| 1 | |
| 2 | |
| 3 | * Copyright 2002-2005, Instant802 Networks, Inc.
|
| 4 | * Copyright 2005-2006, Devicescape Software, Inc.
|
| 5 | * Copyright 2006-2007 Jiri Benc <[email protected]>
|
| 6 | * Copyright 2007 Johannes Berg <[email protected]>
|
| 7 | * Copyright 2013-2014 Intel Mobile Communications GmbH
|
| 8 | * Copyright (C) 2018-2026 Intel Corporation
|
| 9 | *
|
| 10 | * Transmit and frame generation functions.
|
| 11 |
|
| 12 |
|
| 13 | #include <linux/kernel.h>
|
| 14 | #include <linux/slab.h>
|
| 15 | #include <linux/skbuff.h>
|
| 16 | #include <linux/if_vlan.h>
|
| 17 | #include <linux/etherdevice.h>
|
| 18 | #include <linux/bitmap.h>
|
| 19 | #include <linux/rcupdate.h>
|
| 20 | #include <linux/export.h>
|
| 21 | #include <net/net_namespace.h>
|
| 22 | #include <net/ieee80211_radiotap.h>
|
| 23 | #include <net/cfg80211.h>
|
| 24 | #include <net/mac80211.h>
|
| 25 | #include <net/codel.h>
|
| 26 | #include <net/codel_impl.h>
|
| 27 | #include <linux/unaligned.h>
|
| 28 | #include <net/fq_impl.h>
|
| 29 | #include <net/sock.h>
|
| 30 | #include <net/gso.h>
|
| 31 |
|
| 32 | #include "ieee80211_i.h"
|
| 33 | #include "driver-ops.h"
|
| 34 | #include "led.h"
|
| 35 | #include "mesh.h"
|
| 36 | #include "wep.h"
|
| 37 | #include "wpa.h"
|
| 38 | #include "wme.h"
|
| 39 | #include "rate.h"
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 | static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
|
| 44 | struct sk_buff *skb, int group_addr,
|
| 45 | int next_frag_len)
|
| 46 | {
|
| 47 | int rate, mrate, erp, dur, i;
|
| 48 | struct ieee80211_rate *txrate;
|
| 49 | struct ieee80211_local *local = tx->local;
|
| 50 | struct ieee80211_supported_band *sband;
|
| 51 | struct ieee80211_hdr *hdr;
|
| 52 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 53 |
|
| 54 |
|
| 55 | if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))
|
| 56 | return 0;
|
| 57 |
|
| 58 |
|
| 59 | if (WARN_ON_ONCE(tx->rate.idx < 0))
|
| 60 | return 0;
|
| 61 |
|
| 62 | if (info->band >= NUM_NL80211_BANDS)
|
| 63 | return 0;
|
| 64 |
|
| 65 | sband = local->hw.wiphy->bands[info->band];
|
| 66 | txrate = &sband->bitrates[tx->rate.idx];
|
| 67 |
|
| 68 | erp = txrate->flags & IEEE80211_RATE_ERP_G;
|
| 69 |
|
| 70 |
|
| 71 | if (sband->band == NL80211_BAND_S1GHZ)
|
| 72 | return 0;
|
| 73 |
|
| 74 | |
| 75 | * data and mgmt (except PS Poll):
|
| 76 | * - during CFP: 32768
|
| 77 | * - during contention period:
|
| 78 | * if addr1 is group address: 0
|
| 79 | * if more fragments = 0 and addr1 is individual address: time to
|
| 80 | * transmit one ACK plus SIFS
|
| 81 | * if more fragments = 1 and addr1 is individual address: time to
|
| 82 | * transmit next fragment plus 2 x ACK plus 3 x SIFS
|
| 83 | *
|
| 84 | * IEEE 802.11, 9.6:
|
| 85 | * - control response frame (CTS or ACK) shall be transmitted using the
|
| 86 | * same rate as the immediately previous frame in the frame exchange
|
| 87 | * sequence, if this rate belongs to the PHY mandatory rates, or else
|
| 88 | * at the highest possible rate belonging to the PHY rates in the
|
| 89 | * BSSBasicRateSet
|
| 90 |
|
| 91 | hdr = (struct ieee80211_hdr *)skb->data;
|
| 92 | if (ieee80211_is_ctl(hdr->frame_control)) {
|
| 93 | |
| 94 | * mac80211, but should they be implemented, this function
|
| 95 | * needs to be updated to support duration field calculation.
|
| 96 | *
|
| 97 | * RTS: time needed to transmit pending data/mgmt frame plus
|
| 98 | * one CTS frame plus one ACK frame plus 3 x SIFS
|
| 99 | * CTS: duration of immediately previous RTS minus time
|
| 100 | * required to transmit CTS and its SIFS
|
| 101 | * ACK: 0 if immediately previous directed data/mgmt had
|
| 102 | * more=0, with more=1 duration in ACK frame is duration
|
| 103 | * from previous frame minus time needed to transmit ACK
|
| 104 | * and its SIFS
|
| 105 | * PS Poll: BIT(15) | BIT(14) | aid
|
| 106 |
|
| 107 | return 0;
|
| 108 | }
|
| 109 |
|
| 110 |
|
| 111 | if (0 )
|
| 112 | return cpu_to_le16(32768);
|
| 113 |
|
| 114 | if (group_addr)
|
| 115 | return 0;
|
| 116 |
|
| 117 | |
| 118 | * IEEE 802.11, Ch. 9.6 (after IEEE 802.11g changes)
|
| 119 | * CTS and ACK frames shall be transmitted using the highest rate in
|
| 120 | * basic rate set that is less than or equal to the rate of the
|
| 121 | * immediately previous frame and that is using the same modulation
|
| 122 | * (CCK or OFDM). If no basic rate set matches with these requirements,
|
| 123 | * the highest mandatory rate of the PHY that is less than or equal to
|
| 124 | * the rate of the previous frame is used.
|
| 125 | * Mandatory rates for IEEE 802.11g PHY: 1, 2, 5.5, 11, 6, 12, 24 Mbps
|
| 126 |
|
| 127 | rate = -1;
|
| 128 |
|
| 129 | mrate = sband->bitrates[0].bitrate;
|
| 130 | for (i = 0; i < sband->n_bitrates; i++) {
|
| 131 | struct ieee80211_rate *r = &sband->bitrates[i];
|
| 132 | u32 flag;
|
| 133 |
|
| 134 | if (r->bitrate > txrate->bitrate)
|
| 135 | break;
|
| 136 |
|
| 137 | if (tx->sdata->vif.bss_conf.basic_rates & BIT(i))
|
| 138 | rate = r->bitrate;
|
| 139 |
|
| 140 | switch (sband->band) {
|
| 141 | case NL80211_BAND_2GHZ:
|
| 142 | case NL80211_BAND_LC:
|
| 143 | if (tx->sdata->deflink.operating_11g_mode)
|
| 144 | flag = IEEE80211_RATE_MANDATORY_G;
|
| 145 | else
|
| 146 | flag = IEEE80211_RATE_MANDATORY_B;
|
| 147 | break;
|
| 148 | case NL80211_BAND_5GHZ:
|
| 149 | case NL80211_BAND_6GHZ:
|
| 150 | flag = IEEE80211_RATE_MANDATORY_A;
|
| 151 | break;
|
| 152 | default:
|
| 153 | flag = 0;
|
| 154 | WARN_ON(1);
|
| 155 | break;
|
| 156 | }
|
| 157 |
|
| 158 | if (r->flags & flag)
|
| 159 | mrate = r->bitrate;
|
| 160 | }
|
| 161 | if (rate == -1) {
|
| 162 | |
| 163 | * PHY rate
|
| 164 | rate = mrate;
|
| 165 | }
|
| 166 |
|
| 167 |
|
| 168 | if (ieee80211_is_data_qos(hdr->frame_control) &&
|
| 169 | *(ieee80211_get_qos_ctl(hdr)) & IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
|
| 170 | dur = 0;
|
| 171 | else
|
| 172 | |
| 173 | * (10 bytes + 4-byte FCS = 112 bits) plus SIFS; rounded up
|
| 174 | * to closest integer
|
| 175 | dur = ieee80211_frame_duration(sband->band, 10, rate, erp,
|
| 176 | tx->sdata->vif.bss_conf.use_short_preamble);
|
| 177 |
|
| 178 | if (next_frag_len) {
|
| 179 | |
| 180 | * transmit next fragment plus ACK and 2 x SIFS.
|
| 181 | dur *= 2;
|
| 182 |
|
| 183 | dur += ieee80211_frame_duration(sband->band, next_frag_len,
|
| 184 | txrate->bitrate, erp,
|
| 185 | tx->sdata->vif.bss_conf.use_short_preamble);
|
| 186 | }
|
| 187 |
|
| 188 | return cpu_to_le16(dur);
|
| 189 | }
|
| 190 |
|
| 191 |
|
| 192 | static ieee80211_tx_result debug_noinline
|
| 193 | ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
|
| 194 | {
|
| 195 | struct ieee80211_local *local = tx->local;
|
| 196 | struct ieee80211_if_managed *ifmgd;
|
| 197 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
| 198 |
|
| 199 |
|
| 200 | if (!ieee80211_hw_check(&local->hw, SUPPORTS_PS))
|
| 201 | return TX_CONTINUE;
|
| 202 |
|
| 203 |
|
| 204 | if (ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
|
| 205 | return TX_CONTINUE;
|
| 206 |
|
| 207 |
|
| 208 | if (local->hw.conf.dynamic_ps_timeout <= 0)
|
| 209 | return TX_CONTINUE;
|
| 210 |
|
| 211 |
|
| 212 | if (local->scanning)
|
| 213 | return TX_CONTINUE;
|
| 214 |
|
| 215 | if (!local->ps_sdata)
|
| 216 | return TX_CONTINUE;
|
| 217 |
|
| 218 |
|
| 219 | if (local->quiescing)
|
| 220 | return TX_CONTINUE;
|
| 221 |
|
| 222 |
|
| 223 | if (tx->sdata->vif.type != NL80211_IFTYPE_STATION)
|
| 224 | return TX_CONTINUE;
|
| 225 |
|
| 226 | if (unlikely(info->flags & IEEE80211_TX_INTFL_OFFCHAN_TX_OK))
|
| 227 | return TX_CONTINUE;
|
| 228 |
|
| 229 | ifmgd = &tx->sdata->u.mgd;
|
| 230 |
|
| 231 | |
| 232 | * Don't wakeup from power save if u-apsd is enabled, voip ac has
|
| 233 | * u-apsd enabled and the frame is in voip class. This effectively
|
| 234 | * means that even if all access categories have u-apsd enabled, in
|
| 235 | * practise u-apsd is only used with the voip ac. This is a
|
| 236 | * workaround for the case when received voip class packets do not
|
| 237 | * have correct qos tag for some reason, due the network or the
|
| 238 | * peer application.
|
| 239 | *
|
| 240 | * Note: ifmgd->uapsd_queues access is racy here. If the value is
|
| 241 | * changed via debugfs, user needs to reassociate manually to have
|
| 242 | * everything in sync.
|
| 243 |
|
| 244 | if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) &&
|
| 245 | (ifmgd->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) &&
|
| 246 | skb_get_queue_mapping(tx->skb) == IEEE80211_AC_VO)
|
| 247 | return TX_CONTINUE;
|
| 248 |
|
| 249 | if (local->hw.conf.flags & IEEE80211_CONF_PS) {
|
| 250 | ieee80211_stop_queues_by_reason(&local->hw,
|
| 251 | IEEE80211_MAX_QUEUE_MAP,
|
| 252 | IEEE80211_QUEUE_STOP_REASON_PS,
|
| 253 | false);
|
| 254 | ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
|
| 255 | wiphy_work_queue(local->hw.wiphy,
|
| 256 | &local->dynamic_ps_disable_work);
|
| 257 | }
|
| 258 |
|
| 259 |
|
| 260 | if (!ifmgd->associated)
|
| 261 | return TX_CONTINUE;
|
| 262 |
|
| 263 | mod_timer(&local->dynamic_ps_timer, jiffies +
|
| 264 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
|
| 265 |
|
| 266 | return TX_CONTINUE;
|
| 267 | }
|
| 268 |
|
| 269 | static ieee80211_tx_result debug_noinline
|
| 270 | ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
|
| 271 | {
|
| 272 |
|
| 273 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
|
| 274 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
| 275 | bool assoc = false;
|
| 276 |
|
| 277 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
|
| 278 | return TX_CONTINUE;
|
| 279 |
|
| 280 | if (unlikely(test_bit(SCAN_SW_SCANNING, &tx->local->scanning)) &&
|
| 281 | test_bit(SDATA_STATE_OFFCHANNEL, &tx->sdata->state) &&
|
| 282 | !ieee80211_is_probe_req(hdr->frame_control) &&
|
| 283 | !ieee80211_is_any_nullfunc(hdr->frame_control))
|
| 284 | |
| 285 | * When software scanning only nullfunc frames (to notify
|
| 286 | * the sleep state to the AP) and probe requests (for the
|
| 287 | * active scan) are allowed, all other frames should not be
|
| 288 | * sent and we should not get here, but if we do
|
| 289 | * nonetheless, drop them to avoid sending them
|
| 290 | * off-channel. See __ieee80211_start_scan() for more.
|
| 291 |
|
| 292 | return TX_DROP;
|
| 293 |
|
| 294 | if (tx->sdata->vif.type == NL80211_IFTYPE_OCB)
|
| 295 | return TX_CONTINUE;
|
| 296 |
|
| 297 | if (tx->flags & IEEE80211_TX_PS_BUFFERED)
|
| 298 | return TX_CONTINUE;
|
| 299 |
|
| 300 | if (tx->sta)
|
| 301 | assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC);
|
| 302 |
|
| 303 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) {
|
| 304 | if (unlikely(!assoc &&
|
| 305 | ieee80211_is_data(hdr->frame_control))) {
|
| 306 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
|
| 307 | sdata_info(tx->sdata,
|
| 308 | "dropped data frame to not associated station %pM\n",
|
| 309 | hdr->addr1);
|
| 310 | #endif
|
| 311 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc);
|
| 312 | return TX_DROP;
|
| 313 | }
|
| 314 | } else if (unlikely(ieee80211_is_data(hdr->frame_control) &&
|
| 315 | ieee80211_vif_get_num_mcast_if(tx->sdata) == 0)) {
|
| 316 | |
| 317 | * No associated STAs - no need to send multicast
|
| 318 | * frames.
|
| 319 |
|
| 320 | return TX_DROP;
|
| 321 | }
|
| 322 |
|
| 323 | return TX_CONTINUE;
|
| 324 | }
|
| 325 |
|
| 326 | |
| 327 | * of buffered frames for power saving STAs. This situation should not really
|
| 328 | * happen often during normal operation, so dropping the oldest buffered packet
|
| 329 | * from each queue should be OK to make some room for new frames.
|
| 330 | static void purge_old_ps_buffers(struct ieee80211_local *local)
|
| 331 | {
|
| 332 | int total = 0, purged = 0;
|
| 333 | struct sk_buff *skb;
|
| 334 | struct ieee80211_sub_if_data *sdata;
|
| 335 | struct sta_info *sta;
|
| 336 |
|
| 337 | list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
| 338 | struct ps_data *ps;
|
| 339 |
|
| 340 | if (sdata->vif.type == NL80211_IFTYPE_AP)
|
| 341 | ps = &sdata->u.ap.ps;
|
| 342 | else if (ieee80211_vif_is_mesh(&sdata->vif))
|
| 343 | ps = &sdata->u.mesh.ps;
|
| 344 | else
|
| 345 | continue;
|
| 346 |
|
| 347 | skb = skb_dequeue(&ps->bc_buf);
|
| 348 | if (skb) {
|
| 349 | purged++;
|
| 350 | ieee80211_free_txskb(&local->hw, skb);
|
| 351 | }
|
| 352 | total += skb_queue_len(&ps->bc_buf);
|
| 353 | }
|
| 354 |
|
| 355 | |
| 356 | * Drop one frame from each station from the lowest-priority
|
| 357 | * AC that has frames at all.
|
| 358 |
|
| 359 | list_for_each_entry_rcu(sta, &local->sta_list, list) {
|
| 360 | int ac;
|
| 361 |
|
| 362 | for (ac = IEEE80211_AC_BK; ac >= IEEE80211_AC_VO; ac--) {
|
| 363 | skb = skb_dequeue(&sta->ps_tx_buf[ac]);
|
| 364 | total += skb_queue_len(&sta->ps_tx_buf[ac]);
|
| 365 | if (skb) {
|
| 366 | purged++;
|
| 367 | ieee80211_free_txskb(&local->hw, skb);
|
| 368 | break;
|
| 369 | }
|
| 370 | }
|
| 371 | }
|
| 372 |
|
| 373 | local->total_ps_buffered = total;
|
| 374 | ps_dbg_hw(&local->hw, "PS buffers full - purged %d frames\n", purged);
|
| 375 | }
|
| 376 |
|
| 377 | static ieee80211_tx_result
|
| 378 | ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
|
| 379 | {
|
| 380 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
| 381 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
|
| 382 | struct ps_data *ps;
|
| 383 |
|
| 384 | |
| 385 | * broadcast/multicast frame
|
| 386 | *
|
| 387 | * If any of the associated/peer stations is in power save mode,
|
| 388 | * the frame is buffered to be sent after DTIM beacon frame.
|
| 389 | * This is done either by the hardware or us.
|
| 390 |
|
| 391 |
|
| 392 |
|
| 393 | if (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
|
| 394 | tx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
|
| 395 | if (!tx->sdata->bss)
|
| 396 | return TX_CONTINUE;
|
| 397 |
|
| 398 | ps = &tx->sdata->bss->ps;
|
| 399 | } else if (ieee80211_vif_is_mesh(&tx->sdata->vif)) {
|
| 400 | ps = &tx->sdata->u.mesh.ps;
|
| 401 | } else {
|
| 402 | return TX_CONTINUE;
|
| 403 | }
|
| 404 |
|
| 405 |
|
| 406 |
|
| 407 | if (ieee80211_has_order(hdr->frame_control))
|
| 408 | return TX_CONTINUE;
|
| 409 |
|
| 410 | if (ieee80211_is_probe_req(hdr->frame_control))
|
| 411 | return TX_CONTINUE;
|
| 412 |
|
| 413 | if (ieee80211_hw_check(&tx->local->hw, QUEUE_CONTROL))
|
| 414 | info->hw_queue = tx->sdata->vif.cab_queue;
|
| 415 |
|
| 416 |
|
| 417 | if (!atomic_read(&ps->num_sta_ps) && skb_queue_empty(&ps->bc_buf))
|
| 418 | return TX_CONTINUE;
|
| 419 |
|
| 420 | info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
|
| 421 |
|
| 422 |
|
| 423 | if (!ieee80211_hw_check(&tx->local->hw, HOST_BROADCAST_PS_BUFFERING))
|
| 424 | return TX_CONTINUE;
|
| 425 |
|
| 426 |
|
| 427 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
|
| 428 | purge_old_ps_buffers(tx->local);
|
| 429 |
|
| 430 | if (skb_queue_len(&ps->bc_buf) >= AP_MAX_BC_BUFFER) {
|
| 431 | ps_dbg(tx->sdata,
|
| 432 | "BC TX buffer full - dropping the oldest frame\n");
|
| 433 | ieee80211_free_txskb(&tx->local->hw, skb_dequeue(&ps->bc_buf));
|
| 434 | } else
|
| 435 | tx->local->total_ps_buffered++;
|
| 436 |
|
| 437 | skb_queue_tail(&ps->bc_buf, tx->skb);
|
| 438 |
|
| 439 | return TX_QUEUED;
|
| 440 | }
|
| 441 |
|
| 442 | static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta,
|
| 443 | struct sk_buff *skb)
|
| 444 | {
|
| 445 | if (!ieee80211_is_mgmt(fc))
|
| 446 | return 0;
|
| 447 |
|
| 448 | if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP))
|
| 449 | return 0;
|
| 450 |
|
| 451 | if (!ieee80211_is_robust_mgmt_frame(skb))
|
| 452 | return 0;
|
| 453 |
|
| 454 | return 1;
|
| 455 | }
|
| 456 |
|
| 457 | static ieee80211_tx_result
|
| 458 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
|
| 459 | {
|
| 460 | struct sta_info *sta = tx->sta;
|
| 461 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
| 462 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
|
| 463 | struct ieee80211_local *local = tx->local;
|
| 464 |
|
| 465 | if (unlikely(!sta))
|
| 466 | return TX_CONTINUE;
|
| 467 |
|
| 468 | if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
|
| 469 | test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
|
| 470 | test_sta_flag(sta, WLAN_STA_PS_DELIVER)) &&
|
| 471 | !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
|
| 472 | int ac = skb_get_queue_mapping(tx->skb);
|
| 473 |
|
| 474 | if (ieee80211_is_mgmt(hdr->frame_control) &&
|
| 475 | !ieee80211_is_bufferable_mmpdu(tx->skb)) {
|
| 476 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
|
| 477 | return TX_CONTINUE;
|
| 478 | }
|
| 479 |
|
| 480 | ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n",
|
| 481 | sta->sta.addr, sta->sta.aid, ac);
|
| 482 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
|
| 483 | purge_old_ps_buffers(tx->local);
|
| 484 |
|
| 485 |
|
| 486 | spin_lock(&sta->ps_lock);
|
| 487 | |
| 488 | * STA woke up the meantime and all the frames on ps_tx_buf have
|
| 489 | * been queued to pending queue. No reordering can happen, go
|
| 490 | * ahead and Tx the packet.
|
| 491 |
|
| 492 | if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
|
| 493 | !test_sta_flag(sta, WLAN_STA_PS_DRIVER) &&
|
| 494 | !test_sta_flag(sta, WLAN_STA_PS_DELIVER)) {
|
| 495 | spin_unlock(&sta->ps_lock);
|
| 496 | return TX_CONTINUE;
|
| 497 | }
|
| 498 |
|
| 499 | if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) {
|
| 500 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]);
|
| 501 | ps_dbg(tx->sdata,
|
| 502 | "STA %pM TX buffer for AC %d full - dropping oldest frame\n",
|
| 503 | sta->sta.addr, ac);
|
| 504 | ieee80211_free_txskb(&local->hw, old);
|
| 505 | } else
|
| 506 | tx->local->total_ps_buffered++;
|
| 507 |
|
| 508 | info->control.jiffies = jiffies;
|
| 509 | info->control.vif = &tx->sdata->vif;
|
| 510 | info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
|
| 511 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
|
| 512 | skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb);
|
| 513 | spin_unlock(&sta->ps_lock);
|
| 514 |
|
| 515 | if (!timer_pending(&local->sta_cleanup))
|
| 516 | mod_timer(&local->sta_cleanup,
|
| 517 | round_jiffies(jiffies +
|
| 518 | STA_INFO_CLEANUP_INTERVAL));
|
| 519 |
|
| 520 | |
| 521 | * We queued up some frames, so the TIM bit might
|
| 522 | * need to be set, recalculate it.
|
| 523 |
|
| 524 | sta_info_recalc_tim(sta);
|
| 525 |
|
| 526 | return TX_QUEUED;
|
| 527 | } else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) {
|
| 528 | ps_dbg(tx->sdata,
|
| 529 | "STA %pM in PS mode, but polling/in SP -> send frame\n",
|
| 530 | sta->sta.addr);
|
| 531 | }
|
| 532 |
|
| 533 | return TX_CONTINUE;
|
| 534 | }
|
| 535 |
|
| 536 | static ieee80211_tx_result debug_noinline
|
| 537 | ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx)
|
| 538 | {
|
| 539 | if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED))
|
| 540 | return TX_CONTINUE;
|
| 541 |
|
| 542 | if (tx->flags & IEEE80211_TX_UNICAST)
|
| 543 | return ieee80211_tx_h_unicast_ps_buf(tx);
|
| 544 | else
|
| 545 | return ieee80211_tx_h_multicast_ps_buf(tx);
|
| 546 | }
|
| 547 |
|
| 548 | static ieee80211_tx_result debug_noinline
|
| 549 | ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx)
|
| 550 | {
|
| 551 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
| 552 |
|
| 553 | if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol)) {
|
| 554 | if (tx->sdata->control_port_no_encrypt)
|
| 555 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
| 556 | info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
|
| 557 | info->flags |= IEEE80211_TX_CTL_USE_MINRATE;
|
| 558 | }
|
| 559 |
|
| 560 | return TX_CONTINUE;
|
| 561 | }
|
| 562 |
|
| 563 | static struct ieee80211_key *
|
| 564 | ieee80211_select_link_key(struct ieee80211_tx_data *tx)
|
| 565 | {
|
| 566 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
|
| 567 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
| 568 | struct ieee80211_link_data *link;
|
| 569 | unsigned int link_id;
|
| 570 |
|
| 571 | link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK);
|
| 572 | if (link_id == IEEE80211_LINK_UNSPECIFIED) {
|
| 573 | link = &tx->sdata->deflink;
|
| 574 | } else {
|
| 575 | link = rcu_dereference(tx->sdata->link[link_id]);
|
| 576 | if (!link)
|
| 577 | return NULL;
|
| 578 | }
|
| 579 |
|
| 580 | if (ieee80211_is_group_privacy_action(tx->skb))
|
| 581 | return rcu_dereference(link->default_multicast_key);
|
| 582 | else if (ieee80211_is_mgmt(hdr->frame_control) &&
|
| 583 | is_multicast_ether_addr(hdr->addr1) &&
|
| 584 | ieee80211_is_robust_mgmt_frame(tx->skb))
|
| 585 | return rcu_dereference(link->default_mgmt_key);
|
| 586 | else if (is_multicast_ether_addr(hdr->addr1))
|
| 587 | return rcu_dereference(link->default_multicast_key);
|
| 588 |
|
| 589 | return NULL;
|
| 590 | }
|
| 591 |
|
| 592 | static ieee80211_tx_result debug_noinline
|
| 593 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
|
| 594 | {
|
| 595 | struct ieee80211_key *key;
|
| 596 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
| 597 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
|
| 598 |
|
| 599 | if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) {
|
| 600 | tx->key = NULL;
|
| 601 | return TX_CONTINUE;
|
| 602 | }
|
| 603 |
|
| 604 | if (tx->sta &&
|
| 605 | (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
|
| 606 | tx->key = key;
|
| 607 | else if ((key = ieee80211_select_link_key(tx)))
|
| 608 | tx->key = key;
|
| 609 | else if (!is_multicast_ether_addr(hdr->addr1) &&
|
| 610 | (key = rcu_dereference(tx->sdata->default_unicast_key)))
|
| 611 | tx->key = key;
|
| 612 | else
|
| 613 | tx->key = NULL;
|
| 614 |
|
| 615 | if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
|
| 616 | if (tx->key && tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
|
| 617 | info->control.hw_key = &tx->key->conf;
|
| 618 | return TX_CONTINUE;
|
| 619 | }
|
| 620 |
|
| 621 | if (tx->key) {
|
| 622 | bool skip_hw = false;
|
| 623 |
|
| 624 |
|
| 625 |
|
| 626 | switch (tx->key->conf.cipher) {
|
| 627 | case WLAN_CIPHER_SUITE_WEP40:
|
| 628 | case WLAN_CIPHER_SUITE_WEP104:
|
| 629 | case WLAN_CIPHER_SUITE_TKIP:
|
| 630 | if (!ieee80211_is_data_present(hdr->frame_control))
|
| 631 | tx->key = NULL;
|
| 632 | break;
|
| 633 | case WLAN_CIPHER_SUITE_CCMP:
|
| 634 | case WLAN_CIPHER_SUITE_CCMP_256:
|
| 635 | case WLAN_CIPHER_SUITE_GCMP:
|
| 636 | case WLAN_CIPHER_SUITE_GCMP_256:
|
| 637 | if (!ieee80211_is_data_present(hdr->frame_control) &&
|
| 638 | !ieee80211_use_mfp(hdr->frame_control, tx->sta,
|
| 639 | tx->skb) &&
|
| 640 | !ieee80211_is_group_privacy_action(tx->skb) &&
|
| 641 | !ieee80211_require_encrypted_assoc(hdr->frame_control,
|
| 642 | tx->sta))
|
| 643 | tx->key = NULL;
|
| 644 | else
|
| 645 | skip_hw = (tx->key->conf.flags &
|
| 646 | IEEE80211_KEY_FLAG_SW_MGMT_TX) &&
|
| 647 | ieee80211_is_mgmt(hdr->frame_control);
|
| 648 | break;
|
| 649 | case WLAN_CIPHER_SUITE_AES_CMAC:
|
| 650 | case WLAN_CIPHER_SUITE_BIP_CMAC_256:
|
| 651 | case WLAN_CIPHER_SUITE_BIP_GMAC_128:
|
| 652 | case WLAN_CIPHER_SUITE_BIP_GMAC_256:
|
| 653 | if (!ieee80211_is_mgmt(hdr->frame_control))
|
| 654 | tx->key = NULL;
|
| 655 | break;
|
| 656 | }
|
| 657 |
|
| 658 | if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED &&
|
| 659 | !ieee80211_is_deauth(hdr->frame_control)) &&
|
| 660 | tx->skb->protocol != tx->sdata->control_port_protocol)
|
| 661 | return TX_DROP;
|
| 662 |
|
| 663 | if (!skip_hw && tx->key &&
|
| 664 | tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
|
| 665 | info->control.hw_key = &tx->key->conf;
|
| 666 | } else if (ieee80211_is_data_present(hdr->frame_control) && tx->sta &&
|
| 667 | test_sta_flag(tx->sta, WLAN_STA_USES_ENCRYPTION)) {
|
| 668 | return TX_DROP;
|
| 669 | }
|
| 670 |
|
| 671 | return TX_CONTINUE;
|
| 672 | }
|
| 673 |
|
| 674 | static ieee80211_tx_result debug_noinline
|
| 675 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
|
| 676 | {
|
| 677 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
| 678 | struct ieee80211_hdr *hdr = (void *)tx->skb->data;
|
| 679 | struct ieee80211_supported_band *sband;
|
| 680 | u32 len;
|
| 681 | struct ieee80211_tx_rate_control txrc;
|
| 682 | struct ieee80211_sta_rates *ratetbl = NULL;
|
| 683 | bool encap = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
|
| 684 | bool assoc = false;
|
| 685 |
|
| 686 | memset(&txrc, 0, sizeof(txrc));
|
| 687 |
|
| 688 | if (info->band < NUM_NL80211_BANDS)
|
| 689 | sband = tx->local->hw.wiphy->bands[info->band];
|
| 690 | else
|
| 691 | return TX_CONTINUE;
|
| 692 |
|
| 693 | len = min_t(u32, tx->skb->len + FCS_LEN,
|
| 694 | tx->local->hw.wiphy->frag_threshold);
|
| 695 |
|
| 696 |
|
| 697 | txrc.hw = &tx->local->hw;
|
| 698 | txrc.sband = sband;
|
| 699 | txrc.bss_conf = &tx->sdata->vif.bss_conf;
|
| 700 | txrc.skb = tx->skb;
|
| 701 | txrc.reported_rate.idx = -1;
|
| 702 |
|
| 703 | if (unlikely(info->control.flags & IEEE80211_TX_CTRL_DONT_USE_RATE_MASK)) {
|
| 704 | txrc.rate_idx_mask = ~0;
|
| 705 | } else {
|
| 706 | txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[info->band];
|
| 707 |
|
| 708 | if (tx->sdata->rc_has_mcs_mask[info->band])
|
| 709 | txrc.rate_idx_mcs_mask =
|
| 710 | tx->sdata->rc_rateidx_mcs_mask[info->band];
|
| 711 | }
|
| 712 |
|
| 713 | txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
|
| 714 | tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
|
| 715 | tx->sdata->vif.type == NL80211_IFTYPE_ADHOC ||
|
| 716 | tx->sdata->vif.type == NL80211_IFTYPE_OCB);
|
| 717 |
|
| 718 |
|
| 719 | if (len > tx->local->hw.wiphy->rts_threshold) {
|
| 720 | txrc.rts = true;
|
| 721 | }
|
| 722 |
|
| 723 | info->control.use_rts = txrc.rts;
|
| 724 | info->control.use_cts_prot = tx->sdata->vif.bss_conf.use_cts_prot;
|
| 725 |
|
| 726 | |
| 727 | * Use short preamble if the BSS can handle it, but not for
|
| 728 | * management frames unless we know the receiver can handle
|
| 729 | * that -- the management frame might be to a station that
|
| 730 | * just wants a probe response.
|
| 731 |
|
| 732 | if (tx->sdata->vif.bss_conf.use_short_preamble &&
|
| 733 | (ieee80211_is_tx_data(tx->skb) ||
|
| 734 | (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
|
| 735 | txrc.short_preamble = true;
|
| 736 |
|
| 737 | info->control.short_preamble = txrc.short_preamble;
|
| 738 |
|
| 739 |
|
| 740 | if (info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)
|
| 741 | return TX_CONTINUE;
|
| 742 |
|
| 743 | if (tx->sta)
|
| 744 | assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC);
|
| 745 |
|
| 746 | |
| 747 | * Lets not bother rate control if we're associated and cannot talk to
|
| 748 | * the sta. This should not happen - except for frames that aren't
|
| 749 | * really for the peer to start with and already ignore rates.
|
| 750 |
|
| 751 | if (!(info->control.flags & IEEE80211_TX_CTRL_DONT_USE_RATE_MASK) &&
|
| 752 | WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) && assoc &&
|
| 753 | !rate_usable_index_exists(sband, &tx->sta->sta),
|
| 754 | "%s: Dropped data frame as no usable bitrate found while "
|
| 755 | "scanning and associated. Target station: "
|
| 756 | "%pM on %d GHz band\n",
|
| 757 | tx->sdata->name,
|
| 758 | encap ? ((struct ethhdr *)hdr)->h_dest : hdr->addr1,
|
| 759 | info->band ? 5 : 2))
|
| 760 | return TX_DROP;
|
| 761 |
|
| 762 | |
| 763 | * If we're associated with the sta at this point we know we can at
|
| 764 | * least send the frame at the lowest bit rate.
|
| 765 |
|
| 766 | rate_control_get_rate(tx->sdata, tx->sta, &txrc);
|
| 767 |
|
| 768 | if (tx->sta && !info->control.skip_table)
|
| 769 | ratetbl = rcu_dereference(tx->sta->sta.rates);
|
| 770 |
|
| 771 | if (unlikely(info->control.rates[0].idx < 0)) {
|
| 772 | if (ratetbl) {
|
| 773 | struct ieee80211_tx_rate rate = {
|
| 774 | .idx = ratetbl->rate[0].idx,
|
| 775 | .flags = ratetbl->rate[0].flags,
|
| 776 | .count = ratetbl->rate[0].count
|
| 777 | };
|
| 778 |
|
| 779 | if (ratetbl->rate[0].idx < 0)
|
| 780 | return TX_DROP;
|
| 781 |
|
| 782 | tx->rate = rate;
|
| 783 | } else {
|
| 784 | return TX_DROP;
|
| 785 | }
|
| 786 | } else {
|
| 787 | tx->rate = info->control.rates[0];
|
| 788 | }
|
| 789 |
|
| 790 | if (txrc.reported_rate.idx < 0) {
|
| 791 | txrc.reported_rate = tx->rate;
|
| 792 | if (tx->sta && ieee80211_is_tx_data(tx->skb))
|
| 793 | tx->sta->deflink.tx_stats.last_rate = txrc.reported_rate;
|
| 794 | } else if (tx->sta)
|
| 795 | tx->sta->deflink.tx_stats.last_rate = txrc.reported_rate;
|
| 796 |
|
| 797 | if (ratetbl)
|
| 798 | return TX_CONTINUE;
|
| 799 |
|
| 800 | if (unlikely(!info->control.rates[0].count))
|
| 801 | info->control.rates[0].count = 1;
|
| 802 |
|
| 803 | if (WARN_ON_ONCE((info->control.rates[0].count > 1) &&
|
| 804 | (info->flags & IEEE80211_TX_CTL_NO_ACK)))
|
| 805 | info->control.rates[0].count = 1;
|
| 806 |
|
| 807 | return TX_CONTINUE;
|
| 808 | }
|
| 809 |
|
| 810 | static __le16 ieee80211_tx_next_seq(struct sta_info *sta, int tid)
|
| 811 | {
|
| 812 | u16 *seq = &sta->tid_seq[tid];
|
| 813 | __le16 ret = cpu_to_le16(*seq);
|
| 814 |
|
| 815 |
|
| 816 | *seq = (*seq + 0x10) & IEEE80211_SCTL_SEQ;
|
| 817 |
|
| 818 | return ret;
|
| 819 | }
|
| 820 |
|
| 821 | static ieee80211_tx_result debug_noinline
|
| 822 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
|
| 823 | {
|
| 824 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
| 825 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
|
| 826 | int tid;
|
| 827 |
|
| 828 | |
| 829 | * Packet injection may want to control the sequence
|
| 830 | * number, if we have no matching interface then we
|
| 831 | * neither assign one ourselves nor ask the driver to.
|
| 832 |
|
| 833 | if (unlikely(info->control.vif->type == NL80211_IFTYPE_MONITOR))
|
| 834 | return TX_CONTINUE;
|
| 835 |
|
| 836 | if (unlikely(ieee80211_is_ctl(hdr->frame_control)))
|
| 837 | return TX_CONTINUE;
|
| 838 |
|
| 839 | if (ieee80211_hdrlen(hdr->frame_control) < 24)
|
| 840 | return TX_CONTINUE;
|
| 841 |
|
| 842 | if (ieee80211_is_qos_nullfunc(hdr->frame_control))
|
| 843 | return TX_CONTINUE;
|
| 844 |
|
| 845 | if (info->control.flags & IEEE80211_TX_CTRL_NO_SEQNO)
|
| 846 | return TX_CONTINUE;
|
| 847 |
|
| 848 |
|
| 849 | if (unlikely(is_multicast_ether_addr(hdr->addr1) &&
|
| 850 | ieee80211_vif_is_mld(info->control.vif) &&
|
| 851 | info->control.vif->type == NL80211_IFTYPE_AP)) {
|
| 852 | if (info->control.flags & IEEE80211_TX_CTRL_MCAST_MLO_FIRST_TX)
|
| 853 | tx->sdata->mld_mcast_seq += 0x10;
|
| 854 | hdr->seq_ctrl = cpu_to_le16(tx->sdata->mld_mcast_seq);
|
| 855 | return TX_CONTINUE;
|
| 856 | }
|
| 857 |
|
| 858 | |
| 859 | * Anything but QoS data that has a sequence number field
|
| 860 | * (is long enough) gets a sequence number from the global
|
| 861 | * counter. QoS data frames with a multicast destination
|
| 862 | * also use the global counter (802.11-2012 9.3.2.10).
|
| 863 |
|
| 864 | if (!ieee80211_is_data_qos(hdr->frame_control) ||
|
| 865 | is_multicast_ether_addr(hdr->addr1)) {
|
| 866 |
|
| 867 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
|
| 868 |
|
| 869 | hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number);
|
| 870 | tx->sdata->sequence_number += 0x10;
|
| 871 | if (tx->sta)
|
| 872 | tx->sta->deflink.tx_stats.msdu[IEEE80211_NUM_TIDS]++;
|
| 873 | return TX_CONTINUE;
|
| 874 | }
|
| 875 |
|
| 876 | |
| 877 | * This should be true for injected/management frames only, for
|
| 878 | * management frames we have set the IEEE80211_TX_CTL_ASSIGN_SEQ
|
| 879 | * above since they are not QoS-data frames.
|
| 880 |
|
| 881 | if (!tx->sta)
|
| 882 | return TX_CONTINUE;
|
| 883 |
|
| 884 |
|
| 885 | tid = ieee80211_get_tid(hdr);
|
| 886 | tx->sta->deflink.tx_stats.msdu[tid]++;
|
| 887 |
|
| 888 | hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid);
|
| 889 |
|
| 890 | return TX_CONTINUE;
|
| 891 | }
|
| 892 |
|
| 893 | static int ieee80211_fragment(struct ieee80211_tx_data *tx,
|
| 894 | struct sk_buff *skb, int hdrlen,
|
| 895 | int frag_threshold)
|
| 896 | {
|
| 897 | struct ieee80211_local *local = tx->local;
|
| 898 | struct ieee80211_tx_info *info;
|
| 899 | struct sk_buff *tmp;
|
| 900 | int per_fragm = frag_threshold - hdrlen - FCS_LEN;
|
| 901 | int pos = hdrlen + per_fragm;
|
| 902 | int rem = skb->len - hdrlen - per_fragm;
|
| 903 |
|
| 904 | if (WARN_ON(rem < 0))
|
| 905 | return -EINVAL;
|
| 906 |
|
| 907 |
|
| 908 |
|
| 909 | while (rem) {
|
| 910 | int fraglen = per_fragm;
|
| 911 |
|
| 912 | if (fraglen > rem)
|
| 913 | fraglen = rem;
|
| 914 | rem -= fraglen;
|
| 915 | tmp = dev_alloc_skb(local->tx_headroom +
|
| 916 | frag_threshold +
|
| 917 | IEEE80211_ENCRYPT_HEADROOM +
|
| 918 | IEEE80211_ENCRYPT_TAILROOM);
|
| 919 | if (!tmp)
|
| 920 | return -ENOMEM;
|
| 921 |
|
| 922 | __skb_queue_tail(&tx->skbs, tmp);
|
| 923 |
|
| 924 | skb_reserve(tmp,
|
| 925 | local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM);
|
| 926 |
|
| 927 |
|
| 928 | memcpy(tmp->cb, skb->cb, sizeof(tmp->cb));
|
| 929 |
|
| 930 | info = IEEE80211_SKB_CB(tmp);
|
| 931 | info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT |
|
| 932 | IEEE80211_TX_CTL_FIRST_FRAGMENT);
|
| 933 |
|
| 934 | if (rem)
|
| 935 | info->flags |= IEEE80211_TX_CTL_MORE_FRAMES;
|
| 936 |
|
| 937 | skb_copy_queue_mapping(tmp, skb);
|
| 938 | tmp->priority = skb->priority;
|
| 939 | tmp->dev = skb->dev;
|
| 940 |
|
| 941 |
|
| 942 | skb_put_data(tmp, skb->data, hdrlen);
|
| 943 | skb_put_data(tmp, skb->data + pos, fraglen);
|
| 944 |
|
| 945 | pos += fraglen;
|
| 946 | }
|
| 947 |
|
| 948 |
|
| 949 | skb_trim(skb, hdrlen + per_fragm);
|
| 950 | return 0;
|
| 951 | }
|
| 952 |
|
| 953 | static ieee80211_tx_result debug_noinline
|
| 954 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
|
| 955 | {
|
| 956 | struct sk_buff *skb = tx->skb;
|
| 957 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 958 | struct ieee80211_hdr *hdr = (void *)skb->data;
|
| 959 | int frag_threshold = tx->local->hw.wiphy->frag_threshold;
|
| 960 | int hdrlen;
|
| 961 | int fragnum;
|
| 962 |
|
| 963 |
|
| 964 | __skb_queue_tail(&tx->skbs, skb);
|
| 965 | tx->skb = NULL;
|
| 966 |
|
| 967 | if (info->flags & IEEE80211_TX_CTL_DONTFRAG)
|
| 968 | return TX_CONTINUE;
|
| 969 |
|
| 970 | if (ieee80211_hw_check(&tx->local->hw, SUPPORTS_TX_FRAG))
|
| 971 | return TX_CONTINUE;
|
| 972 |
|
| 973 | |
| 974 | * Warn when submitting a fragmented A-MPDU frame and drop it.
|
| 975 | * This scenario is handled in ieee80211_tx_prepare but extra
|
| 976 | * caution taken here as fragmented ampdu may cause Tx stop.
|
| 977 |
|
| 978 | if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
|
| 979 | return TX_DROP;
|
| 980 |
|
| 981 | hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
| 982 |
|
| 983 |
|
| 984 | if (WARN_ON(skb->len + FCS_LEN <= frag_threshold))
|
| 985 | return TX_DROP;
|
| 986 |
|
| 987 | |
| 988 | * Now fragment the frame. This will allocate all the fragments and
|
| 989 | * chain them (using skb as the first fragment) to skb->next.
|
| 990 | * During transmission, we will remove the successfully transmitted
|
| 991 | * fragments from this list. When the low-level driver rejects one
|
| 992 | * of the fragments then we will simply pretend to accept the skb
|
| 993 | * but store it away as pending.
|
| 994 |
|
| 995 | if (ieee80211_fragment(tx, skb, hdrlen, frag_threshold))
|
| 996 | return TX_DROP;
|
| 997 |
|
| 998 |
|
| 999 | fragnum = 0;
|
| 1000 |
|
| 1001 | skb_queue_walk(&tx->skbs, skb) {
|
| 1002 | const __le16 morefrags = cpu_to_le16(IEEE80211_FCTL_MOREFRAGS);
|
| 1003 |
|
| 1004 | hdr = (void *)skb->data;
|
| 1005 | info = IEEE80211_SKB_CB(skb);
|
| 1006 |
|
| 1007 | if (!skb_queue_is_last(&tx->skbs, skb)) {
|
| 1008 | hdr->frame_control |= morefrags;
|
| 1009 | |
| 1010 | * No multi-rate retries for fragmented frames, that
|
| 1011 | * would completely throw off the NAV at other STAs.
|
| 1012 |
|
| 1013 | info->control.rates[1].idx = -1;
|
| 1014 | info->control.rates[2].idx = -1;
|
| 1015 | info->control.rates[3].idx = -1;
|
| 1016 | BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 4);
|
| 1017 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
|
| 1018 | } else {
|
| 1019 | hdr->frame_control &= ~morefrags;
|
| 1020 | }
|
| 1021 | hdr->seq_ctrl |= cpu_to_le16(fragnum & IEEE80211_SCTL_FRAG);
|
| 1022 | fragnum++;
|
| 1023 | }
|
| 1024 |
|
| 1025 | return TX_CONTINUE;
|
| 1026 | }
|
| 1027 |
|
| 1028 | static ieee80211_tx_result debug_noinline
|
| 1029 | ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
|
| 1030 | {
|
| 1031 | struct sk_buff *skb;
|
| 1032 | int ac = -1;
|
| 1033 |
|
| 1034 | if (!tx->sta)
|
| 1035 | return TX_CONTINUE;
|
| 1036 |
|
| 1037 | skb_queue_walk(&tx->skbs, skb) {
|
| 1038 | ac = skb_get_queue_mapping(skb);
|
| 1039 | tx->sta->deflink.tx_stats.bytes[ac] += skb->len;
|
| 1040 | }
|
| 1041 | if (ac >= 0)
|
| 1042 | tx->sta->deflink.tx_stats.packets[ac]++;
|
| 1043 |
|
| 1044 | return TX_CONTINUE;
|
| 1045 | }
|
| 1046 |
|
| 1047 | static ieee80211_tx_result debug_noinline
|
| 1048 | ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx)
|
| 1049 | {
|
| 1050 | if (!tx->key)
|
| 1051 | return TX_CONTINUE;
|
| 1052 |
|
| 1053 | switch (tx->key->conf.cipher) {
|
| 1054 | case WLAN_CIPHER_SUITE_WEP40:
|
| 1055 | case WLAN_CIPHER_SUITE_WEP104:
|
| 1056 | return ieee80211_crypto_wep_encrypt(tx);
|
| 1057 | case WLAN_CIPHER_SUITE_TKIP:
|
| 1058 | return ieee80211_crypto_tkip_encrypt(tx);
|
| 1059 | case WLAN_CIPHER_SUITE_CCMP:
|
| 1060 | return ieee80211_crypto_ccmp_encrypt(
|
| 1061 | tx, IEEE80211_CCMP_MIC_LEN);
|
| 1062 | case WLAN_CIPHER_SUITE_CCMP_256:
|
| 1063 | return ieee80211_crypto_ccmp_encrypt(
|
| 1064 | tx, IEEE80211_CCMP_256_MIC_LEN);
|
| 1065 | case WLAN_CIPHER_SUITE_AES_CMAC:
|
| 1066 | return ieee80211_crypto_aes_cmac_encrypt(
|
| 1067 | tx, IEEE80211_CMAC_128_MIC_LEN);
|
| 1068 | case WLAN_CIPHER_SUITE_BIP_CMAC_256:
|
| 1069 | return ieee80211_crypto_aes_cmac_encrypt(
|
| 1070 | tx, IEEE80211_CMAC_256_MIC_LEN);
|
| 1071 | case WLAN_CIPHER_SUITE_BIP_GMAC_128:
|
| 1072 | case WLAN_CIPHER_SUITE_BIP_GMAC_256:
|
| 1073 | return ieee80211_crypto_aes_gmac_encrypt(tx);
|
| 1074 | case WLAN_CIPHER_SUITE_GCMP:
|
| 1075 | case WLAN_CIPHER_SUITE_GCMP_256:
|
| 1076 | return ieee80211_crypto_gcmp_encrypt(tx);
|
| 1077 | }
|
| 1078 |
|
| 1079 | return TX_DROP;
|
| 1080 | }
|
| 1081 |
|
| 1082 | static ieee80211_tx_result debug_noinline
|
| 1083 | ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
|
| 1084 | {
|
| 1085 | struct sk_buff *skb;
|
| 1086 | struct ieee80211_hdr *hdr;
|
| 1087 | int next_len;
|
| 1088 | bool group_addr;
|
| 1089 |
|
| 1090 | skb_queue_walk(&tx->skbs, skb) {
|
| 1091 | hdr = (void *) skb->data;
|
| 1092 | if (unlikely(ieee80211_is_pspoll(hdr->frame_control)))
|
| 1093 | break;
|
| 1094 | if (!skb_queue_is_last(&tx->skbs, skb)) {
|
| 1095 | struct sk_buff *next = skb_queue_next(&tx->skbs, skb);
|
| 1096 | next_len = next->len;
|
| 1097 | } else
|
| 1098 | next_len = 0;
|
| 1099 | group_addr = is_multicast_ether_addr(hdr->addr1);
|
| 1100 |
|
| 1101 | hdr->duration_id =
|
| 1102 | ieee80211_duration(tx, skb, group_addr, next_len);
|
| 1103 | }
|
| 1104 |
|
| 1105 | return TX_CONTINUE;
|
| 1106 | }
|
| 1107 |
|
| 1108 |
|
| 1109 |
|
| 1110 | static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
|
| 1111 | struct sk_buff *skb,
|
| 1112 | struct ieee80211_tx_info *info,
|
| 1113 | struct tid_ampdu_tx *tid_tx,
|
| 1114 | int tid)
|
| 1115 | {
|
| 1116 | bool queued = false;
|
| 1117 | bool reset_agg_timer = false;
|
| 1118 | struct sk_buff *purge_skb = NULL;
|
| 1119 |
|
| 1120 | if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
|
| 1121 | reset_agg_timer = true;
|
| 1122 | } else if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
|
| 1123 | |
| 1124 | * nothing -- this aggregation session is being started
|
| 1125 | * but that might still fail with the driver
|
| 1126 |
|
| 1127 | } else if (!tx->sta->sta.txq[tid]) {
|
| 1128 | spin_lock(&tx->sta->lock);
|
| 1129 | |
| 1130 | * Need to re-check now, because we may get here
|
| 1131 | *
|
| 1132 | * 1) in the window during which the setup is actually
|
| 1133 | * already done, but not marked yet because not all
|
| 1134 | * packets are spliced over to the driver pending
|
| 1135 | * queue yet -- if this happened we acquire the lock
|
| 1136 | * either before or after the splice happens, but
|
| 1137 | * need to recheck which of these cases happened.
|
| 1138 | *
|
| 1139 | * 2) during session teardown, if the OPERATIONAL bit
|
| 1140 | * was cleared due to the teardown but the pointer
|
| 1141 | * hasn't been assigned NULL yet (or we loaded it
|
| 1142 | * before it was assigned) -- in this case it may
|
| 1143 | * now be NULL which means we should just let the
|
| 1144 | * packet pass through because splicing the frames
|
| 1145 | * back is already done.
|
| 1146 |
|
| 1147 | tid_tx = rcu_dereference_protected_tid_tx(tx->sta, tid);
|
| 1148 |
|
| 1149 | if (!tid_tx) {
|
| 1150 |
|
| 1151 | } else if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
|
| 1152 | reset_agg_timer = true;
|
| 1153 | } else {
|
| 1154 | queued = true;
|
| 1155 | if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) {
|
| 1156 | clear_sta_flag(tx->sta, WLAN_STA_SP);
|
| 1157 | ps_dbg(tx->sta->sdata,
|
| 1158 | "STA %pM aid %d: SP frame queued, close the SP w/o telling the peer\n",
|
| 1159 | tx->sta->sta.addr, tx->sta->sta.aid);
|
| 1160 | }
|
| 1161 | info->control.vif = &tx->sdata->vif;
|
| 1162 | info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
|
| 1163 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
|
| 1164 | __skb_queue_tail(&tid_tx->pending, skb);
|
| 1165 | if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER)
|
| 1166 | purge_skb = __skb_dequeue(&tid_tx->pending);
|
| 1167 | }
|
| 1168 | spin_unlock(&tx->sta->lock);
|
| 1169 |
|
| 1170 | if (purge_skb)
|
| 1171 | ieee80211_free_txskb(&tx->local->hw, purge_skb);
|
| 1172 | }
|
| 1173 |
|
| 1174 |
|
| 1175 | if (reset_agg_timer)
|
| 1176 | tid_tx->last_tx = jiffies;
|
| 1177 |
|
| 1178 | return queued;
|
| 1179 | }
|
| 1180 |
|
| 1181 | void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata,
|
| 1182 | struct sta_info *sta, struct sk_buff *skb)
|
| 1183 | {
|
| 1184 | struct rate_control_ref *ref = sdata->local->rate_ctrl;
|
| 1185 | u16 tid;
|
| 1186 |
|
| 1187 | if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER))
|
| 1188 | return;
|
| 1189 |
|
| 1190 | if (!sta ||
|
| 1191 | (!sta->sta.valid_links && !sta->sta.deflink.ht_cap.ht_supported &&
|
| 1192 | !sta->sta.deflink.s1g_cap.s1g) ||
|
| 1193 | !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO ||
|
| 1194 | skb->protocol == sdata->control_port_protocol)
|
| 1195 | return;
|
| 1196 |
|
| 1197 | tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
|
| 1198 | if (likely(sta->ampdu_mlme.tid_tx[tid]))
|
| 1199 | return;
|
| 1200 |
|
| 1201 | ieee80211_start_tx_ba_session(&sta->sta, tid, 0);
|
| 1202 | }
|
| 1203 |
|
| 1204 | |
| 1205 | * initialises @tx
|
| 1206 | * pass %NULL for the station if unknown, a valid pointer if known
|
| 1207 | * or an ERR_PTR() if the station is known not to exist
|
| 1208 |
|
| 1209 | static ieee80211_tx_result
|
| 1210 | ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
|
| 1211 | struct ieee80211_tx_data *tx,
|
| 1212 | struct sta_info *sta, struct sk_buff *skb)
|
| 1213 | {
|
| 1214 | struct ieee80211_local *local = sdata->local;
|
| 1215 | struct ieee80211_hdr *hdr;
|
| 1216 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 1217 | bool aggr_check = false;
|
| 1218 | int tid;
|
| 1219 |
|
| 1220 | memset(tx, 0, sizeof(*tx));
|
| 1221 | tx->skb = skb;
|
| 1222 | tx->local = local;
|
| 1223 | tx->sdata = sdata;
|
| 1224 | __skb_queue_head_init(&tx->skbs);
|
| 1225 |
|
| 1226 | |
| 1227 | * If this flag is set to true anywhere, and we get here,
|
| 1228 | * we are doing the needed processing, so remove the flag
|
| 1229 | * now.
|
| 1230 |
|
| 1231 | info->control.flags &= ~IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
|
| 1232 |
|
| 1233 | hdr = (struct ieee80211_hdr *) skb->data;
|
| 1234 |
|
| 1235 | if (likely(sta)) {
|
| 1236 | if (!IS_ERR(sta))
|
| 1237 | tx->sta = sta;
|
| 1238 | } else {
|
| 1239 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
|
| 1240 | tx->sta = rcu_dereference(sdata->u.vlan.sta);
|
| 1241 | if (!tx->sta && sdata->wdev.use_4addr)
|
| 1242 | return TX_DROP;
|
| 1243 | } else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
|
| 1244 | tx->sta = sta_info_get_bss(sdata, hdr->addr1);
|
| 1245 | }
|
| 1246 | if (!tx->sta && !is_multicast_ether_addr(hdr->addr1)) {
|
| 1247 | tx->sta = sta_info_get(sdata, hdr->addr1);
|
| 1248 | aggr_check = true;
|
| 1249 | }
|
| 1250 | }
|
| 1251 |
|
| 1252 | if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
|
| 1253 | !ieee80211_is_qos_nullfunc(hdr->frame_control) &&
|
| 1254 | ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION) &&
|
| 1255 | !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) {
|
| 1256 | struct tid_ampdu_tx *tid_tx;
|
| 1257 |
|
| 1258 | tid = ieee80211_get_tid(hdr);
|
| 1259 | tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
|
| 1260 | if (!tid_tx && aggr_check) {
|
| 1261 | ieee80211_aggr_check(sdata, tx->sta, skb);
|
| 1262 | tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
|
| 1263 | }
|
| 1264 |
|
| 1265 | if (tid_tx) {
|
| 1266 | bool queued;
|
| 1267 |
|
| 1268 | queued = ieee80211_tx_prep_agg(tx, skb, info,
|
| 1269 | tid_tx, tid);
|
| 1270 |
|
| 1271 | if (unlikely(queued))
|
| 1272 | return TX_QUEUED;
|
| 1273 | }
|
| 1274 | }
|
| 1275 |
|
| 1276 | if (is_multicast_ether_addr(hdr->addr1)) {
|
| 1277 | tx->flags &= ~IEEE80211_TX_UNICAST;
|
| 1278 | info->flags |= IEEE80211_TX_CTL_NO_ACK;
|
| 1279 | } else
|
| 1280 | tx->flags |= IEEE80211_TX_UNICAST;
|
| 1281 |
|
| 1282 | if (!(info->flags & IEEE80211_TX_CTL_DONTFRAG)) {
|
| 1283 | if (!(tx->flags & IEEE80211_TX_UNICAST) ||
|
| 1284 | skb->len + FCS_LEN <= local->hw.wiphy->frag_threshold ||
|
| 1285 | info->flags & IEEE80211_TX_CTL_AMPDU)
|
| 1286 | info->flags |= IEEE80211_TX_CTL_DONTFRAG;
|
| 1287 | }
|
| 1288 |
|
| 1289 | if (!tx->sta)
|
| 1290 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
|
| 1291 | else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) {
|
| 1292 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
|
| 1293 | ieee80211_check_fast_xmit(tx->sta);
|
| 1294 | }
|
| 1295 |
|
| 1296 | info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
|
| 1297 |
|
| 1298 | return TX_CONTINUE;
|
| 1299 | }
|
| 1300 |
|
| 1301 | static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
|
| 1302 | struct ieee80211_vif *vif,
|
| 1303 | struct sta_info *sta,
|
| 1304 | struct sk_buff *skb)
|
| 1305 | {
|
| 1306 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
| 1307 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 1308 | struct ieee80211_txq *txq = NULL;
|
| 1309 |
|
| 1310 | if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) ||
|
| 1311 | (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE))
|
| 1312 | return NULL;
|
| 1313 |
|
| 1314 | |
| 1315 | * While (re)association request/response frames are not considered
|
| 1316 | * bufferable MMPDUs, use the TXQ abstraction for the transmission of
|
| 1317 | * these frames. This is specifically useful for drivers that might
|
| 1318 | * associate other resources with the TXQ, e.g., encryption keys etc.
|
| 1319 |
|
| 1320 | if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
|
| 1321 | unlikely(!ieee80211_is_data_present(hdr->frame_control))) {
|
| 1322 | if ((!ieee80211_is_mgmt(hdr->frame_control) ||
|
| 1323 | ieee80211_is_bufferable_mmpdu(skb) ||
|
| 1324 | ieee80211_is_assoc(hdr->frame_control) ||
|
| 1325 | vif->type == NL80211_IFTYPE_STATION ||
|
| 1326 | vif->type == NL80211_IFTYPE_NAN ||
|
| 1327 | vif->type == NL80211_IFTYPE_NAN_DATA) &&
|
| 1328 | sta && sta->uploaded) {
|
| 1329 | |
| 1330 | * This will be NULL if the driver didn't set the
|
| 1331 | * opt-in hardware flag.
|
| 1332 |
|
| 1333 | txq = sta->sta.txq[IEEE80211_NUM_TIDS];
|
| 1334 | } else if ((!ieee80211_is_mgmt(hdr->frame_control) ||
|
| 1335 | ieee80211_is_bufferable_mmpdu(skb)) &&
|
| 1336 | !sta) {
|
| 1337 | txq = vif->txq_mgmt;
|
| 1338 | }
|
| 1339 | } else if (sta) {
|
| 1340 | u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
|
| 1341 |
|
| 1342 | if (!sta->uploaded)
|
| 1343 | return NULL;
|
| 1344 |
|
| 1345 | txq = sta->sta.txq[tid];
|
| 1346 | } else {
|
| 1347 | txq = vif->txq;
|
| 1348 | }
|
| 1349 |
|
| 1350 | if (!txq)
|
| 1351 | return NULL;
|
| 1352 |
|
| 1353 | return to_txq_info(txq);
|
| 1354 | }
|
| 1355 |
|
| 1356 | static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb)
|
| 1357 | {
|
| 1358 | struct sk_buff *next;
|
| 1359 | codel_time_t now = codel_get_time();
|
| 1360 |
|
| 1361 | skb_list_walk_safe(skb, skb, next)
|
| 1362 | IEEE80211_SKB_CB(skb)->control.enqueue_time = now;
|
| 1363 | }
|
| 1364 |
|
| 1365 | static u32 codel_skb_len_func(const struct sk_buff *skb)
|
| 1366 | {
|
| 1367 | return skb->len;
|
| 1368 | }
|
| 1369 |
|
| 1370 | static codel_time_t codel_skb_time_func(const struct sk_buff *skb)
|
| 1371 | {
|
| 1372 | const struct ieee80211_tx_info *info;
|
| 1373 |
|
| 1374 | info = (const struct ieee80211_tx_info *)skb->cb;
|
| 1375 | return info->control.enqueue_time;
|
| 1376 | }
|
| 1377 |
|
| 1378 | static struct sk_buff *codel_dequeue_func(struct codel_vars *cvars,
|
| 1379 | void *ctx)
|
| 1380 | {
|
| 1381 | struct ieee80211_local *local;
|
| 1382 | struct txq_info *txqi;
|
| 1383 | struct fq *fq;
|
| 1384 | struct fq_flow *flow;
|
| 1385 |
|
| 1386 | txqi = ctx;
|
| 1387 | local = vif_to_sdata(txqi->txq.vif)->local;
|
| 1388 | fq = &local->fq;
|
| 1389 |
|
| 1390 | if (cvars == &txqi->def_cvars)
|
| 1391 | flow = &txqi->tin.default_flow;
|
| 1392 | else
|
| 1393 | flow = &fq->flows[cvars - local->cvars];
|
| 1394 |
|
| 1395 | return fq_flow_dequeue(fq, flow);
|
| 1396 | }
|
| 1397 |
|
| 1398 | static void codel_drop_func(struct sk_buff *skb,
|
| 1399 | void *ctx)
|
| 1400 | {
|
| 1401 | struct ieee80211_local *local;
|
| 1402 | struct ieee80211_hw *hw;
|
| 1403 | struct txq_info *txqi;
|
| 1404 |
|
| 1405 | txqi = ctx;
|
| 1406 | local = vif_to_sdata(txqi->txq.vif)->local;
|
| 1407 | hw = &local->hw;
|
| 1408 |
|
| 1409 | ieee80211_free_txskb(hw, skb);
|
| 1410 | }
|
| 1411 |
|
| 1412 | static struct sk_buff *fq_tin_dequeue_func(struct fq *fq,
|
| 1413 | struct fq_tin *tin,
|
| 1414 | struct fq_flow *flow)
|
| 1415 | {
|
| 1416 | struct ieee80211_local *local;
|
| 1417 | struct txq_info *txqi;
|
| 1418 | struct codel_vars *cvars;
|
| 1419 | struct codel_params *cparams;
|
| 1420 | struct codel_stats *cstats;
|
| 1421 |
|
| 1422 | local = container_of(fq, struct ieee80211_local, fq);
|
| 1423 | txqi = container_of(tin, struct txq_info, tin);
|
| 1424 | cparams = &local->cparams;
|
| 1425 | cstats = &txqi->cstats;
|
| 1426 |
|
| 1427 | if (flow == &tin->default_flow)
|
| 1428 | cvars = &txqi->def_cvars;
|
| 1429 | else
|
| 1430 | cvars = &local->cvars[flow - fq->flows];
|
| 1431 |
|
| 1432 | return codel_dequeue(txqi,
|
| 1433 | &flow->backlog,
|
| 1434 | cparams,
|
| 1435 | cvars,
|
| 1436 | cstats,
|
| 1437 | codel_skb_len_func,
|
| 1438 | codel_skb_time_func,
|
| 1439 | codel_drop_func,
|
| 1440 | codel_dequeue_func);
|
| 1441 | }
|
| 1442 |
|
| 1443 | static void fq_skb_free_func(struct fq *fq,
|
| 1444 | struct fq_tin *tin,
|
| 1445 | struct fq_flow *flow,
|
| 1446 | struct sk_buff *skb)
|
| 1447 | {
|
| 1448 | struct ieee80211_local *local;
|
| 1449 |
|
| 1450 | local = container_of(fq, struct ieee80211_local, fq);
|
| 1451 | ieee80211_free_txskb(&local->hw, skb);
|
| 1452 | }
|
| 1453 |
|
| 1454 | static void ieee80211_txq_enqueue(struct ieee80211_local *local,
|
| 1455 | struct txq_info *txqi,
|
| 1456 | struct sk_buff *skb)
|
| 1457 | {
|
| 1458 | struct fq *fq = &local->fq;
|
| 1459 | struct fq_tin *tin = &txqi->tin;
|
| 1460 | u32 flow_idx;
|
| 1461 |
|
| 1462 | ieee80211_set_skb_enqueue_time(skb);
|
| 1463 |
|
| 1464 | spin_lock_bh(&fq->lock);
|
| 1465 | |
| 1466 | * For management frames, don't really apply codel etc.,
|
| 1467 | * we don't want to apply any shaping or anything we just
|
| 1468 | * want to simplify the driver API by having them on the
|
| 1469 | * txqi.
|
| 1470 |
|
| 1471 | if (unlikely(txqi->txq.tid == IEEE80211_NUM_TIDS)) {
|
| 1472 | IEEE80211_SKB_CB(skb)->control.flags |=
|
| 1473 | IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
|
| 1474 | __skb_queue_tail(&txqi->frags, skb);
|
| 1475 | } else {
|
| 1476 | flow_idx = fq_flow_idx(fq, skb);
|
| 1477 | fq_tin_enqueue(fq, tin, flow_idx, skb,
|
| 1478 | fq_skb_free_func);
|
| 1479 | }
|
| 1480 | spin_unlock_bh(&fq->lock);
|
| 1481 | }
|
| 1482 |
|
| 1483 | static bool fq_vlan_filter_func(struct fq *fq, struct fq_tin *tin,
|
| 1484 | struct fq_flow *flow, struct sk_buff *skb,
|
| 1485 | void *data)
|
| 1486 | {
|
| 1487 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 1488 |
|
| 1489 | return info->control.vif == data;
|
| 1490 | }
|
| 1491 |
|
| 1492 | void ieee80211_txq_remove_vlan(struct ieee80211_local *local,
|
| 1493 | struct ieee80211_sub_if_data *sdata)
|
| 1494 | {
|
| 1495 | struct fq *fq = &local->fq;
|
| 1496 | struct txq_info *txqi;
|
| 1497 | struct fq_tin *tin;
|
| 1498 | struct ieee80211_sub_if_data *ap;
|
| 1499 |
|
| 1500 | if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
|
| 1501 | return;
|
| 1502 |
|
| 1503 | ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
|
| 1504 |
|
| 1505 | if (!ap->vif.txq)
|
| 1506 | return;
|
| 1507 |
|
| 1508 | txqi = to_txq_info(ap->vif.txq);
|
| 1509 | tin = &txqi->tin;
|
| 1510 |
|
| 1511 | spin_lock_bh(&fq->lock);
|
| 1512 | fq_tin_filter(fq, tin, fq_vlan_filter_func, &sdata->vif,
|
| 1513 | fq_skb_free_func);
|
| 1514 | spin_unlock_bh(&fq->lock);
|
| 1515 | }
|
| 1516 |
|
| 1517 | void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
|
| 1518 | struct sta_info *sta,
|
| 1519 | struct txq_info *txqi, int tid)
|
| 1520 | {
|
| 1521 | fq_tin_init(&txqi->tin);
|
| 1522 | codel_vars_init(&txqi->def_cvars);
|
| 1523 | codel_stats_init(&txqi->cstats);
|
| 1524 | __skb_queue_head_init(&txqi->frags);
|
| 1525 | INIT_LIST_HEAD(&txqi->schedule_order);
|
| 1526 |
|
| 1527 | txqi->txq.vif = &sdata->vif;
|
| 1528 |
|
| 1529 | if (!sta) {
|
| 1530 | txqi->txq.tid = tid;
|
| 1531 |
|
| 1532 | if (tid == IEEE80211_NUM_TIDS) {
|
| 1533 | sdata->vif.txq_mgmt = &txqi->txq;
|
| 1534 | txqi->txq.ac = IEEE80211_AC_VO;
|
| 1535 | } else {
|
| 1536 | sdata->vif.txq = &txqi->txq;
|
| 1537 | txqi->txq.ac = IEEE80211_AC_BE;
|
| 1538 | }
|
| 1539 |
|
| 1540 | return;
|
| 1541 | }
|
| 1542 |
|
| 1543 | if (tid == IEEE80211_NUM_TIDS) {
|
| 1544 | if (sdata->vif.type == NL80211_IFTYPE_STATION) {
|
| 1545 |
|
| 1546 | if (!ieee80211_hw_check(&sdata->local->hw,
|
| 1547 | STA_MMPDU_TXQ))
|
| 1548 | return;
|
| 1549 | } else if (!ieee80211_hw_check(&sdata->local->hw,
|
| 1550 | BUFF_MMPDU_TXQ)) {
|
| 1551 |
|
| 1552 | return;
|
| 1553 | }
|
| 1554 | txqi->txq.ac = IEEE80211_AC_VO;
|
| 1555 | } else {
|
| 1556 | txqi->txq.ac = ieee80211_ac_from_tid(tid);
|
| 1557 | }
|
| 1558 |
|
| 1559 | txqi->txq.sta = &sta->sta;
|
| 1560 | txqi->txq.tid = tid;
|
| 1561 | sta->sta.txq[tid] = &txqi->txq;
|
| 1562 | }
|
| 1563 |
|
| 1564 | void ieee80211_txq_purge(struct ieee80211_local *local,
|
| 1565 | struct txq_info *txqi)
|
| 1566 | {
|
| 1567 | struct fq *fq = &local->fq;
|
| 1568 | struct fq_tin *tin = &txqi->tin;
|
| 1569 |
|
| 1570 | spin_lock_bh(&fq->lock);
|
| 1571 | fq_tin_reset(fq, tin, fq_skb_free_func);
|
| 1572 | ieee80211_purge_tx_queue(&local->hw, &txqi->frags);
|
| 1573 | spin_unlock_bh(&fq->lock);
|
| 1574 |
|
| 1575 | spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]);
|
| 1576 | list_del_init(&txqi->schedule_order);
|
| 1577 | spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]);
|
| 1578 | }
|
| 1579 |
|
| 1580 | void ieee80211_txq_set_params(struct ieee80211_local *local, int radio_idx)
|
| 1581 | {
|
| 1582 | if (local->hw.wiphy->txq_limit)
|
| 1583 | local->fq.limit = local->hw.wiphy->txq_limit;
|
| 1584 | else
|
| 1585 | local->hw.wiphy->txq_limit = local->fq.limit;
|
| 1586 |
|
| 1587 | if (local->hw.wiphy->txq_memory_limit)
|
| 1588 | local->fq.memory_limit = local->hw.wiphy->txq_memory_limit;
|
| 1589 | else
|
| 1590 | local->hw.wiphy->txq_memory_limit = local->fq.memory_limit;
|
| 1591 |
|
| 1592 | if (local->hw.wiphy->txq_quantum)
|
| 1593 | local->fq.quantum = local->hw.wiphy->txq_quantum;
|
| 1594 | else
|
| 1595 | local->hw.wiphy->txq_quantum = local->fq.quantum;
|
| 1596 | }
|
| 1597 |
|
| 1598 | int ieee80211_txq_setup_flows(struct ieee80211_local *local)
|
| 1599 | {
|
| 1600 | struct fq *fq = &local->fq;
|
| 1601 | int ret;
|
| 1602 | int i;
|
| 1603 | bool supp_vht = false;
|
| 1604 | enum nl80211_band band;
|
| 1605 |
|
| 1606 | ret = fq_init(fq, 4096);
|
| 1607 | if (ret)
|
| 1608 | return ret;
|
| 1609 |
|
| 1610 | |
| 1611 | * If the hardware doesn't support VHT, it is safe to limit the maximum
|
| 1612 | * queue size. 4 Mbytes is 64 max-size aggregates in 802.11n.
|
| 1613 |
|
| 1614 | for (band = 0; band < NUM_NL80211_BANDS; band++) {
|
| 1615 | struct ieee80211_supported_band *sband;
|
| 1616 |
|
| 1617 | sband = local->hw.wiphy->bands[band];
|
| 1618 | if (!sband)
|
| 1619 | continue;
|
| 1620 |
|
| 1621 | supp_vht = supp_vht || sband->vht_cap.vht_supported;
|
| 1622 | }
|
| 1623 |
|
| 1624 | if (!supp_vht)
|
| 1625 | fq->memory_limit = 4 << 20;
|
| 1626 |
|
| 1627 | codel_params_init(&local->cparams);
|
| 1628 | local->cparams.interval = MS2TIME(100);
|
| 1629 | local->cparams.target = MS2TIME(20);
|
| 1630 | local->cparams.ecn = true;
|
| 1631 |
|
| 1632 | local->cvars = kvzalloc_objs(local->cvars[0], fq->flows_cnt);
|
| 1633 | if (!local->cvars) {
|
| 1634 | spin_lock_bh(&fq->lock);
|
| 1635 | fq_reset(fq, fq_skb_free_func);
|
| 1636 | spin_unlock_bh(&fq->lock);
|
| 1637 | return -ENOMEM;
|
| 1638 | }
|
| 1639 |
|
| 1640 | for (i = 0; i < fq->flows_cnt; i++)
|
| 1641 | codel_vars_init(&local->cvars[i]);
|
| 1642 |
|
| 1643 | ieee80211_txq_set_params(local, -1);
|
| 1644 |
|
| 1645 | return 0;
|
| 1646 | }
|
| 1647 |
|
| 1648 | void ieee80211_txq_teardown_flows(struct ieee80211_local *local)
|
| 1649 | {
|
| 1650 | struct fq *fq = &local->fq;
|
| 1651 |
|
| 1652 | kvfree(local->cvars);
|
| 1653 | local->cvars = NULL;
|
| 1654 |
|
| 1655 | spin_lock_bh(&fq->lock);
|
| 1656 | fq_reset(fq, fq_skb_free_func);
|
| 1657 | spin_unlock_bh(&fq->lock);
|
| 1658 | }
|
| 1659 |
|
| 1660 | static bool ieee80211_queue_skb(struct ieee80211_local *local,
|
| 1661 | struct ieee80211_sub_if_data *sdata,
|
| 1662 | struct sta_info *sta,
|
| 1663 | struct sk_buff *skb)
|
| 1664 | {
|
| 1665 | struct ieee80211_vif *vif;
|
| 1666 | struct txq_info *txqi;
|
| 1667 |
|
| 1668 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
|
| 1669 | return false;
|
| 1670 |
|
| 1671 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
| 1672 | sdata = container_of(sdata->bss,
|
| 1673 | struct ieee80211_sub_if_data, u.ap);
|
| 1674 |
|
| 1675 | vif = &sdata->vif;
|
| 1676 | txqi = ieee80211_get_txq(local, vif, sta, skb);
|
| 1677 |
|
| 1678 | if (!txqi)
|
| 1679 | return false;
|
| 1680 |
|
| 1681 | ieee80211_txq_enqueue(local, txqi, skb);
|
| 1682 |
|
| 1683 | schedule_and_wake_txq(local, txqi);
|
| 1684 |
|
| 1685 | return true;
|
| 1686 | }
|
| 1687 |
|
| 1688 | static bool ieee80211_tx_frags(struct ieee80211_local *local,
|
| 1689 | struct ieee80211_vif *vif,
|
| 1690 | struct sta_info *sta,
|
| 1691 | struct sk_buff_head *skbs,
|
| 1692 | bool txpending)
|
| 1693 | {
|
| 1694 | struct ieee80211_tx_control control = {};
|
| 1695 | struct sk_buff *skb, *tmp;
|
| 1696 | unsigned long flags;
|
| 1697 |
|
| 1698 | skb_queue_walk_safe(skbs, skb, tmp) {
|
| 1699 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 1700 | int q = info->hw_queue;
|
| 1701 |
|
| 1702 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
|
| 1703 | if (WARN_ON_ONCE(q >= local->hw.queues)) {
|
| 1704 | __skb_unlink(skb, skbs);
|
| 1705 | ieee80211_free_txskb(&local->hw, skb);
|
| 1706 | continue;
|
| 1707 | }
|
| 1708 | #endif
|
| 1709 |
|
| 1710 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
| 1711 | if (local->queue_stop_reasons[q] ||
|
| 1712 | (!txpending && !skb_queue_empty(&local->pending[q]))) {
|
| 1713 | if (unlikely(info->flags &
|
| 1714 | IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) {
|
| 1715 | if (local->queue_stop_reasons[q] &
|
| 1716 | ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL)) {
|
| 1717 | |
| 1718 | * Drop off-channel frames if queues
|
| 1719 | * are stopped for any reason other
|
| 1720 | * than off-channel operation. Never
|
| 1721 | * queue them.
|
| 1722 |
|
| 1723 | spin_unlock_irqrestore(
|
| 1724 | &local->queue_stop_reason_lock,
|
| 1725 | flags);
|
| 1726 | ieee80211_purge_tx_queue(&local->hw,
|
| 1727 | skbs);
|
| 1728 | return true;
|
| 1729 | }
|
| 1730 | } else {
|
| 1731 |
|
| 1732 | |
| 1733 | * Since queue is stopped, queue up frames for
|
| 1734 | * later transmission from the tx-pending
|
| 1735 | * tasklet when the queue is woken again.
|
| 1736 |
|
| 1737 | if (txpending)
|
| 1738 | skb_queue_splice_init(skbs,
|
| 1739 | &local->pending[q]);
|
| 1740 | else
|
| 1741 | skb_queue_splice_tail_init(skbs,
|
| 1742 | &local->pending[q]);
|
| 1743 |
|
| 1744 | spin_unlock_irqrestore(&local->queue_stop_reason_lock,
|
| 1745 | flags);
|
| 1746 | return false;
|
| 1747 | }
|
| 1748 | }
|
| 1749 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
| 1750 |
|
| 1751 | info->control.vif = vif;
|
| 1752 | control.sta = sta ? &sta->sta : NULL;
|
| 1753 |
|
| 1754 | __skb_unlink(skb, skbs);
|
| 1755 | drv_tx(local, &control, skb);
|
| 1756 | }
|
| 1757 |
|
| 1758 | return true;
|
| 1759 | }
|
| 1760 |
|
| 1761 | |
| 1762 | * Returns false if the frame couldn't be transmitted but was queued instead.
|
| 1763 |
|
| 1764 | static bool __ieee80211_tx(struct ieee80211_local *local,
|
| 1765 | struct sk_buff_head *skbs, struct sta_info *sta,
|
| 1766 | bool txpending)
|
| 1767 | {
|
| 1768 | struct ieee80211_tx_info *info;
|
| 1769 | struct ieee80211_sub_if_data *sdata;
|
| 1770 | struct ieee80211_vif *vif;
|
| 1771 | struct sk_buff *skb;
|
| 1772 | bool result;
|
| 1773 |
|
| 1774 | if (WARN_ON(skb_queue_empty(skbs)))
|
| 1775 | return true;
|
| 1776 |
|
| 1777 | skb = skb_peek(skbs);
|
| 1778 | info = IEEE80211_SKB_CB(skb);
|
| 1779 | sdata = vif_to_sdata(info->control.vif);
|
| 1780 | if (sta && !sta->uploaded)
|
| 1781 | sta = NULL;
|
| 1782 |
|
| 1783 | switch (sdata->vif.type) {
|
| 1784 | case NL80211_IFTYPE_MONITOR:
|
| 1785 | if ((sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) ||
|
| 1786 | ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
|
| 1787 | vif = &sdata->vif;
|
| 1788 | break;
|
| 1789 | }
|
| 1790 | sdata = rcu_dereference(local->monitor_sdata);
|
| 1791 | if (sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) {
|
| 1792 | vif = &sdata->vif;
|
| 1793 | info->hw_queue =
|
| 1794 | vif->hw_queue[skb_get_queue_mapping(skb)];
|
| 1795 | } else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
|
| 1796 | ieee80211_purge_tx_queue(&local->hw, skbs);
|
| 1797 | return true;
|
| 1798 | } else
|
| 1799 | vif = NULL;
|
| 1800 | break;
|
| 1801 | case NL80211_IFTYPE_AP_VLAN:
|
| 1802 | sdata = container_of(sdata->bss,
|
| 1803 | struct ieee80211_sub_if_data, u.ap);
|
| 1804 | fallthrough;
|
| 1805 | default:
|
| 1806 | vif = &sdata->vif;
|
| 1807 | break;
|
| 1808 | }
|
| 1809 |
|
| 1810 | result = ieee80211_tx_frags(local, vif, sta, skbs, txpending);
|
| 1811 |
|
| 1812 | WARN_ON_ONCE(!skb_queue_empty(skbs));
|
| 1813 |
|
| 1814 | return result;
|
| 1815 | }
|
| 1816 |
|
| 1817 | |
| 1818 | * Invoke TX handlers, return 0 on success and non-zero if the
|
| 1819 | * frame was dropped or queued.
|
| 1820 | *
|
| 1821 | * The handlers are split into an early and late part. The latter is everything
|
| 1822 | * that can be sensitive to reordering, and will be deferred to after packets
|
| 1823 | * are dequeued from the intermediate queues (when they are enabled).
|
| 1824 |
|
| 1825 | static int invoke_tx_handlers_early(struct ieee80211_tx_data *tx)
|
| 1826 | {
|
| 1827 | ieee80211_tx_result res = TX_DROP;
|
| 1828 |
|
| 1829 | #define CALL_TXH(txh) \
|
| 1830 | do { \
|
| 1831 | res = txh(tx); \
|
| 1832 | if (res != TX_CONTINUE) \
|
| 1833 | goto txh_done; \
|
| 1834 | } while (0)
|
| 1835 |
|
| 1836 | CALL_TXH(ieee80211_tx_h_dynamic_ps);
|
| 1837 | CALL_TXH(ieee80211_tx_h_check_assoc);
|
| 1838 | CALL_TXH(ieee80211_tx_h_ps_buf);
|
| 1839 | CALL_TXH(ieee80211_tx_h_check_control_port_protocol);
|
| 1840 | CALL_TXH(ieee80211_tx_h_select_key);
|
| 1841 |
|
| 1842 | txh_done:
|
| 1843 | if (unlikely(res == TX_DROP)) {
|
| 1844 | tx->sdata->tx_handlers_drop++;
|
| 1845 | if (tx->skb)
|
| 1846 | ieee80211_free_txskb(&tx->local->hw, tx->skb);
|
| 1847 | else
|
| 1848 | ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs);
|
| 1849 | return -1;
|
| 1850 | } else if (unlikely(res == TX_QUEUED)) {
|
| 1851 | I802_DEBUG_INC(tx->local->tx_handlers_queued);
|
| 1852 | return -1;
|
| 1853 | }
|
| 1854 |
|
| 1855 | return 0;
|
| 1856 | }
|
| 1857 |
|
| 1858 | |
| 1859 | * Late handlers can be called while the sta lock is held. Handlers that can
|
| 1860 | * cause packets to be generated will cause deadlock!
|
| 1861 |
|
| 1862 | static int invoke_tx_handlers_late(struct ieee80211_tx_data *tx)
|
| 1863 | {
|
| 1864 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
| 1865 | ieee80211_tx_result res = TX_CONTINUE;
|
| 1866 |
|
| 1867 | if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
|
| 1868 | CALL_TXH(ieee80211_tx_h_rate_ctrl);
|
| 1869 |
|
| 1870 | if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) {
|
| 1871 | __skb_queue_tail(&tx->skbs, tx->skb);
|
| 1872 | tx->skb = NULL;
|
| 1873 | goto txh_done;
|
| 1874 | }
|
| 1875 |
|
| 1876 | CALL_TXH(ieee80211_tx_h_michael_mic_add);
|
| 1877 | CALL_TXH(ieee80211_tx_h_sequence);
|
| 1878 | CALL_TXH(ieee80211_tx_h_fragment);
|
| 1879 |
|
| 1880 | CALL_TXH(ieee80211_tx_h_stats);
|
| 1881 | CALL_TXH(ieee80211_tx_h_encrypt);
|
| 1882 | if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
|
| 1883 | CALL_TXH(ieee80211_tx_h_calculate_duration);
|
| 1884 | #undef CALL_TXH
|
| 1885 |
|
| 1886 | txh_done:
|
| 1887 | if (unlikely(res == TX_DROP)) {
|
| 1888 | tx->sdata->tx_handlers_drop++;
|
| 1889 | if (tx->skb)
|
| 1890 | ieee80211_free_txskb(&tx->local->hw, tx->skb);
|
| 1891 | else
|
| 1892 | ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs);
|
| 1893 | return -1;
|
| 1894 | } else if (unlikely(res == TX_QUEUED)) {
|
| 1895 | I802_DEBUG_INC(tx->local->tx_handlers_queued);
|
| 1896 | return -1;
|
| 1897 | }
|
| 1898 |
|
| 1899 | return 0;
|
| 1900 | }
|
| 1901 |
|
| 1902 | static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
|
| 1903 | {
|
| 1904 | int r = invoke_tx_handlers_early(tx);
|
| 1905 |
|
| 1906 | if (r)
|
| 1907 | return r;
|
| 1908 | return invoke_tx_handlers_late(tx);
|
| 1909 | }
|
| 1910 |
|
| 1911 | bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
|
| 1912 | struct ieee80211_vif *vif, struct sk_buff *skb,
|
| 1913 | int band, struct ieee80211_sta **sta)
|
| 1914 | {
|
| 1915 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 1916 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 1917 | struct ieee80211_tx_data tx;
|
| 1918 | struct sk_buff *skb2;
|
| 1919 |
|
| 1920 | if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
|
| 1921 | kfree_skb(skb);
|
| 1922 | return false;
|
| 1923 | }
|
| 1924 |
|
| 1925 | info->band = band;
|
| 1926 | info->control.vif = vif;
|
| 1927 | info->hw_queue = vif->hw_queue[skb_get_queue_mapping(skb)];
|
| 1928 |
|
| 1929 | if (invoke_tx_handlers(&tx))
|
| 1930 | return false;
|
| 1931 |
|
| 1932 | if (sta) {
|
| 1933 | if (tx.sta)
|
| 1934 | *sta = &tx.sta->sta;
|
| 1935 | else
|
| 1936 | *sta = NULL;
|
| 1937 | }
|
| 1938 |
|
| 1939 |
|
| 1940 | skb2 = __skb_dequeue(&tx.skbs);
|
| 1941 | if (WARN_ON(skb2 != skb || !skb_queue_empty(&tx.skbs))) {
|
| 1942 | ieee80211_free_txskb(hw, skb2);
|
| 1943 | ieee80211_purge_tx_queue(hw, &tx.skbs);
|
| 1944 | return false;
|
| 1945 | }
|
| 1946 |
|
| 1947 | return true;
|
| 1948 | }
|
| 1949 | EXPORT_SYMBOL(ieee80211_tx_prepare_skb);
|
| 1950 |
|
| 1951 | |
| 1952 | * Returns false if the frame couldn't be transmitted but was queued instead.
|
| 1953 |
|
| 1954 | static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
|
| 1955 | struct sta_info *sta, struct sk_buff *skb,
|
| 1956 | bool txpending)
|
| 1957 | {
|
| 1958 | struct ieee80211_local *local = sdata->local;
|
| 1959 | struct ieee80211_tx_data tx;
|
| 1960 | ieee80211_tx_result res_prepare;
|
| 1961 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 1962 | bool result = true;
|
| 1963 |
|
| 1964 | if (unlikely(skb->len < 10)) {
|
| 1965 | dev_kfree_skb(skb);
|
| 1966 | return true;
|
| 1967 | }
|
| 1968 |
|
| 1969 |
|
| 1970 | res_prepare = ieee80211_tx_prepare(sdata, &tx, sta, skb);
|
| 1971 |
|
| 1972 | if (unlikely(res_prepare == TX_DROP)) {
|
| 1973 | ieee80211_free_txskb(&local->hw, skb);
|
| 1974 | tx.sdata->tx_handlers_drop++;
|
| 1975 | return true;
|
| 1976 | } else if (unlikely(res_prepare == TX_QUEUED)) {
|
| 1977 | return true;
|
| 1978 | }
|
| 1979 |
|
| 1980 |
|
| 1981 | if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) ||
|
| 1982 | !ieee80211_hw_check(&local->hw, QUEUE_CONTROL))
|
| 1983 | info->hw_queue =
|
| 1984 | sdata->vif.hw_queue[skb_get_queue_mapping(skb)];
|
| 1985 |
|
| 1986 | if (invoke_tx_handlers_early(&tx))
|
| 1987 | return true;
|
| 1988 |
|
| 1989 | if (ieee80211_queue_skb(local, sdata, tx.sta, tx.skb))
|
| 1990 | return true;
|
| 1991 |
|
| 1992 | if (!invoke_tx_handlers_late(&tx))
|
| 1993 | result = __ieee80211_tx(local, &tx.skbs, tx.sta, txpending);
|
| 1994 |
|
| 1995 | return result;
|
| 1996 | }
|
| 1997 |
|
| 1998 |
|
| 1999 |
|
| 2000 | enum ieee80211_encrypt {
|
| 2001 | ENCRYPT_NO,
|
| 2002 | ENCRYPT_MGMT,
|
| 2003 | ENCRYPT_DATA,
|
| 2004 | };
|
| 2005 |
|
| 2006 | static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
|
| 2007 | struct sk_buff *skb,
|
| 2008 | int head_need,
|
| 2009 | enum ieee80211_encrypt encrypt)
|
| 2010 | {
|
| 2011 | struct ieee80211_local *local = sdata->local;
|
| 2012 | bool enc_tailroom;
|
| 2013 | int tail_need = 0;
|
| 2014 |
|
| 2015 | enc_tailroom = encrypt == ENCRYPT_MGMT ||
|
| 2016 | (encrypt == ENCRYPT_DATA &&
|
| 2017 | sdata->crypto_tx_tailroom_needed_cnt);
|
| 2018 |
|
| 2019 | if (enc_tailroom) {
|
| 2020 | tail_need = IEEE80211_ENCRYPT_TAILROOM;
|
| 2021 | tail_need -= skb_tailroom(skb);
|
| 2022 | tail_need = max_t(int, tail_need, 0);
|
| 2023 | }
|
| 2024 |
|
| 2025 | if (skb_cloned(skb) &&
|
| 2026 | (!ieee80211_hw_check(&local->hw, SUPPORTS_CLONED_SKBS) ||
|
| 2027 | !skb_clone_writable(skb, ETH_HLEN) || enc_tailroom))
|
| 2028 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
|
| 2029 | else if (head_need || tail_need)
|
| 2030 | I802_DEBUG_INC(local->tx_expand_skb_head);
|
| 2031 | else
|
| 2032 | return 0;
|
| 2033 |
|
| 2034 | if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) {
|
| 2035 | wiphy_debug(local->hw.wiphy,
|
| 2036 | "failed to reallocate TX buffer\n");
|
| 2037 | return -ENOMEM;
|
| 2038 | }
|
| 2039 |
|
| 2040 | return 0;
|
| 2041 | }
|
| 2042 |
|
| 2043 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
|
| 2044 | struct sta_info *sta, struct sk_buff *skb)
|
| 2045 | {
|
| 2046 | struct ieee80211_local *local = sdata->local;
|
| 2047 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 2048 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
| 2049 | int headroom;
|
| 2050 | enum ieee80211_encrypt encrypt;
|
| 2051 |
|
| 2052 | if (info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)
|
| 2053 | encrypt = ENCRYPT_NO;
|
| 2054 | else if (ieee80211_is_mgmt(hdr->frame_control))
|
| 2055 | encrypt = ENCRYPT_MGMT;
|
| 2056 | else
|
| 2057 | encrypt = ENCRYPT_DATA;
|
| 2058 |
|
| 2059 | headroom = local->tx_headroom;
|
| 2060 | if (encrypt != ENCRYPT_NO)
|
| 2061 | headroom += IEEE80211_ENCRYPT_HEADROOM;
|
| 2062 | headroom -= skb_headroom(skb);
|
| 2063 | headroom = max_t(int, 0, headroom);
|
| 2064 |
|
| 2065 | if (ieee80211_skb_resize(sdata, skb, headroom, encrypt)) {
|
| 2066 | ieee80211_free_txskb(&local->hw, skb);
|
| 2067 | return;
|
| 2068 | }
|
| 2069 |
|
| 2070 |
|
| 2071 | hdr = (struct ieee80211_hdr *) skb->data;
|
| 2072 | info->control.vif = &sdata->vif;
|
| 2073 |
|
| 2074 | if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
| 2075 | if (ieee80211_is_data(hdr->frame_control) &&
|
| 2076 | is_unicast_ether_addr(hdr->addr1)) {
|
| 2077 | if (mesh_nexthop_resolve(sdata, skb))
|
| 2078 | return;
|
| 2079 | } else {
|
| 2080 | ieee80211_mps_set_frame_flags(sdata, NULL, hdr);
|
| 2081 | }
|
| 2082 | }
|
| 2083 |
|
| 2084 | ieee80211_set_qos_hdr(sdata, skb);
|
| 2085 | ieee80211_tx(sdata, sta, skb, false);
|
| 2086 | }
|
| 2087 |
|
| 2088 | static bool ieee80211_validate_radiotap_len(struct sk_buff *skb)
|
| 2089 | {
|
| 2090 | struct ieee80211_radiotap_header *rthdr =
|
| 2091 | (struct ieee80211_radiotap_header *)skb->data;
|
| 2092 |
|
| 2093 |
|
| 2094 | if (unlikely(skb_headlen(skb) < sizeof(struct ieee80211_radiotap_header)))
|
| 2095 | return false;
|
| 2096 |
|
| 2097 |
|
| 2098 | if (unlikely(rthdr->it_version))
|
| 2099 | return false;
|
| 2100 |
|
| 2101 |
|
| 2102 | if (unlikely(skb_headlen(skb) < ieee80211_get_radiotap_len(skb->data)))
|
| 2103 | return false;
|
| 2104 |
|
| 2105 | return true;
|
| 2106 | }
|
| 2107 |
|
| 2108 | static bool ieee80211_rate_bw_usable(u16 rate_flags,
|
| 2109 | const struct cfg80211_chan_def *chandef)
|
| 2110 | {
|
| 2111 | int width;
|
| 2112 |
|
| 2113 | if (!chandef)
|
| 2114 | return true;
|
| 2115 |
|
| 2116 | if (rate_flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
|
| 2117 | width = 160;
|
| 2118 | else if (rate_flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
|
| 2119 | width = 80;
|
| 2120 | else if (rate_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
| 2121 | width = 40;
|
| 2122 | else
|
| 2123 | return true;
|
| 2124 |
|
| 2125 | return width <= cfg80211_chandef_get_width(chandef);
|
| 2126 | }
|
| 2127 |
|
| 2128 | bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
|
| 2129 | struct net_device *dev,
|
| 2130 | const struct cfg80211_chan_def *chandef)
|
| 2131 | {
|
| 2132 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
|
| 2133 | struct ieee80211_radiotap_iterator iterator;
|
| 2134 | struct ieee80211_radiotap_header *rthdr =
|
| 2135 | (struct ieee80211_radiotap_header *) skb->data;
|
| 2136 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 2137 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
|
| 2138 | NULL);
|
| 2139 | u16 txflags;
|
| 2140 | u16 rate = 0;
|
| 2141 | bool rate_found = false;
|
| 2142 | u8 rate_retries = 0;
|
| 2143 | u16 rate_flags = 0;
|
| 2144 | u8 mcs_known, mcs_flags, mcs_bw;
|
| 2145 | u16 vht_known;
|
| 2146 | u8 vht_mcs = 0, vht_nss = 0;
|
| 2147 | int i;
|
| 2148 |
|
| 2149 | if (!ieee80211_validate_radiotap_len(skb))
|
| 2150 | return false;
|
| 2151 |
|
| 2152 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
|
| 2153 | IEEE80211_TX_CTL_DONTFRAG;
|
| 2154 |
|
| 2155 | |
| 2156 | * for every radiotap entry that is present
|
| 2157 | * (ieee80211_radiotap_iterator_next returns -ENOENT when no more
|
| 2158 | * entries present, or -EINVAL on error)
|
| 2159 |
|
| 2160 |
|
| 2161 | while (!ret) {
|
| 2162 | ret = ieee80211_radiotap_iterator_next(&iterator);
|
| 2163 |
|
| 2164 | if (ret)
|
| 2165 | continue;
|
| 2166 |
|
| 2167 |
|
| 2168 | switch (iterator.this_arg_index) {
|
| 2169 | |
| 2170 | * You must take care when dereferencing iterator.this_arg
|
| 2171 | * for multibyte types... the pointer is not aligned. Use
|
| 2172 | * get_unaligned((type *)iterator.this_arg) to dereference
|
| 2173 | * iterator.this_arg for type "type" safely on all arches.
|
| 2174 |
|
| 2175 | case IEEE80211_RADIOTAP_FLAGS:
|
| 2176 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) {
|
| 2177 | |
| 2178 | * this indicates that the skb we have been
|
| 2179 | * handed has the 32-bit FCS CRC at the end...
|
| 2180 | * we should react to that by snipping it off
|
| 2181 | * because it will be recomputed and added
|
| 2182 | * on transmission
|
| 2183 |
|
| 2184 | if (skb->len < (iterator._max_length + FCS_LEN))
|
| 2185 | return false;
|
| 2186 |
|
| 2187 | skb_trim(skb, skb->len - FCS_LEN);
|
| 2188 | }
|
| 2189 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
|
| 2190 | info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
| 2191 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
|
| 2192 | info->flags &= ~IEEE80211_TX_CTL_DONTFRAG;
|
| 2193 | break;
|
| 2194 |
|
| 2195 | case IEEE80211_RADIOTAP_TX_FLAGS:
|
| 2196 | txflags = get_unaligned_le16(iterator.this_arg);
|
| 2197 | if (txflags & IEEE80211_RADIOTAP_F_TX_NOACK)
|
| 2198 | info->flags |= IEEE80211_TX_CTL_NO_ACK;
|
| 2199 | if (txflags & IEEE80211_RADIOTAP_F_TX_NOSEQNO)
|
| 2200 | info->control.flags |= IEEE80211_TX_CTRL_NO_SEQNO;
|
| 2201 | if (txflags & IEEE80211_RADIOTAP_F_TX_ORDER)
|
| 2202 | info->control.flags |=
|
| 2203 | IEEE80211_TX_CTRL_DONT_REORDER;
|
| 2204 | break;
|
| 2205 |
|
| 2206 | case IEEE80211_RADIOTAP_RATE:
|
| 2207 | rate = *iterator.this_arg;
|
| 2208 | rate_flags = 0;
|
| 2209 | rate_found = true;
|
| 2210 | break;
|
| 2211 |
|
| 2212 | case IEEE80211_RADIOTAP_ANTENNA:
|
| 2213 |
|
| 2214 |
|
| 2215 | if (*iterator.this_arg < 2)
|
| 2216 | info->control.antennas |= BIT(*iterator.this_arg);
|
| 2217 | break;
|
| 2218 |
|
| 2219 | case IEEE80211_RADIOTAP_DATA_RETRIES:
|
| 2220 | rate_retries = *iterator.this_arg;
|
| 2221 | break;
|
| 2222 |
|
| 2223 | case IEEE80211_RADIOTAP_MCS:
|
| 2224 | mcs_known = iterator.this_arg[0];
|
| 2225 | mcs_flags = iterator.this_arg[1];
|
| 2226 | if (!(mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_MCS))
|
| 2227 | break;
|
| 2228 |
|
| 2229 | rate_found = true;
|
| 2230 | rate = iterator.this_arg[2];
|
| 2231 | rate_flags = IEEE80211_TX_RC_MCS;
|
| 2232 |
|
| 2233 | if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_GI &&
|
| 2234 | mcs_flags & IEEE80211_RADIOTAP_MCS_SGI)
|
| 2235 | rate_flags |= IEEE80211_TX_RC_SHORT_GI;
|
| 2236 |
|
| 2237 | mcs_bw = mcs_flags & IEEE80211_RADIOTAP_MCS_BW_MASK;
|
| 2238 | if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_BW &&
|
| 2239 | mcs_bw == IEEE80211_RADIOTAP_MCS_BW_40)
|
| 2240 | rate_flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
|
| 2241 |
|
| 2242 | if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FEC &&
|
| 2243 | mcs_flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC)
|
| 2244 | info->flags |= IEEE80211_TX_CTL_LDPC;
|
| 2245 |
|
| 2246 | if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_STBC) {
|
| 2247 | u8 stbc = u8_get_bits(mcs_flags,
|
| 2248 | IEEE80211_RADIOTAP_MCS_STBC_MASK);
|
| 2249 |
|
| 2250 | info->flags |=
|
| 2251 | u32_encode_bits(stbc,
|
| 2252 | IEEE80211_TX_CTL_STBC);
|
| 2253 | }
|
| 2254 | break;
|
| 2255 |
|
| 2256 | case IEEE80211_RADIOTAP_VHT:
|
| 2257 | vht_known = get_unaligned_le16(iterator.this_arg);
|
| 2258 | rate_found = true;
|
| 2259 |
|
| 2260 | rate_flags = IEEE80211_TX_RC_VHT_MCS;
|
| 2261 | if ((vht_known & IEEE80211_RADIOTAP_VHT_KNOWN_GI) &&
|
| 2262 | (iterator.this_arg[2] &
|
| 2263 | IEEE80211_RADIOTAP_VHT_FLAG_SGI))
|
| 2264 | rate_flags |= IEEE80211_TX_RC_SHORT_GI;
|
| 2265 | if (vht_known &
|
| 2266 | IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH) {
|
| 2267 | if (iterator.this_arg[3] == 1)
|
| 2268 | rate_flags |=
|
| 2269 | IEEE80211_TX_RC_40_MHZ_WIDTH;
|
| 2270 | else if (iterator.this_arg[3] == 4)
|
| 2271 | rate_flags |=
|
| 2272 | IEEE80211_TX_RC_80_MHZ_WIDTH;
|
| 2273 | else if (iterator.this_arg[3] == 11)
|
| 2274 | rate_flags |=
|
| 2275 | IEEE80211_TX_RC_160_MHZ_WIDTH;
|
| 2276 | }
|
| 2277 |
|
| 2278 | vht_mcs = iterator.this_arg[4] >> 4;
|
| 2279 | if (vht_mcs > 11)
|
| 2280 | vht_mcs = 0;
|
| 2281 | vht_nss = iterator.this_arg[4] & 0xF;
|
| 2282 | if (!vht_nss || vht_nss > 8)
|
| 2283 | vht_nss = 1;
|
| 2284 | break;
|
| 2285 |
|
| 2286 | |
| 2287 | * Please update the file
|
| 2288 | * Documentation/networking/mac80211-injection.rst
|
| 2289 | * when parsing new fields here.
|
| 2290 |
|
| 2291 |
|
| 2292 | default:
|
| 2293 | break;
|
| 2294 | }
|
| 2295 | }
|
| 2296 |
|
| 2297 | if (ret != -ENOENT)
|
| 2298 | return false;
|
| 2299 |
|
| 2300 | if (rate_found) {
|
| 2301 | struct ieee80211_supported_band *sband =
|
| 2302 | local->hw.wiphy->bands[info->band];
|
| 2303 |
|
| 2304 | if (!ieee80211_rate_bw_usable(rate_flags, chandef))
|
| 2305 | return false;
|
| 2306 |
|
| 2307 | info->control.flags |= IEEE80211_TX_CTRL_RATE_INJECT;
|
| 2308 |
|
| 2309 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
|
| 2310 | info->control.rates[i].idx = -1;
|
| 2311 | info->control.rates[i].flags = 0;
|
| 2312 | info->control.rates[i].count = 0;
|
| 2313 | }
|
| 2314 |
|
| 2315 | if (rate_flags & IEEE80211_TX_RC_MCS) {
|
| 2316 |
|
| 2317 | if (IEEE80211_HT_MCS_CHAINS(rate) >
|
| 2318 | hweight8(info->control.antennas))
|
| 2319 | info->control.antennas = 0;
|
| 2320 |
|
| 2321 | info->control.rates[0].idx = rate;
|
| 2322 | } else if (rate_flags & IEEE80211_TX_RC_VHT_MCS) {
|
| 2323 |
|
| 2324 | if (vht_nss > hweight8(info->control.antennas))
|
| 2325 | info->control.antennas = 0;
|
| 2326 |
|
| 2327 | ieee80211_rate_set_vht(info->control.rates, vht_mcs,
|
| 2328 | vht_nss);
|
| 2329 | } else if (sband) {
|
| 2330 | for (i = 0; i < sband->n_bitrates; i++) {
|
| 2331 | if (rate * 5 != sband->bitrates[i].bitrate)
|
| 2332 | continue;
|
| 2333 |
|
| 2334 | info->control.rates[0].idx = i;
|
| 2335 | break;
|
| 2336 | }
|
| 2337 | }
|
| 2338 |
|
| 2339 | if (info->control.rates[0].idx < 0)
|
| 2340 | info->control.flags &= ~IEEE80211_TX_CTRL_RATE_INJECT;
|
| 2341 |
|
| 2342 | info->control.rates[0].flags = rate_flags;
|
| 2343 | info->control.rates[0].count = min_t(u8, rate_retries + 1,
|
| 2344 | local->hw.max_rate_tries);
|
| 2345 | }
|
| 2346 |
|
| 2347 | return true;
|
| 2348 | }
|
| 2349 |
|
| 2350 | netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
|
| 2351 | struct net_device *dev)
|
| 2352 | {
|
| 2353 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
|
| 2354 | struct ieee80211_chanctx_conf *chanctx_conf;
|
| 2355 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 2356 | struct ieee80211_hdr *hdr;
|
| 2357 | struct ieee80211_sub_if_data *tmp_sdata, *sdata;
|
| 2358 | struct cfg80211_chan_def *chandef;
|
| 2359 | u16 len_rthdr;
|
| 2360 | int hdrlen;
|
| 2361 |
|
| 2362 | sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
| 2363 | if (unlikely(!ieee80211_sdata_running(sdata)))
|
| 2364 | goto fail;
|
| 2365 |
|
| 2366 | memset(info, 0, sizeof(*info));
|
| 2367 | info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
|
| 2368 | IEEE80211_TX_CTL_INJECTED;
|
| 2369 |
|
| 2370 |
|
| 2371 | if (!ieee80211_validate_radiotap_len(skb))
|
| 2372 | goto fail;
|
| 2373 |
|
| 2374 |
|
| 2375 | len_rthdr = ieee80211_get_radiotap_len(skb->data);
|
| 2376 |
|
| 2377 | |
| 2378 | * fix up the pointers accounting for the radiotap
|
| 2379 | * header still being in there. We are being given
|
| 2380 | * a precooked IEEE80211 header so no need for
|
| 2381 | * normal processing
|
| 2382 |
|
| 2383 | skb_set_mac_header(skb, len_rthdr);
|
| 2384 | |
| 2385 | * these are just fixed to the end of the rt area since we
|
| 2386 | * don't have any better information and at this point, nobody cares
|
| 2387 |
|
| 2388 | skb_set_network_header(skb, len_rthdr);
|
| 2389 | skb_set_transport_header(skb, len_rthdr);
|
| 2390 |
|
| 2391 | if (skb_headlen(skb) < len_rthdr + 2)
|
| 2392 | goto fail;
|
| 2393 |
|
| 2394 | hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
|
| 2395 | hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
| 2396 |
|
| 2397 | if (skb_headlen(skb) < len_rthdr + hdrlen)
|
| 2398 | goto fail;
|
| 2399 |
|
| 2400 | |
| 2401 | * Initialize skb->protocol if the injected frame is a data frame
|
| 2402 | * carrying a rfc1042 header
|
| 2403 |
|
| 2404 | if (ieee80211_is_data(hdr->frame_control) &&
|
| 2405 | skb_headlen(skb) >= len_rthdr + hdrlen + sizeof(rfc1042_header) + 2) {
|
| 2406 | u8 *payload = (u8 *)hdr + hdrlen;
|
| 2407 |
|
| 2408 | if (ether_addr_equal(payload, rfc1042_header))
|
| 2409 | skb->protocol = cpu_to_be16((payload[6] << 8) |
|
| 2410 | payload[7]);
|
| 2411 | }
|
| 2412 |
|
| 2413 | rcu_read_lock();
|
| 2414 |
|
| 2415 | |
| 2416 | * We process outgoing injected frames that have a local address
|
| 2417 | * we handle as though they are non-injected frames.
|
| 2418 | * This code here isn't entirely correct, the local MAC address
|
| 2419 | * isn't always enough to find the interface to use; for proper
|
| 2420 | * VLAN support we have an nl80211-based mechanism.
|
| 2421 | *
|
| 2422 | * This is necessary, for example, for old hostapd versions that
|
| 2423 | * don't use nl80211-based management TX/RX.
|
| 2424 |
|
| 2425 | list_for_each_entry_rcu(tmp_sdata, &local->interfaces, list) {
|
| 2426 | if (!ieee80211_sdata_running(tmp_sdata))
|
| 2427 | continue;
|
| 2428 | if (tmp_sdata->vif.type == NL80211_IFTYPE_MONITOR ||
|
| 2429 | tmp_sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
| 2430 | continue;
|
| 2431 | if (ether_addr_equal(tmp_sdata->vif.addr, hdr->addr2)) {
|
| 2432 | sdata = tmp_sdata;
|
| 2433 | break;
|
| 2434 | }
|
| 2435 | }
|
| 2436 |
|
| 2437 | chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
|
| 2438 | if (!chanctx_conf) {
|
| 2439 | tmp_sdata = rcu_dereference(local->monitor_sdata);
|
| 2440 | if (tmp_sdata)
|
| 2441 | chanctx_conf =
|
| 2442 | rcu_dereference(tmp_sdata->vif.bss_conf.chanctx_conf);
|
| 2443 | }
|
| 2444 |
|
| 2445 | if (!chanctx_conf) {
|
| 2446 | struct ieee80211_chanctx *ctx;
|
| 2447 | bool first = true;
|
| 2448 |
|
| 2449 | list_for_each_entry_rcu(ctx, &local->chanctx_list, list) {
|
| 2450 | if (!first)
|
| 2451 | goto fail_rcu;
|
| 2452 | chanctx_conf = &ctx->conf;
|
| 2453 | first = false;
|
| 2454 | }
|
| 2455 | }
|
| 2456 |
|
| 2457 | if (chanctx_conf)
|
| 2458 | chandef = &chanctx_conf->def;
|
| 2459 | else
|
| 2460 | goto fail_rcu;
|
| 2461 |
|
| 2462 | |
| 2463 | * If driver/HW supports IEEE80211_CHAN_CAN_MONITOR we still
|
| 2464 | * shouldn't transmit on disabled channels.
|
| 2465 |
|
| 2466 | if (!cfg80211_chandef_usable(local->hw.wiphy, chandef,
|
| 2467 | IEEE80211_CHAN_DISABLED))
|
| 2468 | goto fail_rcu;
|
| 2469 |
|
| 2470 | |
| 2471 | * Frame injection is not allowed if beaconing is not allowed
|
| 2472 | * or if we need radar detection. Beaconing is usually not allowed when
|
| 2473 | * the mode or operation (Adhoc, AP, Mesh) does not support DFS.
|
| 2474 | * Passive scan is also used in world regulatory domains where
|
| 2475 | * your country is not known and as such it should be treated as
|
| 2476 | * NO TX unless the channel is explicitly allowed in which case
|
| 2477 | * your current regulatory domain would not have the passive scan
|
| 2478 | * flag.
|
| 2479 | *
|
| 2480 | * Since AP mode uses monitor interfaces to inject/TX management
|
| 2481 | * frames we can make AP mode the exception to this rule once it
|
| 2482 | * supports radar detection as its implementation can deal with
|
| 2483 | * radar detection by itself. We can do that later by adding a
|
| 2484 | * monitor flag interfaces used for AP support.
|
| 2485 |
|
| 2486 | if (!cfg80211_reg_can_beacon(local->hw.wiphy, chandef,
|
| 2487 | sdata->vif.type))
|
| 2488 | goto fail_rcu;
|
| 2489 |
|
| 2490 | info->band = chandef->chan->band;
|
| 2491 |
|
| 2492 | |
| 2493 | * with respect to the sub interface that the frame will actually
|
| 2494 | * be transmitted on. If the DONT_REORDER flag is set, the original
|
| 2495 | * skb-priority is preserved to assure frames injected with this
|
| 2496 | * flag are not reordered relative to each other.
|
| 2497 |
|
| 2498 | ieee80211_select_queue_80211(sdata, skb, hdr);
|
| 2499 | skb_set_queue_mapping(skb, ieee80211_ac_from_tid(skb->priority));
|
| 2500 |
|
| 2501 | |
| 2502 | * Process the radiotap header. This will now take into account the
|
| 2503 | * selected chandef above to accurately set injection rates and
|
| 2504 | * retransmissions.
|
| 2505 |
|
| 2506 | if (!ieee80211_parse_tx_radiotap(skb, dev, chandef))
|
| 2507 | goto fail_rcu;
|
| 2508 |
|
| 2509 |
|
| 2510 | skb_pull(skb, len_rthdr);
|
| 2511 |
|
| 2512 | ieee80211_xmit(sdata, NULL, skb);
|
| 2513 | rcu_read_unlock();
|
| 2514 |
|
| 2515 | return NETDEV_TX_OK;
|
| 2516 |
|
| 2517 | fail_rcu:
|
| 2518 | rcu_read_unlock();
|
| 2519 | fail:
|
| 2520 | dev_kfree_skb(skb);
|
| 2521 | return NETDEV_TX_OK;
|
| 2522 | }
|
| 2523 |
|
| 2524 | static inline bool ieee80211_is_tdls_setup(struct sk_buff *skb)
|
| 2525 | {
|
| 2526 | u16 ethertype = (skb->data[12] << 8) | skb->data[13];
|
| 2527 |
|
| 2528 | return ethertype == ETH_P_TDLS &&
|
| 2529 | skb->len > 14 &&
|
| 2530 | skb->data[14] == WLAN_TDLS_SNAP_RFTYPE;
|
| 2531 | }
|
| 2532 |
|
| 2533 | int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
|
| 2534 | struct sk_buff *skb,
|
| 2535 | struct sta_info **sta_out, bool bss)
|
| 2536 | {
|
| 2537 | struct sta_info *sta;
|
| 2538 |
|
| 2539 | switch (sdata->vif.type) {
|
| 2540 | case NL80211_IFTYPE_AP_VLAN:
|
| 2541 | sta = rcu_dereference(sdata->u.vlan.sta);
|
| 2542 | if (sta) {
|
| 2543 | *sta_out = sta;
|
| 2544 | return 0;
|
| 2545 | } else if (sdata->wdev.use_4addr) {
|
| 2546 | return -ENOLINK;
|
| 2547 | }
|
| 2548 | fallthrough;
|
| 2549 | case NL80211_IFTYPE_AP:
|
| 2550 | case NL80211_IFTYPE_OCB:
|
| 2551 | case NL80211_IFTYPE_ADHOC:
|
| 2552 | if (is_multicast_ether_addr(skb->data)) {
|
| 2553 | *sta_out = ERR_PTR(-ENOENT);
|
| 2554 | return 0;
|
| 2555 | }
|
| 2556 | if (bss)
|
| 2557 | sta = sta_info_get_bss(sdata, skb->data);
|
| 2558 | else
|
| 2559 | sta = sta_info_get(sdata, skb->data);
|
| 2560 | break;
|
| 2561 | #ifdef CONFIG_MAC80211_MESH
|
| 2562 | case NL80211_IFTYPE_MESH_POINT:
|
| 2563 |
|
| 2564 | *sta_out = NULL;
|
| 2565 | return 0;
|
| 2566 | #endif
|
| 2567 | case NL80211_IFTYPE_STATION:
|
| 2568 | if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
|
| 2569 | sta = sta_info_get(sdata, skb->data);
|
| 2570 | if (sta && test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
|
| 2571 | if (test_sta_flag(sta,
|
| 2572 | WLAN_STA_TDLS_PEER_AUTH)) {
|
| 2573 | *sta_out = sta;
|
| 2574 | return 0;
|
| 2575 | }
|
| 2576 |
|
| 2577 | |
| 2578 | * TDLS link during setup - throw out frames to
|
| 2579 | * peer. Allow TDLS-setup frames to unauthorized
|
| 2580 | * peers for the special case of a link teardown
|
| 2581 | * after a TDLS sta is removed due to being
|
| 2582 | * unreachable.
|
| 2583 |
|
| 2584 | if (!ieee80211_is_tdls_setup(skb))
|
| 2585 | return -EINVAL;
|
| 2586 | }
|
| 2587 |
|
| 2588 | }
|
| 2589 |
|
| 2590 | sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr);
|
| 2591 | if (!sta)
|
| 2592 | return -ENOLINK;
|
| 2593 | break;
|
| 2594 | case NL80211_IFTYPE_NAN_DATA:
|
| 2595 | if (is_multicast_ether_addr(skb->data)) {
|
| 2596 | *sta_out = ERR_PTR(-ENOENT);
|
| 2597 | return 0;
|
| 2598 | }
|
| 2599 | sta = sta_info_get(sdata, skb->data);
|
| 2600 | break;
|
| 2601 | default:
|
| 2602 | return -EINVAL;
|
| 2603 | }
|
| 2604 |
|
| 2605 | *sta_out = sta ?: ERR_PTR(-ENOENT);
|
| 2606 | return 0;
|
| 2607 | }
|
| 2608 |
|
| 2609 | static u16 ieee80211_store_ack_skb(struct ieee80211_local *local,
|
| 2610 | struct sk_buff *skb,
|
| 2611 | u32 *info_flags,
|
| 2612 | u64 cookie)
|
| 2613 | {
|
| 2614 | struct sk_buff *ack_skb;
|
| 2615 | u16 info_id = 0;
|
| 2616 |
|
| 2617 | if (skb->sk)
|
| 2618 | ack_skb = skb_clone_sk(skb);
|
| 2619 | else
|
| 2620 | ack_skb = skb_clone(skb, GFP_ATOMIC);
|
| 2621 |
|
| 2622 | if (ack_skb) {
|
| 2623 | unsigned long flags;
|
| 2624 | int id;
|
| 2625 |
|
| 2626 | spin_lock_irqsave(&local->ack_status_lock, flags);
|
| 2627 | id = idr_alloc(&local->ack_status_frames, ack_skb,
|
| 2628 | 1, 0x2000, GFP_ATOMIC);
|
| 2629 | spin_unlock_irqrestore(&local->ack_status_lock, flags);
|
| 2630 |
|
| 2631 | if (id >= 0) {
|
| 2632 | info_id = id;
|
| 2633 | *info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
| 2634 | if (cookie)
|
| 2635 | IEEE80211_SKB_CB(ack_skb)->ack.cookie = cookie;
|
| 2636 | } else {
|
| 2637 | kfree_skb(ack_skb);
|
| 2638 | }
|
| 2639 | }
|
| 2640 |
|
| 2641 | return info_id;
|
| 2642 | }
|
| 2643 |
|
| 2644 | static void ieee80211_remove_ack_skb(struct ieee80211_local *local, u16 info_id)
|
| 2645 | {
|
| 2646 | struct sk_buff *ack_skb;
|
| 2647 | unsigned long flags;
|
| 2648 |
|
| 2649 | spin_lock_irqsave(&local->ack_status_lock, flags);
|
| 2650 | ack_skb = idr_remove(&local->ack_status_frames, info_id);
|
| 2651 | spin_unlock_irqrestore(&local->ack_status_lock, flags);
|
| 2652 |
|
| 2653 | kfree_skb(ack_skb);
|
| 2654 | }
|
| 2655 |
|
| 2656 | |
| 2657 | * ieee80211_build_hdr - build 802.11 header in the given frame
|
| 2658 | * @sdata: virtual interface to build the header for
|
| 2659 | * @skb: the skb to build the header in
|
| 2660 | * @info_flags: skb flags to set
|
| 2661 | * @sta: the station pointer
|
| 2662 | * @ctrl_flags: info control flags to set
|
| 2663 | * @cookie: cookie pointer to fill (if not %NULL)
|
| 2664 | *
|
| 2665 | * This function takes the skb with 802.3 header and reformats the header to
|
| 2666 | * the appropriate IEEE 802.11 header based on which interface the packet is
|
| 2667 | * being transmitted on.
|
| 2668 | *
|
| 2669 | * Note that this function also takes care of the TX status request and
|
| 2670 | * potential unsharing of the SKB - this needs to be interleaved with the
|
| 2671 | * header building.
|
| 2672 | *
|
| 2673 | * The function requires the read-side RCU lock held
|
| 2674 | *
|
| 2675 | * Returns: the (possibly reallocated) skb or an ERR_PTR() code
|
| 2676 |
|
| 2677 | static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
|
| 2678 | struct sk_buff *skb, u32 info_flags,
|
| 2679 | struct sta_info *sta, u32 ctrl_flags,
|
| 2680 | u64 cookie)
|
| 2681 | {
|
| 2682 | struct ieee80211_local *local = sdata->local;
|
| 2683 | struct ieee80211_tx_info *info;
|
| 2684 | int head_need;
|
| 2685 | u16 ethertype, hdrlen, meshhdrlen = 0;
|
| 2686 | __le16 fc;
|
| 2687 | struct ieee80211_hdr hdr;
|
| 2688 | struct ieee80211s_hdr mesh_hdr __maybe_unused;
|
| 2689 | struct mesh_path __maybe_unused *mppath = NULL, *mpath = NULL;
|
| 2690 | const u8 *encaps_data;
|
| 2691 | int encaps_len, skip_header_bytes;
|
| 2692 | bool wme_sta = false, authorized = false;
|
| 2693 | bool tdls_peer;
|
| 2694 | bool multicast;
|
| 2695 | u16 info_id = 0;
|
| 2696 | struct ieee80211_chanctx_conf *chanctx_conf = NULL;
|
| 2697 | enum nl80211_band band;
|
| 2698 | int ret;
|
| 2699 | u8 link_id = u32_get_bits(ctrl_flags, IEEE80211_TX_CTRL_MLO_LINK);
|
| 2700 |
|
| 2701 | if (IS_ERR(sta))
|
| 2702 | sta = NULL;
|
| 2703 |
|
| 2704 | #ifdef CONFIG_MAC80211_DEBUGFS
|
| 2705 | if (local->force_tx_status)
|
| 2706 | info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
| 2707 | #endif
|
| 2708 |
|
| 2709 | |
| 2710 | * operation mode)
|
| 2711 | ethertype = (skb->data[12] << 8) | skb->data[13];
|
| 2712 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
|
| 2713 |
|
| 2714 | if (!ieee80211_vif_is_mld(&sdata->vif))
|
| 2715 | chanctx_conf =
|
| 2716 | rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
|
| 2717 |
|
| 2718 | switch (sdata->vif.type) {
|
| 2719 | case NL80211_IFTYPE_AP_VLAN:
|
| 2720 | if (sdata->wdev.use_4addr) {
|
| 2721 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
|
| 2722 |
|
| 2723 | memcpy(hdr.addr1, sta->sta.addr, ETH_ALEN);
|
| 2724 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
|
| 2725 | memcpy(hdr.addr3, skb->data, ETH_ALEN);
|
| 2726 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
|
| 2727 | hdrlen = 30;
|
| 2728 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
|
| 2729 | wme_sta = sta->sta.wme;
|
| 2730 | }
|
| 2731 | if (!ieee80211_vif_is_mld(&sdata->vif)) {
|
| 2732 | struct ieee80211_sub_if_data *ap_sdata;
|
| 2733 |
|
| 2734 |
|
| 2735 | ap_sdata = container_of(sdata->bss,
|
| 2736 | struct ieee80211_sub_if_data,
|
| 2737 | u.ap);
|
| 2738 | chanctx_conf =
|
| 2739 | rcu_dereference(ap_sdata->vif.bss_conf.chanctx_conf);
|
| 2740 | }
|
| 2741 | if (sdata->wdev.use_4addr)
|
| 2742 | break;
|
| 2743 | fallthrough;
|
| 2744 | case NL80211_IFTYPE_AP:
|
| 2745 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
|
| 2746 |
|
| 2747 | memcpy(hdr.addr1, skb->data, ETH_ALEN);
|
| 2748 |
|
| 2749 | if (ieee80211_vif_is_mld(&sdata->vif) && sta && !sta->sta.mlo) {
|
| 2750 | struct ieee80211_link_data *link;
|
| 2751 |
|
| 2752 | link_id = sta->deflink.link_id;
|
| 2753 | link = rcu_dereference(sdata->link[link_id]);
|
| 2754 | if (WARN_ON(!link)) {
|
| 2755 | ret = -ENOLINK;
|
| 2756 | goto free;
|
| 2757 | }
|
| 2758 | memcpy(hdr.addr2, link->conf->addr, ETH_ALEN);
|
| 2759 | } else if (link_id == IEEE80211_LINK_UNSPECIFIED ||
|
| 2760 | (sta && sta->sta.mlo)) {
|
| 2761 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
|
| 2762 | } else {
|
| 2763 | struct ieee80211_bss_conf *conf;
|
| 2764 |
|
| 2765 | conf = rcu_dereference(sdata->vif.link_conf[link_id]);
|
| 2766 | if (unlikely(!conf)) {
|
| 2767 | ret = -ENOLINK;
|
| 2768 | goto free;
|
| 2769 | }
|
| 2770 |
|
| 2771 | memcpy(hdr.addr2, conf->addr, ETH_ALEN);
|
| 2772 | }
|
| 2773 |
|
| 2774 | memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
|
| 2775 | hdrlen = 24;
|
| 2776 | break;
|
| 2777 | #ifdef CONFIG_MAC80211_MESH
|
| 2778 | case NL80211_IFTYPE_MESH_POINT:
|
| 2779 | if (!is_multicast_ether_addr(skb->data)) {
|
| 2780 | struct sta_info *next_hop;
|
| 2781 | bool mpp_lookup = true;
|
| 2782 |
|
| 2783 | mpath = mesh_path_lookup(sdata, skb->data);
|
| 2784 | if (mpath) {
|
| 2785 | mpp_lookup = false;
|
| 2786 | next_hop = rcu_dereference(mpath->next_hop);
|
| 2787 | if (!next_hop ||
|
| 2788 | !(mpath->flags & (MESH_PATH_ACTIVE |
|
| 2789 | MESH_PATH_RESOLVING)))
|
| 2790 | mpp_lookup = true;
|
| 2791 | }
|
| 2792 |
|
| 2793 | if (mpp_lookup) {
|
| 2794 | mppath = mpp_path_lookup(sdata, skb->data);
|
| 2795 | if (mppath)
|
| 2796 | mppath->exp_time = jiffies;
|
| 2797 | }
|
| 2798 |
|
| 2799 | if (mppath && mpath)
|
| 2800 | mesh_path_del(sdata, mpath->dst);
|
| 2801 | }
|
| 2802 |
|
| 2803 | |
| 2804 | * Use address extension if it is a packet from
|
| 2805 | * another interface or if we know the destination
|
| 2806 | * is being proxied by a portal (i.e. portal address
|
| 2807 | * differs from proxied address)
|
| 2808 |
|
| 2809 | if (ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN) &&
|
| 2810 | !(mppath && !ether_addr_equal(mppath->mpp, skb->data))) {
|
| 2811 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
|
| 2812 | skb->data, skb->data + ETH_ALEN);
|
| 2813 | meshhdrlen = ieee80211_new_mesh_header(sdata, &mesh_hdr,
|
| 2814 | NULL, NULL);
|
| 2815 | } else {
|
| 2816 | |
| 2817 | * For unicast with unknown forwarding information,
|
| 2818 | * destination might be in the MBSS or if that fails
|
| 2819 | * forwarded to another mesh gate. In either case
|
| 2820 | * resolution will be handled in ieee80211_xmit(), so
|
| 2821 | * leave the original DA. This also works for mcast
|
| 2822 | const u8 *mesh_da = skb->data;
|
| 2823 |
|
| 2824 | if (mppath)
|
| 2825 | mesh_da = mppath->mpp;
|
| 2826 | else if (mpath)
|
| 2827 | mesh_da = mpath->dst;
|
| 2828 |
|
| 2829 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
|
| 2830 | mesh_da, sdata->vif.addr);
|
| 2831 | if (is_multicast_ether_addr(mesh_da))
|
| 2832 |
|
| 2833 | meshhdrlen = ieee80211_new_mesh_header(
|
| 2834 | sdata, &mesh_hdr,
|
| 2835 | skb->data + ETH_ALEN, NULL);
|
| 2836 | else
|
| 2837 |
|
| 2838 | meshhdrlen = ieee80211_new_mesh_header(
|
| 2839 | sdata, &mesh_hdr, skb->data,
|
| 2840 | skb->data + ETH_ALEN);
|
| 2841 |
|
| 2842 | }
|
| 2843 |
|
| 2844 | |
| 2845 | * will be skipped.
|
| 2846 |
|
| 2847 | if ((ctrl_flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP) &&
|
| 2848 | is_zero_ether_addr(hdr.addr1))
|
| 2849 | memcpy(hdr.addr1, skb->data, ETH_ALEN);
|
| 2850 | break;
|
| 2851 | #endif
|
| 2852 | case NL80211_IFTYPE_STATION:
|
| 2853 |
|
| 2854 | tdls_peer = test_sta_flag(sta, WLAN_STA_TDLS_PEER);
|
| 2855 |
|
| 2856 | if (tdls_peer) {
|
| 2857 |
|
| 2858 | int tdls_link_id = ieee80211_tdls_sta_link_id(sta);
|
| 2859 | struct ieee80211_link_data *link;
|
| 2860 |
|
| 2861 |
|
| 2862 | memcpy(hdr.addr1, skb->data, ETH_ALEN);
|
| 2863 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
|
| 2864 | link = rcu_dereference(sdata->link[tdls_link_id]);
|
| 2865 | if (WARN_ON_ONCE(!link)) {
|
| 2866 | ret = -EINVAL;
|
| 2867 | goto free;
|
| 2868 | }
|
| 2869 | memcpy(hdr.addr3, link->u.mgd.bssid, ETH_ALEN);
|
| 2870 | hdrlen = 24;
|
| 2871 | } else if (sdata->u.mgd.use_4addr &&
|
| 2872 | cpu_to_be16(ethertype) != sdata->control_port_protocol) {
|
| 2873 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
|
| 2874 | IEEE80211_FCTL_TODS);
|
| 2875 |
|
| 2876 | memcpy(hdr.addr1, sdata->deflink.u.mgd.bssid, ETH_ALEN);
|
| 2877 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
|
| 2878 | memcpy(hdr.addr3, skb->data, ETH_ALEN);
|
| 2879 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
|
| 2880 | hdrlen = 30;
|
| 2881 | } else {
|
| 2882 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
|
| 2883 |
|
| 2884 | memcpy(hdr.addr1, sdata->vif.cfg.ap_addr, ETH_ALEN);
|
| 2885 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
|
| 2886 | memcpy(hdr.addr3, skb->data, ETH_ALEN);
|
| 2887 | hdrlen = 24;
|
| 2888 | }
|
| 2889 | break;
|
| 2890 | case NL80211_IFTYPE_OCB:
|
| 2891 |
|
| 2892 | memcpy(hdr.addr1, skb->data, ETH_ALEN);
|
| 2893 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
|
| 2894 | eth_broadcast_addr(hdr.addr3);
|
| 2895 | hdrlen = 24;
|
| 2896 | break;
|
| 2897 | case NL80211_IFTYPE_ADHOC:
|
| 2898 |
|
| 2899 | memcpy(hdr.addr1, skb->data, ETH_ALEN);
|
| 2900 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
|
| 2901 | memcpy(hdr.addr3, sdata->u.ibss.bssid, ETH_ALEN);
|
| 2902 | hdrlen = 24;
|
| 2903 | break;
|
| 2904 | case NL80211_IFTYPE_NAN_DATA: {
|
| 2905 | struct ieee80211_sub_if_data *nmi;
|
| 2906 |
|
| 2907 |
|
| 2908 | memcpy(hdr.addr1, skb->data, ETH_ALEN);
|
| 2909 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
|
| 2910 | nmi = rcu_dereference(sdata->u.nan_data.nmi);
|
| 2911 | if (!nmi) {
|
| 2912 | ret = -ENOTCONN;
|
| 2913 | goto free;
|
| 2914 | }
|
| 2915 | memcpy(hdr.addr3, nmi->u.nan.conf.cluster_id, ETH_ALEN);
|
| 2916 | hdrlen = 24;
|
| 2917 | break;
|
| 2918 | }
|
| 2919 | default:
|
| 2920 | ret = -EINVAL;
|
| 2921 | goto free;
|
| 2922 | }
|
| 2923 |
|
| 2924 | if (!chanctx_conf) {
|
| 2925 | if (sdata->vif.type == NL80211_IFTYPE_NAN_DATA) {
|
| 2926 |
|
| 2927 | band = NUM_NL80211_BANDS;
|
| 2928 | } else if (!ieee80211_vif_is_mld(&sdata->vif)) {
|
| 2929 | ret = -ENOTCONN;
|
| 2930 | goto free;
|
| 2931 | } else {
|
| 2932 |
|
| 2933 | band = 0;
|
| 2934 | }
|
| 2935 | } else {
|
| 2936 | band = chanctx_conf->def.chan->band;
|
| 2937 | }
|
| 2938 |
|
| 2939 | multicast = is_multicast_ether_addr(hdr.addr1);
|
| 2940 |
|
| 2941 |
|
| 2942 | if (sta) {
|
| 2943 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
|
| 2944 | wme_sta = sta->sta.wme;
|
| 2945 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
| 2946 |
|
| 2947 | wme_sta = true;
|
| 2948 | }
|
| 2949 |
|
| 2950 |
|
| 2951 | if (wme_sta) {
|
| 2952 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
|
| 2953 | hdrlen += 2;
|
| 2954 | }
|
| 2955 |
|
| 2956 | |
| 2957 | * Drop unicast frames to unauthorised stations unless they are
|
| 2958 | * EAPOL frames from the local station.
|
| 2959 |
|
| 2960 | if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) &&
|
| 2961 | (sdata->vif.type != NL80211_IFTYPE_OCB) &&
|
| 2962 | !multicast && !authorized &&
|
| 2963 | (cpu_to_be16(ethertype) != sdata->control_port_protocol ||
|
| 2964 | !ieee80211_is_our_addr(sdata, skb->data + ETH_ALEN, NULL)))) {
|
| 2965 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
|
| 2966 | net_info_ratelimited("%s: dropped frame to %pM (unauthorized port)\n",
|
| 2967 | sdata->name, hdr.addr1);
|
| 2968 | #endif
|
| 2969 |
|
| 2970 | I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
|
| 2971 |
|
| 2972 | ret = -EPERM;
|
| 2973 | goto free;
|
| 2974 | }
|
| 2975 |
|
| 2976 | if (unlikely(!multicast &&
|
| 2977 | (sk_requests_wifi_status(skb->sk) ||
|
| 2978 | ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS)))
|
| 2979 | info_id = ieee80211_store_ack_skb(local, skb, &info_flags,
|
| 2980 | cookie);
|
| 2981 |
|
| 2982 | |
| 2983 | * If the skb is shared we need to obtain our own copy.
|
| 2984 |
|
| 2985 | skb = skb_share_check(skb, GFP_ATOMIC);
|
| 2986 | if (unlikely(!skb)) {
|
| 2987 |
|
| 2988 | if (info_id)
|
| 2989 | ieee80211_remove_ack_skb(local, info_id);
|
| 2990 | return ERR_PTR(-ENOMEM);
|
| 2991 | }
|
| 2992 |
|
| 2993 |
|
| 2994 | info = IEEE80211_SKB_CB(skb);
|
| 2995 | memset(info, 0, sizeof(*info));
|
| 2996 |
|
| 2997 | info->flags = info_flags;
|
| 2998 | if (info_id) {
|
| 2999 | info->status_data = info_id;
|
| 3000 | info->status_data_idr = 1;
|
| 3001 | }
|
| 3002 | info->band = band;
|
| 3003 |
|
| 3004 | hdr.frame_control = fc;
|
| 3005 | hdr.duration_id = 0;
|
| 3006 | hdr.seq_ctrl = 0;
|
| 3007 |
|
| 3008 | skip_header_bytes = ETH_HLEN;
|
| 3009 | if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) {
|
| 3010 | encaps_data = bridge_tunnel_header;
|
| 3011 | encaps_len = sizeof(bridge_tunnel_header);
|
| 3012 | skip_header_bytes -= 2;
|
| 3013 | } else if (ethertype >= ETH_P_802_3_MIN) {
|
| 3014 | encaps_data = rfc1042_header;
|
| 3015 | encaps_len = sizeof(rfc1042_header);
|
| 3016 | skip_header_bytes -= 2;
|
| 3017 | } else {
|
| 3018 | encaps_data = NULL;
|
| 3019 | encaps_len = 0;
|
| 3020 | }
|
| 3021 |
|
| 3022 | skb_pull(skb, skip_header_bytes);
|
| 3023 | head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);
|
| 3024 |
|
| 3025 | |
| 3026 | * So we need to modify the skb header and hence need a copy of
|
| 3027 | * that. The head_need variable above doesn't, so far, include
|
| 3028 | * the needed header space that we don't need right away. If we
|
| 3029 | * can, then we don't reallocate right now but only after the
|
| 3030 | * frame arrives at the master device (if it does...)
|
| 3031 | *
|
| 3032 | * If we cannot, however, then we will reallocate to include all
|
| 3033 | * the ever needed space. Also, if we need to reallocate it anyway,
|
| 3034 | * make it big enough for everything we may ever need.
|
| 3035 |
|
| 3036 |
|
| 3037 | if (head_need > 0 || skb_cloned(skb)) {
|
| 3038 | head_need += IEEE80211_ENCRYPT_HEADROOM;
|
| 3039 | head_need += local->tx_headroom;
|
| 3040 | head_need = max_t(int, 0, head_need);
|
| 3041 | if (ieee80211_skb_resize(sdata, skb, head_need, ENCRYPT_DATA)) {
|
| 3042 | ret = -ENOMEM;
|
| 3043 | goto free_txskb;
|
| 3044 | }
|
| 3045 | }
|
| 3046 |
|
| 3047 | if (encaps_data)
|
| 3048 | memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len);
|
| 3049 |
|
| 3050 | #ifdef CONFIG_MAC80211_MESH
|
| 3051 | if (meshhdrlen > 0)
|
| 3052 | memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen);
|
| 3053 | #endif
|
| 3054 |
|
| 3055 | if (ieee80211_is_data_qos(fc)) {
|
| 3056 | __le16 *qos_control;
|
| 3057 |
|
| 3058 | qos_control = skb_push(skb, 2);
|
| 3059 | memcpy(skb_push(skb, hdrlen - 2), &hdr, hdrlen - 2);
|
| 3060 | |
| 3061 | * Maybe we could actually set some fields here, for now just
|
| 3062 | * initialise to zero to indicate no special operation.
|
| 3063 |
|
| 3064 | *qos_control = 0;
|
| 3065 | } else
|
| 3066 | memcpy(skb_push(skb, hdrlen), &hdr, hdrlen);
|
| 3067 |
|
| 3068 | skb_reset_mac_header(skb);
|
| 3069 |
|
| 3070 | if (likely(!cookie)) {
|
| 3071 | ctrl_flags |= u32_encode_bits(link_id,
|
| 3072 | IEEE80211_TX_CTRL_MLO_LINK);
|
| 3073 | } else {
|
| 3074 | unsigned int pre_conf_link_id;
|
| 3075 |
|
| 3076 | |
| 3077 | * ctrl_flags already have been set by
|
| 3078 | * ieee80211_tx_control_port(), here
|
| 3079 | * we just sanity check that
|
| 3080 |
|
| 3081 |
|
| 3082 | pre_conf_link_id = u32_get_bits(ctrl_flags,
|
| 3083 | IEEE80211_TX_CTRL_MLO_LINK);
|
| 3084 |
|
| 3085 | if (pre_conf_link_id != link_id &&
|
| 3086 | link_id != IEEE80211_LINK_UNSPECIFIED) {
|
| 3087 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
|
| 3088 | net_info_ratelimited("%s: dropped frame to %pM with bad link ID request (%d vs. %d)\n",
|
| 3089 | sdata->name, hdr.addr1,
|
| 3090 | pre_conf_link_id, link_id);
|
| 3091 | #endif
|
| 3092 | ret = -EINVAL;
|
| 3093 | goto free_txskb;
|
| 3094 | }
|
| 3095 | }
|
| 3096 |
|
| 3097 | info->control.flags = ctrl_flags;
|
| 3098 |
|
| 3099 | return skb;
|
| 3100 | free_txskb:
|
| 3101 | ieee80211_free_txskb(&local->hw, skb);
|
| 3102 | return ERR_PTR(ret);
|
| 3103 | free:
|
| 3104 | kfree_skb(skb);
|
| 3105 | return ERR_PTR(ret);
|
| 3106 | }
|
| 3107 |
|
| 3108 | |
| 3109 | * fast-xmit overview
|
| 3110 | *
|
| 3111 | * The core idea of this fast-xmit is to remove per-packet checks by checking
|
| 3112 | * them out of band. ieee80211_check_fast_xmit() implements the out-of-band
|
| 3113 | * checks that are needed to get the sta->fast_tx pointer assigned, after which
|
| 3114 | * much less work can be done per packet. For example, fragmentation must be
|
| 3115 | * disabled or the fast_tx pointer will not be set. All the conditions are seen
|
| 3116 | * in the code here.
|
| 3117 | *
|
| 3118 | * Once assigned, the fast_tx data structure also caches the per-packet 802.11
|
| 3119 | * header and other data to aid packet processing in ieee80211_xmit_fast().
|
| 3120 | *
|
| 3121 | * The most difficult part of this is that when any of these assumptions
|
| 3122 | * change, an external trigger (i.e. a call to ieee80211_clear_fast_xmit(),
|
| 3123 | * ieee80211_check_fast_xmit() or friends) is required to reset the data,
|
| 3124 | * since the per-packet code no longer checks the conditions. This is reflected
|
| 3125 | * by the calls to these functions throughout the rest of the code, and must be
|
| 3126 | * maintained if any of the TX path checks change.
|
| 3127 |
|
| 3128 |
|
| 3129 | void ieee80211_check_fast_xmit(struct sta_info *sta)
|
| 3130 | {
|
| 3131 | struct ieee80211_fast_tx build = {}, *fast_tx = NULL, *old;
|
| 3132 | struct ieee80211_local *local = sta->local;
|
| 3133 | struct ieee80211_sub_if_data *sdata = sta->sdata;
|
| 3134 | struct ieee80211_hdr *hdr = (void *)build.hdr;
|
| 3135 | struct ieee80211_chanctx_conf *chanctx_conf;
|
| 3136 | __le16 fc;
|
| 3137 |
|
| 3138 | if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT))
|
| 3139 | return;
|
| 3140 |
|
| 3141 | if (ieee80211_vif_is_mesh(&sdata->vif))
|
| 3142 | mesh_fast_tx_flush_sta(sdata, sta);
|
| 3143 |
|
| 3144 | |
| 3145 | * invocations winning data access races to, e.g., the key pointer that
|
| 3146 | * is used.
|
| 3147 | * Without it, the invocation of this function right after the key
|
| 3148 | * pointer changes wouldn't be sufficient, as another CPU could access
|
| 3149 | * the pointer, then stall, and then do the cache update after the CPU
|
| 3150 | * that invalidated the key.
|
| 3151 | * With the locking, such scenarios cannot happen as the check for the
|
| 3152 | * key and the fast-tx assignment are done atomically, so the CPU that
|
| 3153 | * modifies the key will either wait or other one will see the key
|
| 3154 | * cleared/changed already.
|
| 3155 |
|
| 3156 | spin_lock_bh(&sta->lock);
|
| 3157 | if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) &&
|
| 3158 | !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS) &&
|
| 3159 | sdata->vif.type == NL80211_IFTYPE_STATION)
|
| 3160 | goto out;
|
| 3161 |
|
| 3162 | if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED) || !sta->uploaded)
|
| 3163 | goto out;
|
| 3164 |
|
| 3165 | if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
|
| 3166 | test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
|
| 3167 | test_sta_flag(sta, WLAN_STA_PS_DELIVER) ||
|
| 3168 | test_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT))
|
| 3169 | goto out;
|
| 3170 |
|
| 3171 | if (sdata->noack_map)
|
| 3172 | goto out;
|
| 3173 |
|
| 3174 |
|
| 3175 | if (local->hw.wiphy->frag_threshold != (u32)-1 &&
|
| 3176 | !ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG))
|
| 3177 | goto out;
|
| 3178 |
|
| 3179 | if (!ieee80211_vif_is_mld(&sdata->vif)) {
|
| 3180 | rcu_read_lock();
|
| 3181 | chanctx_conf =
|
| 3182 | rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
|
| 3183 | if (!chanctx_conf) {
|
| 3184 | rcu_read_unlock();
|
| 3185 | goto out;
|
| 3186 | }
|
| 3187 | build.band = chanctx_conf->def.chan->band;
|
| 3188 | rcu_read_unlock();
|
| 3189 | } else {
|
| 3190 |
|
| 3191 | build.band = 0;
|
| 3192 | }
|
| 3193 |
|
| 3194 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
|
| 3195 |
|
| 3196 | switch (sdata->vif.type) {
|
| 3197 | case NL80211_IFTYPE_ADHOC:
|
| 3198 |
|
| 3199 | build.da_offs = offsetof(struct ieee80211_hdr, addr1);
|
| 3200 | build.sa_offs = offsetof(struct ieee80211_hdr, addr2);
|
| 3201 | memcpy(hdr->addr3, sdata->u.ibss.bssid, ETH_ALEN);
|
| 3202 | build.hdr_len = 24;
|
| 3203 | break;
|
| 3204 | case NL80211_IFTYPE_STATION:
|
| 3205 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
|
| 3206 |
|
| 3207 | int tdls_link_id = ieee80211_tdls_sta_link_id(sta);
|
| 3208 | struct ieee80211_link_data *link;
|
| 3209 |
|
| 3210 |
|
| 3211 | build.da_offs = offsetof(struct ieee80211_hdr, addr1);
|
| 3212 | build.sa_offs = offsetof(struct ieee80211_hdr, addr2);
|
| 3213 | rcu_read_lock();
|
| 3214 | link = rcu_dereference(sdata->link[tdls_link_id]);
|
| 3215 | if (!WARN_ON_ONCE(!link))
|
| 3216 | memcpy(hdr->addr3, link->u.mgd.bssid, ETH_ALEN);
|
| 3217 | rcu_read_unlock();
|
| 3218 | build.hdr_len = 24;
|
| 3219 | break;
|
| 3220 | }
|
| 3221 |
|
| 3222 | if (sdata->u.mgd.use_4addr) {
|
| 3223 |
|
| 3224 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
|
| 3225 | IEEE80211_FCTL_TODS);
|
| 3226 |
|
| 3227 | memcpy(hdr->addr1, sdata->deflink.u.mgd.bssid, ETH_ALEN);
|
| 3228 | memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
|
| 3229 | build.da_offs = offsetof(struct ieee80211_hdr, addr3);
|
| 3230 | build.sa_offs = offsetof(struct ieee80211_hdr, addr4);
|
| 3231 | build.hdr_len = 30;
|
| 3232 | break;
|
| 3233 | }
|
| 3234 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
|
| 3235 |
|
| 3236 | memcpy(hdr->addr1, sdata->vif.cfg.ap_addr, ETH_ALEN);
|
| 3237 | build.da_offs = offsetof(struct ieee80211_hdr, addr3);
|
| 3238 | build.sa_offs = offsetof(struct ieee80211_hdr, addr2);
|
| 3239 | build.hdr_len = 24;
|
| 3240 | break;
|
| 3241 | case NL80211_IFTYPE_AP_VLAN:
|
| 3242 | if (sdata->wdev.use_4addr) {
|
| 3243 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
|
| 3244 | IEEE80211_FCTL_TODS);
|
| 3245 |
|
| 3246 | memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
|
| 3247 | memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
|
| 3248 | build.da_offs = offsetof(struct ieee80211_hdr, addr3);
|
| 3249 | build.sa_offs = offsetof(struct ieee80211_hdr, addr4);
|
| 3250 | build.hdr_len = 30;
|
| 3251 | break;
|
| 3252 | }
|
| 3253 | fallthrough;
|
| 3254 | case NL80211_IFTYPE_AP:
|
| 3255 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
|
| 3256 |
|
| 3257 | build.da_offs = offsetof(struct ieee80211_hdr, addr1);
|
| 3258 | if (sta->sta.mlo || !ieee80211_vif_is_mld(&sdata->vif)) {
|
| 3259 | memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
|
| 3260 | } else {
|
| 3261 | unsigned int link_id = sta->deflink.link_id;
|
| 3262 | struct ieee80211_link_data *link;
|
| 3263 |
|
| 3264 | rcu_read_lock();
|
| 3265 | link = rcu_dereference(sdata->link[link_id]);
|
| 3266 | if (WARN_ON(!link)) {
|
| 3267 | rcu_read_unlock();
|
| 3268 | goto out;
|
| 3269 | }
|
| 3270 | memcpy(hdr->addr2, link->conf->addr, ETH_ALEN);
|
| 3271 | rcu_read_unlock();
|
| 3272 | }
|
| 3273 | build.sa_offs = offsetof(struct ieee80211_hdr, addr3);
|
| 3274 | build.hdr_len = 24;
|
| 3275 | break;
|
| 3276 | default:
|
| 3277 |
|
| 3278 | goto out;
|
| 3279 | }
|
| 3280 |
|
| 3281 | if (sta->sta.wme) {
|
| 3282 | build.hdr_len += 2;
|
| 3283 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
|
| 3284 | }
|
| 3285 |
|
| 3286 | |
| 3287 | * but that's fine because the code that changes the pointers will call
|
| 3288 | * this function after doing so. For a single CPU that would be enough,
|
| 3289 | * for multiple see the comment above.
|
| 3290 |
|
| 3291 | build.key = rcu_access_pointer(sta->ptk[sta->ptk_idx]);
|
| 3292 | if (!build.key)
|
| 3293 | build.key = rcu_access_pointer(sdata->default_unicast_key);
|
| 3294 | if (build.key) {
|
| 3295 | bool gen_iv, iv_spc, mmic;
|
| 3296 |
|
| 3297 | gen_iv = build.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV;
|
| 3298 | iv_spc = build.key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE;
|
| 3299 | mmic = build.key->conf.flags &
|
| 3300 | (IEEE80211_KEY_FLAG_GENERATE_MMIC |
|
| 3301 | IEEE80211_KEY_FLAG_PUT_MIC_SPACE);
|
| 3302 |
|
| 3303 |
|
| 3304 | if (!(build.key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
| 3305 | goto out;
|
| 3306 |
|
| 3307 |
|
| 3308 | if (build.key->flags & KEY_FLAG_TAINTED)
|
| 3309 | goto out;
|
| 3310 |
|
| 3311 | switch (build.key->conf.cipher) {
|
| 3312 | case WLAN_CIPHER_SUITE_CCMP:
|
| 3313 | case WLAN_CIPHER_SUITE_CCMP_256:
|
| 3314 | if (gen_iv)
|
| 3315 | build.pn_offs = build.hdr_len;
|
| 3316 | if (gen_iv || iv_spc)
|
| 3317 | build.hdr_len += IEEE80211_CCMP_HDR_LEN;
|
| 3318 | break;
|
| 3319 | case WLAN_CIPHER_SUITE_GCMP:
|
| 3320 | case WLAN_CIPHER_SUITE_GCMP_256:
|
| 3321 | if (gen_iv)
|
| 3322 | build.pn_offs = build.hdr_len;
|
| 3323 | if (gen_iv || iv_spc)
|
| 3324 | build.hdr_len += IEEE80211_GCMP_HDR_LEN;
|
| 3325 | break;
|
| 3326 | case WLAN_CIPHER_SUITE_TKIP:
|
| 3327 |
|
| 3328 | if (mmic || gen_iv)
|
| 3329 | goto out;
|
| 3330 | if (iv_spc)
|
| 3331 | build.hdr_len += IEEE80211_TKIP_IV_LEN;
|
| 3332 | break;
|
| 3333 | case WLAN_CIPHER_SUITE_WEP40:
|
| 3334 | case WLAN_CIPHER_SUITE_WEP104:
|
| 3335 |
|
| 3336 | if (gen_iv)
|
| 3337 | goto out;
|
| 3338 | if (iv_spc)
|
| 3339 | build.hdr_len += IEEE80211_WEP_IV_LEN;
|
| 3340 | break;
|
| 3341 | case WLAN_CIPHER_SUITE_AES_CMAC:
|
| 3342 | case WLAN_CIPHER_SUITE_BIP_CMAC_256:
|
| 3343 | case WLAN_CIPHER_SUITE_BIP_GMAC_128:
|
| 3344 | case WLAN_CIPHER_SUITE_BIP_GMAC_256:
|
| 3345 | WARN(1,
|
| 3346 | "management cipher suite 0x%x enabled for data\n",
|
| 3347 | build.key->conf.cipher);
|
| 3348 | goto out;
|
| 3349 | default:
|
| 3350 |
|
| 3351 | if (WARN_ON(gen_iv))
|
| 3352 | goto out;
|
| 3353 | }
|
| 3354 |
|
| 3355 | fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
| 3356 | }
|
| 3357 |
|
| 3358 | hdr->frame_control = fc;
|
| 3359 |
|
| 3360 | memcpy(build.hdr + build.hdr_len,
|
| 3361 | rfc1042_header, sizeof(rfc1042_header));
|
| 3362 | build.hdr_len += sizeof(rfc1042_header);
|
| 3363 |
|
| 3364 | fast_tx = kmemdup(&build, sizeof(build), GFP_ATOMIC);
|
| 3365 |
|
| 3366 |
|
| 3367 | out:
|
| 3368 |
|
| 3369 | old = rcu_dereference_protected(sta->fast_tx,
|
| 3370 | lockdep_is_held(&sta->lock));
|
| 3371 | rcu_assign_pointer(sta->fast_tx, fast_tx);
|
| 3372 | if (old)
|
| 3373 | kfree_rcu(old, rcu_head);
|
| 3374 | spin_unlock_bh(&sta->lock);
|
| 3375 | }
|
| 3376 |
|
| 3377 | void ieee80211_check_fast_xmit_all(struct ieee80211_local *local)
|
| 3378 | {
|
| 3379 | struct sta_info *sta;
|
| 3380 |
|
| 3381 | rcu_read_lock();
|
| 3382 | list_for_each_entry_rcu(sta, &local->sta_list, list)
|
| 3383 | ieee80211_check_fast_xmit(sta);
|
| 3384 | rcu_read_unlock();
|
| 3385 | }
|
| 3386 |
|
| 3387 | void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata)
|
| 3388 | {
|
| 3389 | struct ieee80211_local *local = sdata->local;
|
| 3390 | struct sta_info *sta;
|
| 3391 |
|
| 3392 | rcu_read_lock();
|
| 3393 |
|
| 3394 | list_for_each_entry_rcu(sta, &local->sta_list, list) {
|
| 3395 | if (sdata != sta->sdata &&
|
| 3396 | (!sta->sdata->bss || sta->sdata->bss != sdata->bss))
|
| 3397 | continue;
|
| 3398 | ieee80211_check_fast_xmit(sta);
|
| 3399 | }
|
| 3400 |
|
| 3401 | rcu_read_unlock();
|
| 3402 | }
|
| 3403 |
|
| 3404 | void ieee80211_clear_fast_xmit(struct sta_info *sta)
|
| 3405 | {
|
| 3406 | struct ieee80211_fast_tx *fast_tx;
|
| 3407 |
|
| 3408 | spin_lock_bh(&sta->lock);
|
| 3409 | fast_tx = rcu_dereference_protected(sta->fast_tx,
|
| 3410 | lockdep_is_held(&sta->lock));
|
| 3411 | RCU_INIT_POINTER(sta->fast_tx, NULL);
|
| 3412 | spin_unlock_bh(&sta->lock);
|
| 3413 |
|
| 3414 | if (fast_tx)
|
| 3415 | kfree_rcu(fast_tx, rcu_head);
|
| 3416 | }
|
| 3417 |
|
| 3418 | static bool ieee80211_amsdu_realloc_pad(struct ieee80211_local *local,
|
| 3419 | struct sk_buff *skb, int headroom)
|
| 3420 | {
|
| 3421 | if (skb_headroom(skb) < headroom) {
|
| 3422 | I802_DEBUG_INC(local->tx_expand_skb_head);
|
| 3423 |
|
| 3424 | if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) {
|
| 3425 | wiphy_debug(local->hw.wiphy,
|
| 3426 | "failed to reallocate TX buffer\n");
|
| 3427 | return false;
|
| 3428 | }
|
| 3429 | }
|
| 3430 |
|
| 3431 | return true;
|
| 3432 | }
|
| 3433 |
|
| 3434 | static bool ieee80211_amsdu_prepare_head(struct ieee80211_sub_if_data *sdata,
|
| 3435 | struct ieee80211_fast_tx *fast_tx,
|
| 3436 | struct sk_buff *skb)
|
| 3437 | {
|
| 3438 | struct ieee80211_local *local = sdata->local;
|
| 3439 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 3440 | struct ieee80211_hdr *hdr;
|
| 3441 | struct ethhdr *amsdu_hdr;
|
| 3442 | int hdr_len = fast_tx->hdr_len - sizeof(rfc1042_header);
|
| 3443 | int subframe_len = skb->len - hdr_len;
|
| 3444 | void *data;
|
| 3445 | u8 *qc, *h_80211_src, *h_80211_dst;
|
| 3446 | const u8 *bssid;
|
| 3447 |
|
| 3448 | if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
|
| 3449 | return false;
|
| 3450 |
|
| 3451 | if (info->control.flags & IEEE80211_TX_CTRL_AMSDU)
|
| 3452 | return true;
|
| 3453 |
|
| 3454 | if (!ieee80211_amsdu_realloc_pad(local, skb,
|
| 3455 | sizeof(*amsdu_hdr) +
|
| 3456 | local->hw.extra_tx_headroom))
|
| 3457 | return false;
|
| 3458 |
|
| 3459 | data = skb_push(skb, sizeof(*amsdu_hdr));
|
| 3460 | memmove(data, data + sizeof(*amsdu_hdr), hdr_len);
|
| 3461 | hdr = data;
|
| 3462 | amsdu_hdr = data + hdr_len;
|
| 3463 |
|
| 3464 | h_80211_src = data + fast_tx->sa_offs;
|
| 3465 | h_80211_dst = data + fast_tx->da_offs;
|
| 3466 |
|
| 3467 | amsdu_hdr->h_proto = cpu_to_be16(subframe_len);
|
| 3468 | ether_addr_copy(amsdu_hdr->h_source, h_80211_src);
|
| 3469 | ether_addr_copy(amsdu_hdr->h_dest, h_80211_dst);
|
| 3470 |
|
| 3471 | |
| 3472 | * fields needs to be changed to BSSID for A-MSDU frames depending
|
| 3473 | * on FromDS/ToDS values.
|
| 3474 |
|
| 3475 | switch (sdata->vif.type) {
|
| 3476 | case NL80211_IFTYPE_STATION:
|
| 3477 | bssid = sdata->vif.cfg.ap_addr;
|
| 3478 | break;
|
| 3479 | case NL80211_IFTYPE_AP:
|
| 3480 | case NL80211_IFTYPE_AP_VLAN:
|
| 3481 | bssid = sdata->vif.addr;
|
| 3482 | break;
|
| 3483 | default:
|
| 3484 | bssid = NULL;
|
| 3485 | }
|
| 3486 |
|
| 3487 | if (bssid && ieee80211_has_fromds(hdr->frame_control))
|
| 3488 | ether_addr_copy(h_80211_src, bssid);
|
| 3489 |
|
| 3490 | if (bssid && ieee80211_has_tods(hdr->frame_control))
|
| 3491 | ether_addr_copy(h_80211_dst, bssid);
|
| 3492 |
|
| 3493 | qc = ieee80211_get_qos_ctl(hdr);
|
| 3494 | *qc |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
|
| 3495 |
|
| 3496 | info->control.flags |= IEEE80211_TX_CTRL_AMSDU;
|
| 3497 |
|
| 3498 | return true;
|
| 3499 | }
|
| 3500 |
|
| 3501 | static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
|
| 3502 | struct sta_info *sta,
|
| 3503 | struct ieee80211_fast_tx *fast_tx,
|
| 3504 | struct sk_buff *skb,
|
| 3505 | const u8 *da, const u8 *sa)
|
| 3506 | {
|
| 3507 | struct ieee80211_local *local = sdata->local;
|
| 3508 | struct fq *fq = &local->fq;
|
| 3509 | struct fq_tin *tin;
|
| 3510 | struct fq_flow *flow;
|
| 3511 | u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
|
| 3512 | struct ieee80211_txq *txq = sta->sta.txq[tid];
|
| 3513 | struct txq_info *txqi;
|
| 3514 | struct sk_buff **frag_tail, *head;
|
| 3515 | int subframe_len = skb->len - ETH_ALEN;
|
| 3516 | u8 max_subframes = sta->sta.max_amsdu_subframes;
|
| 3517 | int max_frags = local->hw.max_tx_fragments;
|
| 3518 | int max_amsdu_len = sta->sta.cur->max_amsdu_len;
|
| 3519 | int orig_truesize;
|
| 3520 | u32 flow_idx;
|
| 3521 | __be16 len;
|
| 3522 | void *data;
|
| 3523 | bool ret = false;
|
| 3524 | unsigned int orig_len;
|
| 3525 | int n = 2, nfrags, pad = 0;
|
| 3526 | u16 hdrlen;
|
| 3527 |
|
| 3528 | if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
|
| 3529 | return false;
|
| 3530 |
|
| 3531 | if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
|
| 3532 | return false;
|
| 3533 |
|
| 3534 | if (ieee80211_vif_is_mesh(&sdata->vif))
|
| 3535 | return false;
|
| 3536 |
|
| 3537 | if (skb_is_gso(skb))
|
| 3538 | return false;
|
| 3539 |
|
| 3540 | if (!txq)
|
| 3541 | return false;
|
| 3542 |
|
| 3543 | txqi = to_txq_info(txq);
|
| 3544 | if (test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags))
|
| 3545 | return false;
|
| 3546 |
|
| 3547 | if (sta->sta.cur->max_rc_amsdu_len)
|
| 3548 | max_amsdu_len = min_t(int, max_amsdu_len,
|
| 3549 | sta->sta.cur->max_rc_amsdu_len);
|
| 3550 |
|
| 3551 | if (sta->sta.cur->max_tid_amsdu_len[tid])
|
| 3552 | max_amsdu_len = min_t(int, max_amsdu_len,
|
| 3553 | sta->sta.cur->max_tid_amsdu_len[tid]);
|
| 3554 |
|
| 3555 | flow_idx = fq_flow_idx(fq, skb);
|
| 3556 |
|
| 3557 | spin_lock_bh(&fq->lock);
|
| 3558 |
|
| 3559 | |
| 3560 | * responsive to environment changes.
|
| 3561 |
|
| 3562 |
|
| 3563 | tin = &txqi->tin;
|
| 3564 | flow = fq_flow_classify(fq, tin, flow_idx, skb);
|
| 3565 | head = skb_peek_tail(&flow->queue);
|
| 3566 | if (!head || skb_is_gso(head))
|
| 3567 | goto out;
|
| 3568 |
|
| 3569 | orig_truesize = head->truesize;
|
| 3570 | orig_len = head->len;
|
| 3571 |
|
| 3572 | if (skb->len + head->len > max_amsdu_len)
|
| 3573 | goto out;
|
| 3574 |
|
| 3575 | nfrags = 1 + skb_shinfo(skb)->nr_frags;
|
| 3576 | nfrags += 1 + skb_shinfo(head)->nr_frags;
|
| 3577 | frag_tail = &skb_shinfo(head)->frag_list;
|
| 3578 | while (*frag_tail) {
|
| 3579 | nfrags += 1 + skb_shinfo(*frag_tail)->nr_frags;
|
| 3580 | frag_tail = &(*frag_tail)->next;
|
| 3581 | n++;
|
| 3582 | }
|
| 3583 |
|
| 3584 | if (max_subframes && n > max_subframes)
|
| 3585 | goto out;
|
| 3586 |
|
| 3587 | if (max_frags && nfrags > max_frags)
|
| 3588 | goto out;
|
| 3589 |
|
| 3590 | if (!drv_can_aggregate_in_amsdu(local, head, skb))
|
| 3591 | goto out;
|
| 3592 |
|
| 3593 | if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head))
|
| 3594 | goto out;
|
| 3595 |
|
| 3596 | |
| 3597 | * and frag_tail should be &skb_shinfo(head)->frag_list.
|
| 3598 | * However, ieee80211_amsdu_prepare_head() can reallocate it.
|
| 3599 | * Reload frag_tail to have it pointing to the correct place.
|
| 3600 |
|
| 3601 | if (n == 2)
|
| 3602 | frag_tail = &skb_shinfo(head)->frag_list;
|
| 3603 |
|
| 3604 | |
| 3605 | * Pad out the previous subframe to a multiple of 4 by adding the
|
| 3606 | * padding to the next one, that's being added. Note that head->len
|
| 3607 | * is the length of the full A-MSDU, but that works since each time
|
| 3608 | * we add a new subframe we pad out the previous one to a multiple
|
| 3609 | * of 4 and thus it no longer matters in the next round.
|
| 3610 |
|
| 3611 | hdrlen = fast_tx->hdr_len - sizeof(rfc1042_header);
|
| 3612 | if ((head->len - hdrlen) & 3)
|
| 3613 | pad = 4 - ((head->len - hdrlen) & 3);
|
| 3614 |
|
| 3615 | if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) +
|
| 3616 | 2 + pad))
|
| 3617 | goto out_recalc;
|
| 3618 |
|
| 3619 | ret = true;
|
| 3620 | data = skb_push(skb, ETH_ALEN + 2);
|
| 3621 | ether_addr_copy(data, da);
|
| 3622 | ether_addr_copy(data + ETH_ALEN, sa);
|
| 3623 |
|
| 3624 | data += 2 * ETH_ALEN;
|
| 3625 | len = cpu_to_be16(subframe_len);
|
| 3626 | memcpy(data, &len, 2);
|
| 3627 | memcpy(data + 2, rfc1042_header, sizeof(rfc1042_header));
|
| 3628 |
|
| 3629 | memset(skb_push(skb, pad), 0, pad);
|
| 3630 |
|
| 3631 | head->len += skb->len;
|
| 3632 | head->data_len += skb->len;
|
| 3633 | *frag_tail = skb;
|
| 3634 |
|
| 3635 | out_recalc:
|
| 3636 | fq->memory_usage += head->truesize - orig_truesize;
|
| 3637 | if (head->len != orig_len) {
|
| 3638 | flow->backlog += head->len - orig_len;
|
| 3639 | tin->backlog_bytes += head->len - orig_len;
|
| 3640 | }
|
| 3641 | out:
|
| 3642 | spin_unlock_bh(&fq->lock);
|
| 3643 |
|
| 3644 | return ret;
|
| 3645 | }
|
| 3646 |
|
| 3647 | |
| 3648 | * Can be called while the sta lock is held. Anything that can cause packets to
|
| 3649 | * be generated will cause deadlock!
|
| 3650 |
|
| 3651 | static ieee80211_tx_result
|
| 3652 | ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata,
|
| 3653 | struct sta_info *sta, u8 pn_offs,
|
| 3654 | struct ieee80211_key *key,
|
| 3655 | struct ieee80211_tx_data *tx)
|
| 3656 | {
|
| 3657 | struct sk_buff *skb = tx->skb;
|
| 3658 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 3659 | struct ieee80211_hdr *hdr = (void *)skb->data;
|
| 3660 | u8 tid = IEEE80211_NUM_TIDS;
|
| 3661 |
|
| 3662 | if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL) &&
|
| 3663 | ieee80211_tx_h_rate_ctrl(tx) != TX_CONTINUE)
|
| 3664 | return TX_DROP;
|
| 3665 |
|
| 3666 | if (key)
|
| 3667 | info->control.hw_key = &key->conf;
|
| 3668 |
|
| 3669 | dev_sw_netstats_tx_add(skb->dev, 1, skb->len);
|
| 3670 |
|
| 3671 | if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
|
| 3672 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
|
| 3673 | hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid);
|
| 3674 | } else {
|
| 3675 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
|
| 3676 | hdr->seq_ctrl = cpu_to_le16(sdata->sequence_number);
|
| 3677 | sdata->sequence_number += 0x10;
|
| 3678 | }
|
| 3679 |
|
| 3680 | if (skb_shinfo(skb)->gso_size)
|
| 3681 | sta->deflink.tx_stats.msdu[tid] +=
|
| 3682 | DIV_ROUND_UP(skb->len, skb_shinfo(skb)->gso_size);
|
| 3683 | else
|
| 3684 | sta->deflink.tx_stats.msdu[tid]++;
|
| 3685 |
|
| 3686 | info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)];
|
| 3687 |
|
| 3688 | |
| 3689 | * has to consider fragmentation, so is more complex)
|
| 3690 |
|
| 3691 | sta->deflink.tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len;
|
| 3692 | sta->deflink.tx_stats.packets[skb_get_queue_mapping(skb)]++;
|
| 3693 |
|
| 3694 | if (pn_offs) {
|
| 3695 | u64 pn;
|
| 3696 | u8 *crypto_hdr = skb->data + pn_offs;
|
| 3697 |
|
| 3698 | switch (key->conf.cipher) {
|
| 3699 | case WLAN_CIPHER_SUITE_CCMP:
|
| 3700 | case WLAN_CIPHER_SUITE_CCMP_256:
|
| 3701 | case WLAN_CIPHER_SUITE_GCMP:
|
| 3702 | case WLAN_CIPHER_SUITE_GCMP_256:
|
| 3703 | pn = atomic64_inc_return(&key->conf.tx_pn);
|
| 3704 | crypto_hdr[0] = pn;
|
| 3705 | crypto_hdr[1] = pn >> 8;
|
| 3706 | crypto_hdr[3] = 0x20 | (key->conf.keyidx << 6);
|
| 3707 | crypto_hdr[4] = pn >> 16;
|
| 3708 | crypto_hdr[5] = pn >> 24;
|
| 3709 | crypto_hdr[6] = pn >> 32;
|
| 3710 | crypto_hdr[7] = pn >> 40;
|
| 3711 | break;
|
| 3712 | }
|
| 3713 | }
|
| 3714 |
|
| 3715 | return TX_CONTINUE;
|
| 3716 | }
|
| 3717 |
|
| 3718 | static netdev_features_t
|
| 3719 | ieee80211_sdata_netdev_features(struct ieee80211_sub_if_data *sdata)
|
| 3720 | {
|
| 3721 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
|
| 3722 | return sdata->vif.netdev_features;
|
| 3723 |
|
| 3724 | if (!sdata->bss)
|
| 3725 | return 0;
|
| 3726 |
|
| 3727 | sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
|
| 3728 | return sdata->vif.netdev_features;
|
| 3729 | }
|
| 3730 |
|
| 3731 | static struct sk_buff *
|
| 3732 | ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features)
|
| 3733 | {
|
| 3734 | if (skb_is_gso(skb)) {
|
| 3735 | struct sk_buff *segs;
|
| 3736 |
|
| 3737 | segs = skb_gso_segment(skb, features);
|
| 3738 | if (!segs)
|
| 3739 | return skb;
|
| 3740 | if (IS_ERR(segs))
|
| 3741 | goto free;
|
| 3742 |
|
| 3743 | consume_skb(skb);
|
| 3744 | return segs;
|
| 3745 | }
|
| 3746 |
|
| 3747 | if (skb_needs_linearize(skb, features) && __skb_linearize(skb))
|
| 3748 | goto free;
|
| 3749 |
|
| 3750 | if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
| 3751 | int ofs = skb_checksum_start_offset(skb);
|
| 3752 |
|
| 3753 | if (skb->encapsulation)
|
| 3754 | skb_set_inner_transport_header(skb, ofs);
|
| 3755 | else
|
| 3756 | skb_set_transport_header(skb, ofs);
|
| 3757 |
|
| 3758 | if (skb_csum_hwoffload_help(skb, features))
|
| 3759 | goto free;
|
| 3760 | }
|
| 3761 |
|
| 3762 | skb_mark_not_on_list(skb);
|
| 3763 | return skb;
|
| 3764 |
|
| 3765 | free:
|
| 3766 | kfree_skb(skb);
|
| 3767 | return NULL;
|
| 3768 | }
|
| 3769 |
|
| 3770 | void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
| 3771 | struct sta_info *sta,
|
| 3772 | struct ieee80211_fast_tx *fast_tx,
|
| 3773 | struct sk_buff *skb, bool ampdu,
|
| 3774 | const u8 *da, const u8 *sa)
|
| 3775 | {
|
| 3776 | struct ieee80211_local *local = sdata->local;
|
| 3777 | struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
|
| 3778 | struct ieee80211_tx_info *info;
|
| 3779 | struct ieee80211_tx_data tx;
|
| 3780 | ieee80211_tx_result r;
|
| 3781 | int hw_headroom = sdata->local->hw.extra_tx_headroom;
|
| 3782 | int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
|
| 3783 |
|
| 3784 | skb = skb_share_check(skb, GFP_ATOMIC);
|
| 3785 | if (unlikely(!skb))
|
| 3786 | return;
|
| 3787 |
|
| 3788 | if ((hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) &&
|
| 3789 | ieee80211_amsdu_aggregate(sdata, sta, fast_tx, skb, da, sa))
|
| 3790 | return;
|
| 3791 |
|
| 3792 | |
| 3793 | * as the may-encrypt argument for the resize to not account for
|
| 3794 | * more room than we already have in 'extra_head'
|
| 3795 |
|
| 3796 | if (unlikely(ieee80211_skb_resize(sdata, skb,
|
| 3797 | max_t(int, extra_head + hw_headroom -
|
| 3798 | skb_headroom(skb), 0),
|
| 3799 | ENCRYPT_NO)))
|
| 3800 | goto free;
|
| 3801 |
|
| 3802 | hdr = skb_push(skb, extra_head);
|
| 3803 | memcpy(skb->data, fast_tx->hdr, fast_tx->hdr_len);
|
| 3804 | memcpy(skb->data + fast_tx->da_offs, da, ETH_ALEN);
|
| 3805 | memcpy(skb->data + fast_tx->sa_offs, sa, ETH_ALEN);
|
| 3806 |
|
| 3807 | info = IEEE80211_SKB_CB(skb);
|
| 3808 | memset(info, 0, sizeof(*info));
|
| 3809 | info->band = fast_tx->band;
|
| 3810 | info->control.vif = &sdata->vif;
|
| 3811 | info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT |
|
| 3812 | IEEE80211_TX_CTL_DONTFRAG;
|
| 3813 | info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT |
|
| 3814 | u32_encode_bits(IEEE80211_LINK_UNSPECIFIED,
|
| 3815 | IEEE80211_TX_CTRL_MLO_LINK);
|
| 3816 |
|
| 3817 | #ifdef CONFIG_MAC80211_DEBUGFS
|
| 3818 | if (local->force_tx_status)
|
| 3819 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
| 3820 | #endif
|
| 3821 |
|
| 3822 | if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
|
| 3823 | u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
|
| 3824 |
|
| 3825 | *ieee80211_get_qos_ctl(hdr) = tid;
|
| 3826 | }
|
| 3827 |
|
| 3828 | __skb_queue_head_init(&tx.skbs);
|
| 3829 |
|
| 3830 | tx.flags = IEEE80211_TX_UNICAST;
|
| 3831 | tx.local = local;
|
| 3832 | tx.sdata = sdata;
|
| 3833 | tx.sta = sta;
|
| 3834 | tx.key = fast_tx->key;
|
| 3835 |
|
| 3836 | if (ieee80211_queue_skb(local, sdata, sta, skb))
|
| 3837 | return;
|
| 3838 |
|
| 3839 | tx.skb = skb;
|
| 3840 | r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs,
|
| 3841 | fast_tx->key, &tx);
|
| 3842 | tx.skb = NULL;
|
| 3843 | if (r == TX_DROP) {
|
| 3844 | tx.sdata->tx_handlers_drop++;
|
| 3845 | goto free;
|
| 3846 | }
|
| 3847 |
|
| 3848 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
| 3849 | sdata = container_of(sdata->bss,
|
| 3850 | struct ieee80211_sub_if_data, u.ap);
|
| 3851 |
|
| 3852 | __skb_queue_tail(&tx.skbs, skb);
|
| 3853 | ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false);
|
| 3854 | return;
|
| 3855 |
|
| 3856 | free:
|
| 3857 | kfree_skb(skb);
|
| 3858 | }
|
| 3859 |
|
| 3860 | static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
| 3861 | struct sta_info *sta,
|
| 3862 | struct ieee80211_fast_tx *fast_tx,
|
| 3863 | struct sk_buff *skb)
|
| 3864 | {
|
| 3865 | u16 ethertype = (skb->data[12] << 8) | skb->data[13];
|
| 3866 | struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
|
| 3867 | struct tid_ampdu_tx *tid_tx = NULL;
|
| 3868 | struct sk_buff *next;
|
| 3869 | struct ethhdr eth;
|
| 3870 | u8 tid = IEEE80211_NUM_TIDS;
|
| 3871 |
|
| 3872 |
|
| 3873 | if (cpu_to_be16(ethertype) == sdata->control_port_protocol)
|
| 3874 | return false;
|
| 3875 |
|
| 3876 |
|
| 3877 | if (ethertype < ETH_P_802_3_MIN)
|
| 3878 | return false;
|
| 3879 |
|
| 3880 |
|
| 3881 | if (sk_requests_wifi_status(skb->sk))
|
| 3882 | return false;
|
| 3883 |
|
| 3884 | if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
|
| 3885 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
|
| 3886 | tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
|
| 3887 | if (tid_tx) {
|
| 3888 | if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state))
|
| 3889 | return false;
|
| 3890 | if (tid_tx->timeout)
|
| 3891 | tid_tx->last_tx = jiffies;
|
| 3892 | }
|
| 3893 | }
|
| 3894 |
|
| 3895 | memcpy(ð, skb->data, ETH_HLEN - 2);
|
| 3896 |
|
| 3897 |
|
| 3898 | skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata));
|
| 3899 | if (!skb)
|
| 3900 | return true;
|
| 3901 |
|
| 3902 | skb_list_walk_safe(skb, skb, next) {
|
| 3903 | skb_mark_not_on_list(skb);
|
| 3904 | __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid_tx,
|
| 3905 | eth.h_dest, eth.h_source);
|
| 3906 | }
|
| 3907 |
|
| 3908 | return true;
|
| 3909 | }
|
| 3910 |
|
| 3911 | struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
|
| 3912 | struct ieee80211_txq *txq)
|
| 3913 | {
|
| 3914 | struct ieee80211_local *local = hw_to_local(hw);
|
| 3915 | struct txq_info *txqi = container_of(txq, struct txq_info, txq);
|
| 3916 | struct ieee80211_hdr *hdr;
|
| 3917 | struct sk_buff *skb = NULL;
|
| 3918 | struct fq *fq = &local->fq;
|
| 3919 | struct fq_tin *tin = &txqi->tin;
|
| 3920 | struct ieee80211_tx_info *info;
|
| 3921 | struct ieee80211_tx_data tx;
|
| 3922 | ieee80211_tx_result r;
|
| 3923 | struct ieee80211_vif *vif = txq->vif;
|
| 3924 | int q = vif->hw_queue[txq->ac];
|
| 3925 | unsigned long flags;
|
| 3926 | bool q_stopped;
|
| 3927 |
|
| 3928 | WARN_ON_ONCE(softirq_count() == 0);
|
| 3929 |
|
| 3930 | if (!ieee80211_txq_airtime_check(hw, txq))
|
| 3931 | return NULL;
|
| 3932 |
|
| 3933 | begin:
|
| 3934 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
| 3935 | q_stopped = local->queue_stop_reasons[q];
|
| 3936 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
| 3937 |
|
| 3938 | if (unlikely(q_stopped)) {
|
| 3939 |
|
| 3940 | set_bit(IEEE80211_TXQ_DIRTY, &txqi->flags);
|
| 3941 | return NULL;
|
| 3942 | }
|
| 3943 |
|
| 3944 | spin_lock_bh(&fq->lock);
|
| 3945 |
|
| 3946 |
|
| 3947 | skb = __skb_dequeue(&txqi->frags);
|
| 3948 | if (unlikely(skb)) {
|
| 3949 | if (!(IEEE80211_SKB_CB(skb)->control.flags &
|
| 3950 | IEEE80211_TX_INTCFL_NEED_TXPROCESSING))
|
| 3951 | goto out;
|
| 3952 | IEEE80211_SKB_CB(skb)->control.flags &=
|
| 3953 | ~IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
|
| 3954 | } else {
|
| 3955 | if (unlikely(test_bit(IEEE80211_TXQ_STOP, &txqi->flags)))
|
| 3956 | goto out;
|
| 3957 |
|
| 3958 | skb = fq_tin_dequeue(fq, tin, fq_tin_dequeue_func);
|
| 3959 | }
|
| 3960 |
|
| 3961 | if (!skb)
|
| 3962 | goto out;
|
| 3963 |
|
| 3964 | spin_unlock_bh(&fq->lock);
|
| 3965 |
|
| 3966 | hdr = (struct ieee80211_hdr *)skb->data;
|
| 3967 | info = IEEE80211_SKB_CB(skb);
|
| 3968 |
|
| 3969 | memset(&tx, 0, sizeof(tx));
|
| 3970 | __skb_queue_head_init(&tx.skbs);
|
| 3971 | tx.local = local;
|
| 3972 | tx.skb = skb;
|
| 3973 | tx.sdata = vif_to_sdata(info->control.vif);
|
| 3974 |
|
| 3975 | if (txq->sta) {
|
| 3976 | tx.sta = container_of(txq->sta, struct sta_info, sta);
|
| 3977 | |
| 3978 | * Drop unicast frames to unauthorised stations unless they are
|
| 3979 | * injected frames or EAPOL frames from the local station.
|
| 3980 |
|
| 3981 | if (unlikely(!(info->flags & IEEE80211_TX_CTL_INJECTED) &&
|
| 3982 | ieee80211_is_data_present(hdr->frame_control) &&
|
| 3983 | !ieee80211_vif_is_mesh(&tx.sdata->vif) &&
|
| 3984 | tx.sdata->vif.type != NL80211_IFTYPE_OCB &&
|
| 3985 | !is_multicast_ether_addr(hdr->addr1) &&
|
| 3986 | !test_sta_flag(tx.sta, WLAN_STA_AUTHORIZED) &&
|
| 3987 | (!(info->control.flags &
|
| 3988 | IEEE80211_TX_CTRL_PORT_CTRL_PROTO) ||
|
| 3989 | !ieee80211_is_our_addr(tx.sdata, hdr->addr2,
|
| 3990 | NULL)))) {
|
| 3991 | I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
|
| 3992 | ieee80211_free_txskb(&local->hw, skb);
|
| 3993 | goto begin;
|
| 3994 | }
|
| 3995 | }
|
| 3996 |
|
| 3997 | |
| 3998 | * The key can be removed while the packet was queued, so need to call
|
| 3999 | * this here to get the current key.
|
| 4000 |
|
| 4001 | info->control.hw_key = NULL;
|
| 4002 | r = ieee80211_tx_h_select_key(&tx);
|
| 4003 | if (r != TX_CONTINUE) {
|
| 4004 | ieee80211_free_txskb(&local->hw, skb);
|
| 4005 | goto begin;
|
| 4006 | }
|
| 4007 |
|
| 4008 | if (test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags))
|
| 4009 | info->flags |= (IEEE80211_TX_CTL_AMPDU |
|
| 4010 | IEEE80211_TX_CTL_DONTFRAG);
|
| 4011 |
|
| 4012 | if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
|
| 4013 | if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
|
| 4014 | r = ieee80211_tx_h_rate_ctrl(&tx);
|
| 4015 | if (r != TX_CONTINUE) {
|
| 4016 | ieee80211_free_txskb(&local->hw, skb);
|
| 4017 | goto begin;
|
| 4018 | }
|
| 4019 | }
|
| 4020 | goto encap_out;
|
| 4021 | }
|
| 4022 |
|
| 4023 | if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) {
|
| 4024 | struct sta_info *sta = container_of(txq->sta, struct sta_info,
|
| 4025 | sta);
|
| 4026 | u8 pn_offs = 0;
|
| 4027 |
|
| 4028 | if (tx.key &&
|
| 4029 | (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
|
| 4030 | pn_offs = ieee80211_hdrlen(hdr->frame_control);
|
| 4031 |
|
| 4032 | r = ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs,
|
| 4033 | tx.key, &tx);
|
| 4034 | if (r != TX_CONTINUE) {
|
| 4035 | ieee80211_free_txskb(&local->hw, skb);
|
| 4036 | goto begin;
|
| 4037 | }
|
| 4038 | } else {
|
| 4039 | if (invoke_tx_handlers_late(&tx))
|
| 4040 | goto begin;
|
| 4041 |
|
| 4042 | skb = __skb_dequeue(&tx.skbs);
|
| 4043 | info = IEEE80211_SKB_CB(skb);
|
| 4044 |
|
| 4045 | if (!skb_queue_empty(&tx.skbs)) {
|
| 4046 | spin_lock_bh(&fq->lock);
|
| 4047 | skb_queue_splice_tail(&tx.skbs, &txqi->frags);
|
| 4048 | spin_unlock_bh(&fq->lock);
|
| 4049 | }
|
| 4050 | }
|
| 4051 |
|
| 4052 | if (skb_has_frag_list(skb) &&
|
| 4053 | !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) {
|
| 4054 | if (skb_linearize(skb)) {
|
| 4055 | ieee80211_free_txskb(&local->hw, skb);
|
| 4056 | goto begin;
|
| 4057 | }
|
| 4058 | }
|
| 4059 |
|
| 4060 | switch (tx.sdata->vif.type) {
|
| 4061 | case NL80211_IFTYPE_MONITOR:
|
| 4062 | if ((tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) ||
|
| 4063 | ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
|
| 4064 | vif = &tx.sdata->vif;
|
| 4065 | break;
|
| 4066 | }
|
| 4067 | tx.sdata = rcu_dereference(local->monitor_sdata);
|
| 4068 | if (tx.sdata &&
|
| 4069 | ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) {
|
| 4070 | vif = &tx.sdata->vif;
|
| 4071 | info->hw_queue =
|
| 4072 | vif->hw_queue[skb_get_queue_mapping(skb)];
|
| 4073 | } else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
|
| 4074 | ieee80211_free_txskb(&local->hw, skb);
|
| 4075 | goto begin;
|
| 4076 | } else {
|
| 4077 | info->control.vif = NULL;
|
| 4078 | return skb;
|
| 4079 | }
|
| 4080 | break;
|
| 4081 | case NL80211_IFTYPE_AP_VLAN:
|
| 4082 | tx.sdata = container_of(tx.sdata->bss,
|
| 4083 | struct ieee80211_sub_if_data, u.ap);
|
| 4084 | fallthrough;
|
| 4085 | default:
|
| 4086 | vif = &tx.sdata->vif;
|
| 4087 | break;
|
| 4088 | }
|
| 4089 |
|
| 4090 | encap_out:
|
| 4091 | info->control.vif = vif;
|
| 4092 |
|
| 4093 | if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
|
| 4094 | bool ampdu = txq->sta && txq->ac != IEEE80211_AC_VO;
|
| 4095 | u32 airtime;
|
| 4096 |
|
| 4097 | airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
|
| 4098 | skb->len, ampdu);
|
| 4099 | if (!airtime)
|
| 4100 | return skb;
|
| 4101 |
|
| 4102 | airtime = ieee80211_info_set_tx_time_est(info, airtime);
|
| 4103 | info->tx_time_mc = !tx.sta;
|
| 4104 | ieee80211_sta_update_pending_airtime(local, tx.sta, txq->ac,
|
| 4105 | airtime, false,
|
| 4106 | info->tx_time_mc);
|
| 4107 | }
|
| 4108 |
|
| 4109 | return skb;
|
| 4110 |
|
| 4111 | out:
|
| 4112 | spin_unlock_bh(&fq->lock);
|
| 4113 |
|
| 4114 | return skb;
|
| 4115 | }
|
| 4116 | EXPORT_SYMBOL(ieee80211_tx_dequeue);
|
| 4117 |
|
| 4118 | static inline s32 ieee80211_sta_deficit(struct sta_info *sta, u8 ac)
|
| 4119 | {
|
| 4120 | struct airtime_info *air_info = &sta->airtime[ac];
|
| 4121 |
|
| 4122 | return air_info->deficit - atomic_read(&air_info->aql_tx_pending);
|
| 4123 | }
|
| 4124 |
|
| 4125 | static void
|
| 4126 | ieee80211_txq_set_active(struct txq_info *txqi)
|
| 4127 | {
|
| 4128 | struct sta_info *sta;
|
| 4129 |
|
| 4130 | if (!txqi->txq.sta)
|
| 4131 | return;
|
| 4132 |
|
| 4133 | sta = container_of(txqi->txq.sta, struct sta_info, sta);
|
| 4134 | sta->airtime[txqi->txq.ac].last_active = jiffies;
|
| 4135 | }
|
| 4136 |
|
| 4137 | static bool
|
| 4138 | ieee80211_txq_keep_active(struct txq_info *txqi)
|
| 4139 | {
|
| 4140 | struct sta_info *sta;
|
| 4141 |
|
| 4142 | if (!txqi->txq.sta)
|
| 4143 | return false;
|
| 4144 |
|
| 4145 | sta = container_of(txqi->txq.sta, struct sta_info, sta);
|
| 4146 | if (ieee80211_sta_deficit(sta, txqi->txq.ac) >= 0)
|
| 4147 | return false;
|
| 4148 |
|
| 4149 | return ieee80211_sta_keep_active(sta, txqi->txq.ac);
|
| 4150 | }
|
| 4151 |
|
| 4152 | struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
|
| 4153 | {
|
| 4154 | struct ieee80211_local *local = hw_to_local(hw);
|
| 4155 | struct ieee80211_txq *ret = NULL;
|
| 4156 | struct txq_info *txqi = NULL, *head = NULL;
|
| 4157 | bool found_eligible_txq = false;
|
| 4158 | bool aql_check;
|
| 4159 |
|
| 4160 | spin_lock_bh(&local->active_txq_lock[ac]);
|
| 4161 |
|
| 4162 | if (!local->schedule_round[ac])
|
| 4163 | goto out;
|
| 4164 |
|
| 4165 | begin:
|
| 4166 | txqi = list_first_entry_or_null(&local->active_txqs[ac],
|
| 4167 | struct txq_info,
|
| 4168 | schedule_order);
|
| 4169 | if (!txqi)
|
| 4170 | goto out;
|
| 4171 |
|
| 4172 | if (txqi == head) {
|
| 4173 | if (!found_eligible_txq)
|
| 4174 | goto out;
|
| 4175 | else
|
| 4176 | found_eligible_txq = false;
|
| 4177 | }
|
| 4178 |
|
| 4179 | if (!head)
|
| 4180 | head = txqi;
|
| 4181 |
|
| 4182 | aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
|
| 4183 | if (aql_check)
|
| 4184 | found_eligible_txq = true;
|
| 4185 |
|
| 4186 | if (txqi->txq.sta) {
|
| 4187 | struct sta_info *sta = container_of(txqi->txq.sta,
|
| 4188 | struct sta_info, sta);
|
| 4189 |
|
| 4190 | if (ieee80211_sta_deficit(sta, txqi->txq.ac) < 0) {
|
| 4191 | sta->airtime[txqi->txq.ac].deficit +=
|
| 4192 | sta->airtime_weight;
|
| 4193 |
|
| 4194 | aql_check = false;
|
| 4195 | }
|
| 4196 | }
|
| 4197 |
|
| 4198 | if (!aql_check) {
|
| 4199 | list_move_tail(&txqi->schedule_order,
|
| 4200 | &local->active_txqs[txqi->txq.ac]);
|
| 4201 | goto begin;
|
| 4202 | }
|
| 4203 |
|
| 4204 | if (txqi->schedule_round == local->schedule_round[ac])
|
| 4205 | goto out;
|
| 4206 |
|
| 4207 | list_del_init(&txqi->schedule_order);
|
| 4208 | txqi->schedule_round = local->schedule_round[ac];
|
| 4209 | ret = &txqi->txq;
|
| 4210 |
|
| 4211 | out:
|
| 4212 | spin_unlock_bh(&local->active_txq_lock[ac]);
|
| 4213 | return ret;
|
| 4214 | }
|
| 4215 | EXPORT_SYMBOL(ieee80211_next_txq);
|
| 4216 |
|
| 4217 | void __ieee80211_schedule_txq(struct ieee80211_hw *hw,
|
| 4218 | struct ieee80211_txq *txq,
|
| 4219 | bool force)
|
| 4220 | {
|
| 4221 | struct ieee80211_local *local = hw_to_local(hw);
|
| 4222 | struct txq_info *txqi = to_txq_info(txq);
|
| 4223 | bool has_queue;
|
| 4224 |
|
| 4225 | spin_lock_bh(&local->active_txq_lock[txq->ac]);
|
| 4226 |
|
| 4227 | has_queue = force ||
|
| 4228 | (!test_bit(IEEE80211_TXQ_STOP, &txqi->flags) &&
|
| 4229 | txq_has_queue(txq));
|
| 4230 | if (list_empty(&txqi->schedule_order) &&
|
| 4231 | (has_queue || ieee80211_txq_keep_active(txqi))) {
|
| 4232 | |
| 4233 | * head of the list to ensure that they only get moved to the
|
| 4234 | * back by the airtime DRR scheduler once they have a negative
|
| 4235 | * deficit. A station that already has a negative deficit will
|
| 4236 | * get immediately moved to the back of the list on the next
|
| 4237 | * call to ieee80211_next_txq().
|
| 4238 |
|
| 4239 | if (txqi->txq.sta && local->airtime_flags && has_queue &&
|
| 4240 | wiphy_ext_feature_isset(local->hw.wiphy,
|
| 4241 | NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
|
| 4242 | list_add(&txqi->schedule_order,
|
| 4243 | &local->active_txqs[txq->ac]);
|
| 4244 | else
|
| 4245 | list_add_tail(&txqi->schedule_order,
|
| 4246 | &local->active_txqs[txq->ac]);
|
| 4247 | if (has_queue)
|
| 4248 | ieee80211_txq_set_active(txqi);
|
| 4249 | }
|
| 4250 |
|
| 4251 | spin_unlock_bh(&local->active_txq_lock[txq->ac]);
|
| 4252 | }
|
| 4253 | EXPORT_SYMBOL(__ieee80211_schedule_txq);
|
| 4254 |
|
| 4255 | DEFINE_STATIC_KEY_FALSE(aql_disable);
|
| 4256 |
|
| 4257 | bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
|
| 4258 | struct ieee80211_txq *txq)
|
| 4259 | {
|
| 4260 | struct sta_info *sta;
|
| 4261 | struct ieee80211_local *local = hw_to_local(hw);
|
| 4262 |
|
| 4263 | if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
|
| 4264 | return true;
|
| 4265 |
|
| 4266 | if (static_branch_unlikely(&aql_disable))
|
| 4267 | return true;
|
| 4268 |
|
| 4269 | if (!txq->sta)
|
| 4270 | return atomic_read(&local->aql_mc_pending_airtime) <
|
| 4271 | local->aql_txq_limit_mc;
|
| 4272 |
|
| 4273 | if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
|
| 4274 | return true;
|
| 4275 |
|
| 4276 | sta = container_of(txq->sta, struct sta_info, sta);
|
| 4277 | if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) <
|
| 4278 | sta->airtime[txq->ac].aql_limit_low)
|
| 4279 | return true;
|
| 4280 |
|
| 4281 | if (atomic_read(&local->aql_total_pending_airtime) <
|
| 4282 | local->aql_threshold &&
|
| 4283 | atomic_read(&sta->airtime[txq->ac].aql_tx_pending) <
|
| 4284 | sta->airtime[txq->ac].aql_limit_high)
|
| 4285 | return true;
|
| 4286 |
|
| 4287 | return false;
|
| 4288 | }
|
| 4289 | EXPORT_SYMBOL(ieee80211_txq_airtime_check);
|
| 4290 |
|
| 4291 | u32 ieee80211_txq_aql_pending(struct ieee80211_hw *hw,
|
| 4292 | struct ieee80211_txq *txq)
|
| 4293 | {
|
| 4294 | struct ieee80211_local *local = hw_to_local(hw);
|
| 4295 | struct sta_info *sta;
|
| 4296 |
|
| 4297 | if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
|
| 4298 | return 0;
|
| 4299 |
|
| 4300 | if (!txq->sta)
|
| 4301 | return atomic_read(&local->aql_mc_pending_airtime);
|
| 4302 |
|
| 4303 | sta = container_of(txq->sta, struct sta_info, sta);
|
| 4304 |
|
| 4305 | return atomic_read(&sta->airtime[txq->ac].aql_tx_pending);
|
| 4306 | }
|
| 4307 | EXPORT_SYMBOL(ieee80211_txq_aql_pending);
|
| 4308 |
|
| 4309 | static bool
|
| 4310 | ieee80211_txq_schedule_airtime_check(struct ieee80211_local *local, u8 ac)
|
| 4311 | {
|
| 4312 | unsigned int num_txq = 0;
|
| 4313 | struct txq_info *txq;
|
| 4314 | u32 aql_limit;
|
| 4315 |
|
| 4316 | if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
|
| 4317 | return true;
|
| 4318 |
|
| 4319 | list_for_each_entry(txq, &local->active_txqs[ac], schedule_order)
|
| 4320 | num_txq++;
|
| 4321 |
|
| 4322 | aql_limit = (num_txq - 1) * local->aql_txq_limit_low[ac] / 2 +
|
| 4323 | local->aql_txq_limit_high[ac];
|
| 4324 |
|
| 4325 | return atomic_read(&local->aql_ac_pending_airtime[ac]) < aql_limit;
|
| 4326 | }
|
| 4327 |
|
| 4328 | bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
|
| 4329 | struct ieee80211_txq *txq)
|
| 4330 | {
|
| 4331 | struct ieee80211_local *local = hw_to_local(hw);
|
| 4332 | struct txq_info *iter, *tmp, *txqi = to_txq_info(txq);
|
| 4333 | struct sta_info *sta;
|
| 4334 | u8 ac = txq->ac;
|
| 4335 |
|
| 4336 | spin_lock_bh(&local->active_txq_lock[ac]);
|
| 4337 |
|
| 4338 | if (list_empty(&txqi->schedule_order))
|
| 4339 | goto out;
|
| 4340 |
|
| 4341 | if (!ieee80211_txq_schedule_airtime_check(local, ac))
|
| 4342 | goto out;
|
| 4343 |
|
| 4344 | if (!txqi->txq.sta)
|
| 4345 | goto out;
|
| 4346 |
|
| 4347 | list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
|
| 4348 | schedule_order) {
|
| 4349 | if (iter == txqi)
|
| 4350 | break;
|
| 4351 |
|
| 4352 | if (!iter->txq.sta) {
|
| 4353 | list_move_tail(&iter->schedule_order,
|
| 4354 | &local->active_txqs[ac]);
|
| 4355 | continue;
|
| 4356 | }
|
| 4357 | sta = container_of(iter->txq.sta, struct sta_info, sta);
|
| 4358 | if (ieee80211_sta_deficit(sta, ac) < 0)
|
| 4359 | sta->airtime[ac].deficit += sta->airtime_weight;
|
| 4360 | list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
|
| 4361 | }
|
| 4362 |
|
| 4363 | sta = container_of(txqi->txq.sta, struct sta_info, sta);
|
| 4364 | if (sta->airtime[ac].deficit >= 0)
|
| 4365 | goto out;
|
| 4366 |
|
| 4367 | sta->airtime[ac].deficit += sta->airtime_weight;
|
| 4368 | list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]);
|
| 4369 | spin_unlock_bh(&local->active_txq_lock[ac]);
|
| 4370 |
|
| 4371 | return false;
|
| 4372 | out:
|
| 4373 | if (!list_empty(&txqi->schedule_order))
|
| 4374 | list_del_init(&txqi->schedule_order);
|
| 4375 | spin_unlock_bh(&local->active_txq_lock[ac]);
|
| 4376 |
|
| 4377 | return true;
|
| 4378 | }
|
| 4379 | EXPORT_SYMBOL(ieee80211_txq_may_transmit);
|
| 4380 |
|
| 4381 | void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
|
| 4382 | {
|
| 4383 | struct ieee80211_local *local = hw_to_local(hw);
|
| 4384 |
|
| 4385 | spin_lock_bh(&local->active_txq_lock[ac]);
|
| 4386 |
|
| 4387 | if (ieee80211_txq_schedule_airtime_check(local, ac)) {
|
| 4388 | local->schedule_round[ac]++;
|
| 4389 | if (!local->schedule_round[ac])
|
| 4390 | local->schedule_round[ac]++;
|
| 4391 | } else {
|
| 4392 | local->schedule_round[ac] = 0;
|
| 4393 | }
|
| 4394 |
|
| 4395 | spin_unlock_bh(&local->active_txq_lock[ac]);
|
| 4396 | }
|
| 4397 | EXPORT_SYMBOL(ieee80211_txq_schedule_start);
|
| 4398 |
|
| 4399 | void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
| 4400 | struct net_device *dev,
|
| 4401 | u32 info_flags,
|
| 4402 | u32 ctrl_flags,
|
| 4403 | u64 cookie)
|
| 4404 | {
|
| 4405 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
| 4406 | struct ieee80211_local *local = sdata->local;
|
| 4407 | struct sta_info *sta;
|
| 4408 | struct sk_buff *next;
|
| 4409 | int len = skb->len;
|
| 4410 |
|
| 4411 | if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) {
|
| 4412 | kfree_skb(skb);
|
| 4413 | return;
|
| 4414 | }
|
| 4415 |
|
| 4416 | sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
|
| 4417 |
|
| 4418 | rcu_read_lock();
|
| 4419 |
|
| 4420 | if (ieee80211_vif_is_mesh(&sdata->vif) &&
|
| 4421 | ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT) &&
|
| 4422 | ieee80211_mesh_xmit_fast(sdata, skb, ctrl_flags))
|
| 4423 | goto out;
|
| 4424 |
|
| 4425 | if (ieee80211_lookup_ra_sta(sdata, skb, &sta,
|
| 4426 | skb->protocol == sdata->control_port_protocol))
|
| 4427 | goto out_free;
|
| 4428 |
|
| 4429 | if (IS_ERR(sta))
|
| 4430 | sta = NULL;
|
| 4431 |
|
| 4432 | skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
|
| 4433 | ieee80211_aggr_check(sdata, sta, skb);
|
| 4434 |
|
| 4435 | if (sta) {
|
| 4436 | struct ieee80211_fast_tx *fast_tx;
|
| 4437 |
|
| 4438 | fast_tx = rcu_dereference(sta->fast_tx);
|
| 4439 |
|
| 4440 | if (fast_tx &&
|
| 4441 | ieee80211_xmit_fast(sdata, sta, fast_tx, skb))
|
| 4442 | goto out;
|
| 4443 | }
|
| 4444 |
|
| 4445 | |
| 4446 | * things so we cannot really handle checksum or GSO offload.
|
| 4447 | * fix it up in software before we handle anything else.
|
| 4448 |
|
| 4449 | skb = ieee80211_tx_skb_fixup(skb, 0);
|
| 4450 | if (!skb) {
|
| 4451 | len = 0;
|
| 4452 | goto out;
|
| 4453 | }
|
| 4454 |
|
| 4455 | skb_list_walk_safe(skb, skb, next) {
|
| 4456 | skb_mark_not_on_list(skb);
|
| 4457 |
|
| 4458 | if (skb->protocol == sdata->control_port_protocol)
|
| 4459 | ctrl_flags |= IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP;
|
| 4460 |
|
| 4461 | skb = ieee80211_build_hdr(sdata, skb, info_flags,
|
| 4462 | sta, ctrl_flags, cookie);
|
| 4463 | if (IS_ERR(skb)) {
|
| 4464 | kfree_skb_list(next);
|
| 4465 | goto out;
|
| 4466 | }
|
| 4467 |
|
| 4468 | dev_sw_netstats_tx_add(dev, 1, skb->len);
|
| 4469 |
|
| 4470 | ieee80211_xmit(sdata, sta, skb);
|
| 4471 | }
|
| 4472 | goto out;
|
| 4473 | out_free:
|
| 4474 | kfree_skb(skb);
|
| 4475 | len = 0;
|
| 4476 | out:
|
| 4477 | if (len)
|
| 4478 | ieee80211_tpt_led_trig_tx(local, len);
|
| 4479 | rcu_read_unlock();
|
| 4480 | }
|
| 4481 |
|
| 4482 | static int ieee80211_change_da(struct sk_buff *skb, struct sta_info *sta)
|
| 4483 | {
|
| 4484 | struct ethhdr *eth;
|
| 4485 | int err;
|
| 4486 |
|
| 4487 | err = skb_ensure_writable(skb, ETH_HLEN);
|
| 4488 | if (unlikely(err))
|
| 4489 | return err;
|
| 4490 |
|
| 4491 | eth = (void *)skb->data;
|
| 4492 | ether_addr_copy(eth->h_dest, sta->sta.addr);
|
| 4493 |
|
| 4494 | return 0;
|
| 4495 | }
|
| 4496 |
|
| 4497 | static bool ieee80211_multicast_to_unicast(struct sk_buff *skb,
|
| 4498 | struct net_device *dev)
|
| 4499 | {
|
| 4500 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
| 4501 | const struct ethhdr *eth = (void *)skb->data;
|
| 4502 | const struct vlan_ethhdr *ethvlan = (void *)skb->data;
|
| 4503 | __be16 ethertype;
|
| 4504 |
|
| 4505 | switch (sdata->vif.type) {
|
| 4506 | case NL80211_IFTYPE_AP_VLAN:
|
| 4507 | if (sdata->u.vlan.sta)
|
| 4508 | return false;
|
| 4509 | if (sdata->wdev.use_4addr)
|
| 4510 | return false;
|
| 4511 | fallthrough;
|
| 4512 | case NL80211_IFTYPE_AP:
|
| 4513 |
|
| 4514 | if (!sdata->bss->multicast_to_unicast)
|
| 4515 | return false;
|
| 4516 | break;
|
| 4517 | default:
|
| 4518 | return false;
|
| 4519 | }
|
| 4520 |
|
| 4521 |
|
| 4522 | ethertype = eth->h_proto;
|
| 4523 | if (ethertype == htons(ETH_P_8021Q) && skb->len >= VLAN_ETH_HLEN)
|
| 4524 | ethertype = ethvlan->h_vlan_encapsulated_proto;
|
| 4525 | switch (ethertype) {
|
| 4526 | case htons(ETH_P_ARP):
|
| 4527 | case htons(ETH_P_IP):
|
| 4528 | case htons(ETH_P_IPV6):
|
| 4529 | break;
|
| 4530 | default:
|
| 4531 | return false;
|
| 4532 | }
|
| 4533 |
|
| 4534 | return true;
|
| 4535 | }
|
| 4536 |
|
| 4537 | static void
|
| 4538 | ieee80211_convert_to_unicast(struct sk_buff *skb, struct net_device *dev,
|
| 4539 | struct sk_buff_head *queue)
|
| 4540 | {
|
| 4541 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
| 4542 | struct ieee80211_local *local = sdata->local;
|
| 4543 | const struct ethhdr *eth = (struct ethhdr *)skb->data;
|
| 4544 | struct sta_info *sta, *first = NULL;
|
| 4545 | struct sk_buff *cloned_skb;
|
| 4546 |
|
| 4547 | rcu_read_lock();
|
| 4548 |
|
| 4549 | list_for_each_entry_rcu(sta, &local->sta_list, list) {
|
| 4550 | if (sdata != sta->sdata)
|
| 4551 |
|
| 4552 | continue;
|
| 4553 | if (unlikely(ether_addr_equal(eth->h_source, sta->sta.addr)))
|
| 4554 |
|
| 4555 | continue;
|
| 4556 | if (!first) {
|
| 4557 | first = sta;
|
| 4558 | continue;
|
| 4559 | }
|
| 4560 | cloned_skb = skb_clone(skb, GFP_ATOMIC);
|
| 4561 | if (!cloned_skb)
|
| 4562 | goto multicast;
|
| 4563 | if (unlikely(ieee80211_change_da(cloned_skb, sta))) {
|
| 4564 | dev_kfree_skb(cloned_skb);
|
| 4565 | goto multicast;
|
| 4566 | }
|
| 4567 | __skb_queue_tail(queue, cloned_skb);
|
| 4568 | }
|
| 4569 |
|
| 4570 | if (likely(first)) {
|
| 4571 | if (unlikely(ieee80211_change_da(skb, first)))
|
| 4572 | goto multicast;
|
| 4573 | __skb_queue_tail(queue, skb);
|
| 4574 | } else {
|
| 4575 |
|
| 4576 | kfree_skb(skb);
|
| 4577 | skb = NULL;
|
| 4578 | }
|
| 4579 |
|
| 4580 | goto out;
|
| 4581 | multicast:
|
| 4582 | __skb_queue_purge(queue);
|
| 4583 | __skb_queue_tail(queue, skb);
|
| 4584 | out:
|
| 4585 | rcu_read_unlock();
|
| 4586 | }
|
| 4587 |
|
| 4588 | static void ieee80211_mlo_multicast_tx_one(struct ieee80211_sub_if_data *sdata,
|
| 4589 | struct sk_buff *skb, u32 ctrl_flags,
|
| 4590 | unsigned int link_id)
|
| 4591 | {
|
| 4592 | struct sk_buff *out;
|
| 4593 |
|
| 4594 | out = skb_copy(skb, GFP_ATOMIC);
|
| 4595 | if (!out)
|
| 4596 | return;
|
| 4597 |
|
| 4598 | ctrl_flags |= u32_encode_bits(link_id, IEEE80211_TX_CTRL_MLO_LINK);
|
| 4599 | __ieee80211_subif_start_xmit(out, sdata->dev, 0, ctrl_flags, 0);
|
| 4600 | }
|
| 4601 |
|
| 4602 | static void ieee80211_mlo_multicast_tx(struct net_device *dev,
|
| 4603 | struct sk_buff *skb)
|
| 4604 | {
|
| 4605 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
| 4606 | unsigned long links = sdata->vif.active_links;
|
| 4607 | unsigned int link;
|
| 4608 | u32 ctrl_flags = IEEE80211_TX_CTRL_MCAST_MLO_FIRST_TX;
|
| 4609 |
|
| 4610 | if (hweight16(links) == 1) {
|
| 4611 | ctrl_flags |= u32_encode_bits(__ffs(links),
|
| 4612 | IEEE80211_TX_CTRL_MLO_LINK);
|
| 4613 |
|
| 4614 | __ieee80211_subif_start_xmit(skb, sdata->dev, 0, ctrl_flags, 0);
|
| 4615 | return;
|
| 4616 | }
|
| 4617 |
|
| 4618 | for_each_set_bit(link, &links, IEEE80211_MLD_MAX_NUM_LINKS) {
|
| 4619 | ieee80211_mlo_multicast_tx_one(sdata, skb, ctrl_flags, link);
|
| 4620 | ctrl_flags = 0;
|
| 4621 | }
|
| 4622 | kfree_skb(skb);
|
| 4623 | }
|
| 4624 |
|
| 4625 | |
| 4626 | * ieee80211_subif_start_xmit - netif start_xmit function for 802.3 vifs
|
| 4627 | * @skb: packet to be sent
|
| 4628 | * @dev: incoming interface
|
| 4629 | *
|
| 4630 | * On failure skb will be freed.
|
| 4631 | *
|
| 4632 | * Returns: the netdev TX status (but really only %NETDEV_TX_OK)
|
| 4633 |
|
| 4634 | netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
| 4635 | struct net_device *dev)
|
| 4636 | {
|
| 4637 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
| 4638 | const struct ethhdr *eth = (void *)skb->data;
|
| 4639 |
|
| 4640 | if (likely(!is_multicast_ether_addr(eth->h_dest)))
|
| 4641 | goto normal;
|
| 4642 |
|
| 4643 | if (unlikely(!ieee80211_sdata_running(sdata))) {
|
| 4644 | kfree_skb(skb);
|
| 4645 | return NETDEV_TX_OK;
|
| 4646 | }
|
| 4647 |
|
| 4648 | if (unlikely(ieee80211_multicast_to_unicast(skb, dev))) {
|
| 4649 | struct sk_buff_head queue;
|
| 4650 |
|
| 4651 | __skb_queue_head_init(&queue);
|
| 4652 | ieee80211_convert_to_unicast(skb, dev, &queue);
|
| 4653 | while ((skb = __skb_dequeue(&queue)))
|
| 4654 | __ieee80211_subif_start_xmit(skb, dev, 0,
|
| 4655 | IEEE80211_TX_CTRL_MLO_LINK_UNSPEC,
|
| 4656 | 0);
|
| 4657 | } else if (ieee80211_vif_is_mld(&sdata->vif) &&
|
| 4658 | ((sdata->vif.type == NL80211_IFTYPE_AP &&
|
| 4659 | !ieee80211_hw_check(&sdata->local->hw, MLO_MCAST_MULTI_LINK_TX)) ||
|
| 4660 | (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
|
| 4661 | !sdata->wdev.use_4addr))) {
|
| 4662 | ieee80211_mlo_multicast_tx(dev, skb);
|
| 4663 | } else {
|
| 4664 | normal:
|
| 4665 | __ieee80211_subif_start_xmit(skb, dev, 0,
|
| 4666 | IEEE80211_TX_CTRL_MLO_LINK_UNSPEC,
|
| 4667 | 0);
|
| 4668 | }
|
| 4669 |
|
| 4670 | return NETDEV_TX_OK;
|
| 4671 | }
|
| 4672 |
|
| 4673 |
|
| 4674 |
|
| 4675 | static bool __ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata,
|
| 4676 | struct sk_buff *skb, struct sta_info *sta,
|
| 4677 | bool txpending)
|
| 4678 | {
|
| 4679 | struct ieee80211_local *local = sdata->local;
|
| 4680 | struct ieee80211_tx_control control = {};
|
| 4681 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 4682 | struct ieee80211_sta *pubsta = NULL;
|
| 4683 | unsigned long flags;
|
| 4684 | int q = info->hw_queue;
|
| 4685 |
|
| 4686 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
| 4687 |
|
| 4688 | if (local->queue_stop_reasons[q] ||
|
| 4689 | (!txpending && !skb_queue_empty(&local->pending[q]))) {
|
| 4690 | if (txpending)
|
| 4691 | skb_queue_head(&local->pending[q], skb);
|
| 4692 | else
|
| 4693 | skb_queue_tail(&local->pending[q], skb);
|
| 4694 |
|
| 4695 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
| 4696 |
|
| 4697 | return false;
|
| 4698 | }
|
| 4699 |
|
| 4700 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
| 4701 |
|
| 4702 | if (sta && sta->uploaded)
|
| 4703 | pubsta = &sta->sta;
|
| 4704 |
|
| 4705 | control.sta = pubsta;
|
| 4706 |
|
| 4707 | drv_tx(local, &control, skb);
|
| 4708 |
|
| 4709 | return true;
|
| 4710 | }
|
| 4711 |
|
| 4712 | static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata,
|
| 4713 | struct sk_buff *skb, struct sta_info *sta,
|
| 4714 | bool txpending)
|
| 4715 | {
|
| 4716 | struct ieee80211_local *local = sdata->local;
|
| 4717 | struct sk_buff *next;
|
| 4718 | bool ret = true;
|
| 4719 |
|
| 4720 | if (ieee80211_queue_skb(local, sdata, sta, skb))
|
| 4721 | return true;
|
| 4722 |
|
| 4723 | skb_list_walk_safe(skb, skb, next) {
|
| 4724 | skb_mark_not_on_list(skb);
|
| 4725 | if (!__ieee80211_tx_8023(sdata, skb, sta, txpending))
|
| 4726 | ret = false;
|
| 4727 | }
|
| 4728 |
|
| 4729 | return ret;
|
| 4730 | }
|
| 4731 |
|
| 4732 | static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
|
| 4733 | struct net_device *dev, struct sta_info *sta,
|
| 4734 | struct ieee80211_key *key, struct sk_buff *skb)
|
| 4735 | {
|
| 4736 | struct ieee80211_tx_info *info;
|
| 4737 | struct ieee80211_local *local = sdata->local;
|
| 4738 | struct ieee80211_chanctx_conf *chanctx_conf;
|
| 4739 | struct tid_ampdu_tx *tid_tx = NULL;
|
| 4740 | struct sk_buff *seg, *next;
|
| 4741 | unsigned int skbs = 0, len = 0;
|
| 4742 | u16 queue;
|
| 4743 | u8 tid;
|
| 4744 |
|
| 4745 | queue = ieee80211_select_queue(sdata, sta, skb);
|
| 4746 | skb_set_queue_mapping(skb, queue);
|
| 4747 |
|
| 4748 | if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) &&
|
| 4749 | test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
|
| 4750 | goto out_free;
|
| 4751 |
|
| 4752 | skb = skb_share_check(skb, GFP_ATOMIC);
|
| 4753 | if (unlikely(!skb))
|
| 4754 | return;
|
| 4755 |
|
| 4756 | ieee80211_aggr_check(sdata, sta, skb);
|
| 4757 |
|
| 4758 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
|
| 4759 |
|
| 4760 | if (sta)
|
| 4761 | tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
|
| 4762 | if (tid_tx) {
|
| 4763 | if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
|
| 4764 |
|
| 4765 | __ieee80211_subif_start_xmit(skb, dev, 0,
|
| 4766 | IEEE80211_TX_CTRL_MLO_LINK_UNSPEC,
|
| 4767 | 0);
|
| 4768 | return;
|
| 4769 | }
|
| 4770 |
|
| 4771 | if (tid_tx->timeout)
|
| 4772 | tid_tx->last_tx = jiffies;
|
| 4773 | }
|
| 4774 |
|
| 4775 | skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata));
|
| 4776 | if (!skb)
|
| 4777 | return;
|
| 4778 |
|
| 4779 | info = IEEE80211_SKB_CB(skb);
|
| 4780 | memset(info, 0, sizeof(*info));
|
| 4781 |
|
| 4782 | info->hw_queue = sdata->vif.hw_queue[queue];
|
| 4783 |
|
| 4784 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
| 4785 | sdata = container_of(sdata->bss,
|
| 4786 | struct ieee80211_sub_if_data, u.ap);
|
| 4787 |
|
| 4788 |
|
| 4789 | if (!ieee80211_vif_is_mld(&sdata->vif)) {
|
| 4790 | chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
|
| 4791 | if (unlikely(!chanctx_conf)) {
|
| 4792 | kfree_skb_list(skb);
|
| 4793 | return;
|
| 4794 | }
|
| 4795 | info->band = chanctx_conf->def.chan->band;
|
| 4796 | }
|
| 4797 |
|
| 4798 | info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP;
|
| 4799 | info->control.vif = &sdata->vif;
|
| 4800 |
|
| 4801 | if (key)
|
| 4802 | info->control.hw_key = &key->conf;
|
| 4803 |
|
| 4804 | skb_list_walk_safe(skb, seg, next) {
|
| 4805 | skbs++;
|
| 4806 | len += seg->len;
|
| 4807 | if (seg != skb)
|
| 4808 | memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info));
|
| 4809 | }
|
| 4810 |
|
| 4811 | if (unlikely(sk_requests_wifi_status(skb->sk))) {
|
| 4812 | info->status_data = ieee80211_store_ack_skb(local, skb,
|
| 4813 | &info->flags, 0);
|
| 4814 | if (info->status_data)
|
| 4815 | info->status_data_idr = 1;
|
| 4816 | }
|
| 4817 |
|
| 4818 | dev_sw_netstats_tx_add(dev, skbs, len);
|
| 4819 |
|
| 4820 | if (sta) {
|
| 4821 | sta->deflink.tx_stats.packets[queue] += skbs;
|
| 4822 | sta->deflink.tx_stats.bytes[queue] += len;
|
| 4823 | }
|
| 4824 |
|
| 4825 | ieee80211_tpt_led_trig_tx(local, len);
|
| 4826 |
|
| 4827 | ieee80211_tx_8023(sdata, skb, sta, false);
|
| 4828 |
|
| 4829 | return;
|
| 4830 |
|
| 4831 | out_free:
|
| 4832 | kfree_skb(skb);
|
| 4833 | }
|
| 4834 |
|
| 4835 | static bool ieee80211_check_mcast_offload(struct ieee80211_sub_if_data *sdata,
|
| 4836 | struct sk_buff *skb)
|
| 4837 | {
|
| 4838 | struct ethhdr *ehdr = (struct ethhdr *)skb->data;
|
| 4839 |
|
| 4840 | if ((ieee80211_vif_is_mld(&sdata->vif) &&
|
| 4841 | (sdata->vif.type == NL80211_IFTYPE_AP &&
|
| 4842 | !ieee80211_hw_check(&sdata->local->hw, MLO_MCAST_MULTI_LINK_TX))) ||
|
| 4843 | (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
|
| 4844 | !sdata->wdev.use_4addr))
|
| 4845 | return false;
|
| 4846 |
|
| 4847 | if (!is_multicast_ether_addr(skb->data) ||
|
| 4848 | !(sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_MCAST) ||
|
| 4849 | sdata->control_port_protocol == ehdr->h_proto)
|
| 4850 | return false;
|
| 4851 |
|
| 4852 | return true;
|
| 4853 | }
|
| 4854 |
|
| 4855 | static void __ieee80211_subif_start_xmit_8023(struct sk_buff *skb,
|
| 4856 | struct net_device *dev)
|
| 4857 | {
|
| 4858 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
| 4859 | struct ethhdr *ehdr = (struct ethhdr *)skb->data;
|
| 4860 | struct ieee80211_link_data *link;
|
| 4861 | struct ieee80211_key *key;
|
| 4862 | struct sta_info *sta;
|
| 4863 |
|
| 4864 | rcu_read_lock();
|
| 4865 |
|
| 4866 | if (unlikely(sdata->control_port_protocol == ehdr->h_proto))
|
| 4867 | goto skip_offload;
|
| 4868 |
|
| 4869 | if (ieee80211_lookup_ra_sta(sdata, skb, &sta, false)) {
|
| 4870 | kfree_skb(skb);
|
| 4871 | goto out;
|
| 4872 | }
|
| 4873 |
|
| 4874 | |
| 4875 | * If STA is invalid, use the multicast offload path when applicable.
|
| 4876 | * In AP mode, drop the frame if there are no associated stations;
|
| 4877 | * otherwise use the default link and multicast key for transmission.
|
| 4878 |
|
| 4879 | if (unlikely(IS_ERR_OR_NULL(sta) &&
|
| 4880 | ieee80211_check_mcast_offload(sdata, skb))) {
|
| 4881 | sta = NULL;
|
| 4882 | if (ieee80211_vif_get_num_mcast_if(sdata) <= 0) {
|
| 4883 |
|
| 4884 | kfree_skb(skb);
|
| 4885 | goto out;
|
| 4886 | }
|
| 4887 | link = &sdata->deflink;
|
| 4888 | key = rcu_dereference(link->default_multicast_key);
|
| 4889 | } else if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded ||
|
| 4890 | !test_sta_flag(sta, WLAN_STA_AUTHORIZED))) {
|
| 4891 | goto skip_offload;
|
| 4892 | } else {
|
| 4893 | key = rcu_dereference(sta->ptk[sta->ptk_idx]);
|
| 4894 | if (!key)
|
| 4895 | key = rcu_dereference(sdata->default_unicast_key);
|
| 4896 | }
|
| 4897 |
|
| 4898 | if (key && (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) ||
|
| 4899 | key->conf.cipher == WLAN_CIPHER_SUITE_TKIP))
|
| 4900 | goto skip_offload;
|
| 4901 |
|
| 4902 | sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
|
| 4903 | ieee80211_8023_xmit(sdata, dev, sta, key, skb);
|
| 4904 | goto out;
|
| 4905 |
|
| 4906 | skip_offload:
|
| 4907 | ieee80211_subif_start_xmit(skb, dev);
|
| 4908 | out:
|
| 4909 | rcu_read_unlock();
|
| 4910 | }
|
| 4911 |
|
| 4912 | netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb,
|
| 4913 | struct net_device *dev)
|
| 4914 | {
|
| 4915 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
| 4916 | struct ethhdr *ehdr = (struct ethhdr *)skb->data;
|
| 4917 |
|
| 4918 | if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) {
|
| 4919 | kfree_skb(skb);
|
| 4920 | return NETDEV_TX_OK;
|
| 4921 | }
|
| 4922 |
|
| 4923 | if (unlikely(is_multicast_ether_addr(ehdr->h_dest) &&
|
| 4924 | ieee80211_multicast_to_unicast(skb, dev))) {
|
| 4925 | struct sk_buff_head queue;
|
| 4926 |
|
| 4927 | __skb_queue_head_init(&queue);
|
| 4928 | ieee80211_convert_to_unicast(skb, dev, &queue);
|
| 4929 | while ((skb = __skb_dequeue(&queue)))
|
| 4930 | __ieee80211_subif_start_xmit_8023(skb, dev);
|
| 4931 | } else {
|
| 4932 | __ieee80211_subif_start_xmit_8023(skb, dev);
|
| 4933 | }
|
| 4934 |
|
| 4935 | return NETDEV_TX_OK;
|
| 4936 | }
|
| 4937 |
|
| 4938 | struct sk_buff *
|
| 4939 | ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
|
| 4940 | struct sk_buff *skb, u32 info_flags)
|
| 4941 | {
|
| 4942 | struct ieee80211_hdr *hdr;
|
| 4943 | struct ieee80211_tx_data tx = {
|
| 4944 | .local = sdata->local,
|
| 4945 | .sdata = sdata,
|
| 4946 | };
|
| 4947 | struct sta_info *sta;
|
| 4948 |
|
| 4949 | rcu_read_lock();
|
| 4950 |
|
| 4951 | if (ieee80211_lookup_ra_sta(sdata, skb, &sta, false)) {
|
| 4952 | kfree_skb(skb);
|
| 4953 | skb = ERR_PTR(-EINVAL);
|
| 4954 | goto out;
|
| 4955 | }
|
| 4956 |
|
| 4957 | skb = ieee80211_build_hdr(sdata, skb, info_flags, sta,
|
| 4958 | IEEE80211_TX_CTRL_MLO_LINK_UNSPEC, 0);
|
| 4959 | if (IS_ERR(skb))
|
| 4960 | goto out;
|
| 4961 |
|
| 4962 | hdr = (void *)skb->data;
|
| 4963 | tx.sta = sta_info_get(sdata, hdr->addr1);
|
| 4964 | tx.skb = skb;
|
| 4965 |
|
| 4966 | if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) {
|
| 4967 | rcu_read_unlock();
|
| 4968 | kfree_skb(skb);
|
| 4969 | return ERR_PTR(-EINVAL);
|
| 4970 | }
|
| 4971 |
|
| 4972 | out:
|
| 4973 | rcu_read_unlock();
|
| 4974 | return skb;
|
| 4975 | }
|
| 4976 |
|
| 4977 | |
| 4978 | * ieee80211_clear_tx_pending may not be called in a context where
|
| 4979 | * it is possible that it packets could come in again.
|
| 4980 |
|
| 4981 | void ieee80211_clear_tx_pending(struct ieee80211_local *local)
|
| 4982 | {
|
| 4983 | struct sk_buff *skb;
|
| 4984 | int i;
|
| 4985 |
|
| 4986 | for (i = 0; i < local->hw.queues; i++) {
|
| 4987 | while ((skb = skb_dequeue(&local->pending[i])) != NULL)
|
| 4988 | ieee80211_free_txskb(&local->hw, skb);
|
| 4989 | }
|
| 4990 | }
|
| 4991 |
|
| 4992 | |
| 4993 | * Returns false if the frame couldn't be transmitted but was queued instead,
|
| 4994 | * which in this case means re-queued -- take as an indication to stop sending
|
| 4995 | * more pending frames.
|
| 4996 |
|
| 4997 | static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
|
| 4998 | struct sk_buff *skb)
|
| 4999 | {
|
| 5000 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 5001 | struct ieee80211_sub_if_data *sdata;
|
| 5002 | struct sta_info *sta;
|
| 5003 | struct ieee80211_hdr *hdr;
|
| 5004 | bool result;
|
| 5005 | struct ieee80211_chanctx_conf *chanctx_conf;
|
| 5006 |
|
| 5007 | sdata = vif_to_sdata(info->control.vif);
|
| 5008 |
|
| 5009 | if (info->control.flags & IEEE80211_TX_INTCFL_NEED_TXPROCESSING) {
|
| 5010 |
|
| 5011 | if (!ieee80211_vif_is_mld(&sdata->vif)) {
|
| 5012 | chanctx_conf =
|
| 5013 | rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
|
| 5014 | if (unlikely(!chanctx_conf)) {
|
| 5015 | dev_kfree_skb(skb);
|
| 5016 | return true;
|
| 5017 | }
|
| 5018 | info->band = chanctx_conf->def.chan->band;
|
| 5019 | }
|
| 5020 | result = ieee80211_tx(sdata, NULL, skb, true);
|
| 5021 | } else if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
|
| 5022 | if (ieee80211_lookup_ra_sta(sdata, skb, &sta, true)) {
|
| 5023 | dev_kfree_skb(skb);
|
| 5024 | return true;
|
| 5025 | }
|
| 5026 |
|
| 5027 | if (IS_ERR(sta) || (sta && !sta->uploaded))
|
| 5028 | sta = NULL;
|
| 5029 |
|
| 5030 | result = ieee80211_tx_8023(sdata, skb, sta, true);
|
| 5031 | } else {
|
| 5032 | struct sk_buff_head skbs;
|
| 5033 |
|
| 5034 | __skb_queue_head_init(&skbs);
|
| 5035 | __skb_queue_tail(&skbs, skb);
|
| 5036 |
|
| 5037 | hdr = (struct ieee80211_hdr *)skb->data;
|
| 5038 | sta = sta_info_get(sdata, hdr->addr1);
|
| 5039 |
|
| 5040 | result = __ieee80211_tx(local, &skbs, sta, true);
|
| 5041 | }
|
| 5042 |
|
| 5043 | return result;
|
| 5044 | }
|
| 5045 |
|
| 5046 | |
| 5047 | * Transmit all pending packets. Called from tasklet.
|
| 5048 |
|
| 5049 | void ieee80211_tx_pending(struct tasklet_struct *t)
|
| 5050 | {
|
| 5051 | struct ieee80211_local *local = from_tasklet(local, t,
|
| 5052 | tx_pending_tasklet);
|
| 5053 | unsigned long flags;
|
| 5054 | int i;
|
| 5055 | bool txok;
|
| 5056 |
|
| 5057 | rcu_read_lock();
|
| 5058 |
|
| 5059 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
| 5060 | for (i = 0; i < local->hw.queues; i++) {
|
| 5061 | |
| 5062 | * If queue is stopped by something other than due to pending
|
| 5063 | * frames, or we have no pending frames, proceed to next queue.
|
| 5064 |
|
| 5065 | if (local->queue_stop_reasons[i] ||
|
| 5066 | skb_queue_empty(&local->pending[i]))
|
| 5067 | continue;
|
| 5068 |
|
| 5069 | while (!skb_queue_empty(&local->pending[i])) {
|
| 5070 | struct sk_buff *skb = __skb_dequeue(&local->pending[i]);
|
| 5071 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 5072 |
|
| 5073 | if (WARN_ON(!info->control.vif)) {
|
| 5074 | ieee80211_free_txskb(&local->hw, skb);
|
| 5075 | continue;
|
| 5076 | }
|
| 5077 |
|
| 5078 | spin_unlock_irqrestore(&local->queue_stop_reason_lock,
|
| 5079 | flags);
|
| 5080 |
|
| 5081 | txok = ieee80211_tx_pending_skb(local, skb);
|
| 5082 | spin_lock_irqsave(&local->queue_stop_reason_lock,
|
| 5083 | flags);
|
| 5084 | if (!txok)
|
| 5085 | break;
|
| 5086 | }
|
| 5087 | }
|
| 5088 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
| 5089 |
|
| 5090 | rcu_read_unlock();
|
| 5091 | }
|
| 5092 |
|
| 5093 |
|
| 5094 |
|
| 5095 | static void ieee80211_beacon_add_tim_pvb(struct ps_data *ps,
|
| 5096 | struct sk_buff *skb,
|
| 5097 | bool mcast_traffic)
|
| 5098 | {
|
| 5099 | int i, n1 = 0, n2;
|
| 5100 |
|
| 5101 | |
| 5102 | * Find largest even number N1 so that bits numbered 1 through
|
| 5103 | * (N1 x 8) - 1 in the bitmap are 0 and number N2 so that bits
|
| 5104 | * (N2 + 1) x 8 through 2007 are 0.
|
| 5105 |
|
| 5106 | for (i = 0; i < IEEE80211_MAX_TIM_LEN; i++) {
|
| 5107 | if (ps->tim[i]) {
|
| 5108 | n1 = i & 0xfe;
|
| 5109 | break;
|
| 5110 | }
|
| 5111 | }
|
| 5112 | n2 = n1;
|
| 5113 | for (i = IEEE80211_MAX_TIM_LEN - 1; i >= n1; i--) {
|
| 5114 | if (ps->tim[i]) {
|
| 5115 | n2 = i;
|
| 5116 | break;
|
| 5117 | }
|
| 5118 | }
|
| 5119 |
|
| 5120 |
|
| 5121 | skb_put_u8(skb, n1 | mcast_traffic);
|
| 5122 |
|
| 5123 | skb_put_data(skb, ps->tim + n1, n2 - n1 + 1);
|
| 5124 | }
|
| 5125 |
|
| 5126 | |
| 5127 | * mac80211 currently supports encoding using block bitmap mode, non
|
| 5128 | * inversed. The current implementation supports up to 1600 AIDs.
|
| 5129 | *
|
| 5130 | * Block bitmap encoding breaks down the AID bitmap into blocks of 64
|
| 5131 | * AIDs. Each block contains between 0 and 8 subblocks. Each subblock
|
| 5132 | * describes 8 AIDs and the presence of a subblock is determined by
|
| 5133 | * the block bitmap.
|
| 5134 |
|
| 5135 | static void ieee80211_s1g_beacon_add_tim_pvb(struct ps_data *ps,
|
| 5136 | struct sk_buff *skb,
|
| 5137 | bool mcast_traffic,
|
| 5138 | bool ucast_traffic)
|
| 5139 | {
|
| 5140 | int blk;
|
| 5141 |
|
| 5142 | |
| 5143 | * if no unicast and multicast traffic don't emit a bitmap control
|
| 5144 | * or pvb
|
| 5145 |
|
| 5146 | if (!mcast_traffic && !ucast_traffic)
|
| 5147 | return;
|
| 5148 |
|
| 5149 | |
| 5150 | * Emit a bitmap control block with a page slice number of 31 and a
|
| 5151 | * page index of 0 which indicates as per IEEE80211-2024 9.4.2.5.1
|
| 5152 | * that the entire page (2048 bits) indicated by the page index
|
| 5153 | * is encoded in the partial virtual bitmap.
|
| 5154 |
|
| 5155 | skb_put_u8(skb, mcast_traffic | (31 << 1));
|
| 5156 |
|
| 5157 |
|
| 5158 | if (!ucast_traffic)
|
| 5159 | return;
|
| 5160 |
|
| 5161 |
|
| 5162 | for (blk = 0; blk < IEEE80211_MAX_SUPPORTED_S1G_TIM_BLOCKS; blk++) {
|
| 5163 | u8 blk_bmap = 0;
|
| 5164 | int sblk;
|
| 5165 |
|
| 5166 | for (sblk = 0; sblk < 8; sblk++) {
|
| 5167 | int sblk_idx = blk * 8 + sblk;
|
| 5168 |
|
| 5169 | |
| 5170 | * If the current subblock is non-zero, increase the
|
| 5171 | * number of subblocks to emit for the current block.
|
| 5172 |
|
| 5173 | if (ps->tim[sblk_idx])
|
| 5174 | blk_bmap |= BIT(sblk);
|
| 5175 | }
|
| 5176 |
|
| 5177 |
|
| 5178 | if (!blk_bmap)
|
| 5179 | continue;
|
| 5180 |
|
| 5181 | |
| 5182 | * Emit a block control byte for the current encoded block
|
| 5183 | * with an encoding mode of block bitmap (0x0), not inverse
|
| 5184 | * (0x0) and the current block offset (5 bits)
|
| 5185 |
|
| 5186 | skb_put_u8(skb, blk << 3);
|
| 5187 |
|
| 5188 | |
| 5189 | * Emit the block bitmap for the current encoded block which
|
| 5190 | * contains the present subblocks.
|
| 5191 |
|
| 5192 | skb_put_u8(skb, blk_bmap);
|
| 5193 |
|
| 5194 |
|
| 5195 | for (sblk = 0; sblk < 8; sblk++) {
|
| 5196 | int sblk_idx = blk * 8 + sblk;
|
| 5197 |
|
| 5198 | if (!(blk_bmap & BIT(sblk)))
|
| 5199 | continue;
|
| 5200 |
|
| 5201 | skb_put_u8(skb, ps->tim[sblk_idx]);
|
| 5202 | }
|
| 5203 | }
|
| 5204 | }
|
| 5205 |
|
| 5206 | static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
|
| 5207 | struct ieee80211_link_data *link,
|
| 5208 | struct ps_data *ps, struct sk_buff *skb,
|
| 5209 | bool is_template)
|
| 5210 | {
|
| 5211 | struct element *tim;
|
| 5212 | bool mcast_traffic = false, have_bits = false;
|
| 5213 | struct ieee80211_bss_conf *link_conf = link->conf;
|
| 5214 | bool s1g = ieee80211_get_link_sband(link)->band == NL80211_BAND_S1GHZ;
|
| 5215 |
|
| 5216 | |
| 5217 | * mode.
|
| 5218 | if (atomic_read(&ps->num_sta_ps) > 0)
|
| 5219 | |
| 5220 | * checking byte-for-byte
|
| 5221 | have_bits = !bitmap_empty((unsigned long *)ps->tim,
|
| 5222 | IEEE80211_MAX_AID + 1);
|
| 5223 |
|
| 5224 | if (!is_template) {
|
| 5225 | if (ps->dtim_count == 0)
|
| 5226 | ps->dtim_count = link_conf->dtim_period - 1;
|
| 5227 | else
|
| 5228 | ps->dtim_count--;
|
| 5229 | }
|
| 5230 |
|
| 5231 |
|
| 5232 | tim = skb_put(skb, sizeof(struct element));
|
| 5233 | tim->id = WLAN_EID_TIM;
|
| 5234 | skb_put_u8(skb, ps->dtim_count);
|
| 5235 | skb_put_u8(skb, link_conf->dtim_period);
|
| 5236 |
|
| 5237 | if (ps->dtim_count == 0 && !skb_queue_empty(&ps->bc_buf))
|
| 5238 | mcast_traffic = true;
|
| 5239 |
|
| 5240 | ps->dtim_bc_mc = mcast_traffic;
|
| 5241 |
|
| 5242 | if (s1g) {
|
| 5243 | ieee80211_s1g_beacon_add_tim_pvb(ps, skb, mcast_traffic,
|
| 5244 | have_bits);
|
| 5245 | } else if (have_bits) {
|
| 5246 | ieee80211_beacon_add_tim_pvb(ps, skb, mcast_traffic);
|
| 5247 | } else {
|
| 5248 |
|
| 5249 | skb_put_u8(skb, mcast_traffic);
|
| 5250 |
|
| 5251 | skb_put_u8(skb, 0);
|
| 5252 | }
|
| 5253 |
|
| 5254 | tim->datalen = skb_tail_pointer(skb) - tim->data;
|
| 5255 | }
|
| 5256 |
|
| 5257 | static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
|
| 5258 | struct ieee80211_link_data *link,
|
| 5259 | struct ps_data *ps, struct sk_buff *skb,
|
| 5260 | bool is_template)
|
| 5261 | {
|
| 5262 | struct ieee80211_local *local = sdata->local;
|
| 5263 |
|
| 5264 | |
| 5265 | * Not very nice, but we want to allow the driver to call
|
| 5266 | * ieee80211_beacon_get() as a response to the set_tim()
|
| 5267 | * callback. That, however, is already invoked under the
|
| 5268 | * sta_lock to guarantee consistent and race-free update
|
| 5269 | * of the tim bitmap in mac80211 and the driver.
|
| 5270 |
|
| 5271 | if (local->tim_in_locked_section) {
|
| 5272 | __ieee80211_beacon_add_tim(sdata, link, ps, skb, is_template);
|
| 5273 | } else {
|
| 5274 | spin_lock_bh(&local->tim_lock);
|
| 5275 | __ieee80211_beacon_add_tim(sdata, link, ps, skb, is_template);
|
| 5276 | spin_unlock_bh(&local->tim_lock);
|
| 5277 | }
|
| 5278 |
|
| 5279 | return 0;
|
| 5280 | }
|
| 5281 |
|
| 5282 | static void ieee80211_set_beacon_cntdwn(struct ieee80211_sub_if_data *sdata,
|
| 5283 | struct beacon_data *beacon,
|
| 5284 | struct ieee80211_link_data *link)
|
| 5285 | {
|
| 5286 | u8 *beacon_data, count, max_count = 1;
|
| 5287 | struct probe_resp *resp;
|
| 5288 | size_t beacon_data_len;
|
| 5289 | u16 *bcn_offsets;
|
| 5290 | int i;
|
| 5291 |
|
| 5292 | switch (sdata->vif.type) {
|
| 5293 | case NL80211_IFTYPE_AP:
|
| 5294 | beacon_data = beacon->tail;
|
| 5295 | beacon_data_len = beacon->tail_len;
|
| 5296 | break;
|
| 5297 | case NL80211_IFTYPE_ADHOC:
|
| 5298 | beacon_data = beacon->head;
|
| 5299 | beacon_data_len = beacon->head_len;
|
| 5300 | break;
|
| 5301 | case NL80211_IFTYPE_MESH_POINT:
|
| 5302 | beacon_data = beacon->head;
|
| 5303 | beacon_data_len = beacon->head_len;
|
| 5304 | break;
|
| 5305 | default:
|
| 5306 | return;
|
| 5307 | }
|
| 5308 |
|
| 5309 | resp = rcu_dereference(link->u.ap.probe_resp);
|
| 5310 |
|
| 5311 | bcn_offsets = beacon->cntdwn_counter_offsets;
|
| 5312 | count = beacon->cntdwn_current_counter;
|
| 5313 | if (link->conf->csa_active)
|
| 5314 | max_count = IEEE80211_MAX_CNTDWN_COUNTERS_NUM;
|
| 5315 |
|
| 5316 | for (i = 0; i < max_count; ++i) {
|
| 5317 | if (bcn_offsets[i]) {
|
| 5318 | if (WARN_ON_ONCE(bcn_offsets[i] >= beacon_data_len))
|
| 5319 | return;
|
| 5320 | beacon_data[bcn_offsets[i]] = count;
|
| 5321 | }
|
| 5322 |
|
| 5323 | if (sdata->vif.type == NL80211_IFTYPE_AP && resp) {
|
| 5324 | u16 *resp_offsets = resp->cntdwn_counter_offsets;
|
| 5325 |
|
| 5326 | if (resp_offsets[i])
|
| 5327 | resp->data[resp_offsets[i]] = count;
|
| 5328 | }
|
| 5329 | }
|
| 5330 | }
|
| 5331 |
|
| 5332 | static u8 __ieee80211_beacon_update_cntdwn(struct ieee80211_link_data *link,
|
| 5333 | struct beacon_data *beacon)
|
| 5334 | {
|
| 5335 | if (beacon->cntdwn_current_counter == 1) {
|
| 5336 | |
| 5337 | * Channel switch handling is done by a worker thread while
|
| 5338 | * beacons get pulled from hardware timers. It's therefore
|
| 5339 | * possible that software threads are slow enough to not be
|
| 5340 | * able to complete CSA handling in a single beacon interval,
|
| 5341 | * in which case we get here. There isn't much to do about
|
| 5342 | * it, other than letting the user know that the AP isn't
|
| 5343 | * behaving correctly.
|
| 5344 |
|
| 5345 | link_err_once(link,
|
| 5346 | "beacon TX faster than countdown (channel/color switch) completion\n");
|
| 5347 | return 0;
|
| 5348 | }
|
| 5349 |
|
| 5350 | beacon->cntdwn_current_counter--;
|
| 5351 |
|
| 5352 | return beacon->cntdwn_current_counter;
|
| 5353 | }
|
| 5354 |
|
| 5355 | u8 ieee80211_beacon_update_cntdwn(struct ieee80211_vif *vif, unsigned int link_id)
|
| 5356 | {
|
| 5357 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 5358 | struct ieee80211_link_data *link;
|
| 5359 | struct beacon_data *beacon = NULL;
|
| 5360 | u8 count = 0;
|
| 5361 |
|
| 5362 | if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
|
| 5363 | return 0;
|
| 5364 |
|
| 5365 | rcu_read_lock();
|
| 5366 |
|
| 5367 | link = rcu_dereference(sdata->link[link_id]);
|
| 5368 | if (!link)
|
| 5369 | goto unlock;
|
| 5370 |
|
| 5371 | if (sdata->vif.type == NL80211_IFTYPE_AP)
|
| 5372 | beacon = rcu_dereference(link->u.ap.beacon);
|
| 5373 | else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
|
| 5374 | beacon = rcu_dereference(sdata->u.ibss.presp);
|
| 5375 | else if (ieee80211_vif_is_mesh(&sdata->vif))
|
| 5376 | beacon = rcu_dereference(sdata->u.mesh.beacon);
|
| 5377 |
|
| 5378 | if (!beacon)
|
| 5379 | goto unlock;
|
| 5380 |
|
| 5381 | count = __ieee80211_beacon_update_cntdwn(link, beacon);
|
| 5382 |
|
| 5383 | unlock:
|
| 5384 | rcu_read_unlock();
|
| 5385 | return count;
|
| 5386 | }
|
| 5387 | EXPORT_SYMBOL(ieee80211_beacon_update_cntdwn);
|
| 5388 |
|
| 5389 | void ieee80211_beacon_set_cntdwn(struct ieee80211_vif *vif, u8 counter)
|
| 5390 | {
|
| 5391 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 5392 | struct beacon_data *beacon = NULL;
|
| 5393 |
|
| 5394 | rcu_read_lock();
|
| 5395 |
|
| 5396 | if (sdata->vif.type == NL80211_IFTYPE_AP)
|
| 5397 | beacon = rcu_dereference(sdata->deflink.u.ap.beacon);
|
| 5398 | else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
|
| 5399 | beacon = rcu_dereference(sdata->u.ibss.presp);
|
| 5400 | else if (ieee80211_vif_is_mesh(&sdata->vif))
|
| 5401 | beacon = rcu_dereference(sdata->u.mesh.beacon);
|
| 5402 |
|
| 5403 | if (!beacon)
|
| 5404 | goto unlock;
|
| 5405 |
|
| 5406 | if (counter < beacon->cntdwn_current_counter)
|
| 5407 | beacon->cntdwn_current_counter = counter;
|
| 5408 |
|
| 5409 | unlock:
|
| 5410 | rcu_read_unlock();
|
| 5411 | }
|
| 5412 | EXPORT_SYMBOL(ieee80211_beacon_set_cntdwn);
|
| 5413 |
|
| 5414 | bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif,
|
| 5415 | unsigned int link_id)
|
| 5416 | {
|
| 5417 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 5418 | struct ieee80211_link_data *link;
|
| 5419 | struct beacon_data *beacon = NULL;
|
| 5420 | u8 *beacon_data;
|
| 5421 | size_t beacon_data_len;
|
| 5422 | int ret = false;
|
| 5423 |
|
| 5424 | if (!ieee80211_sdata_running(sdata))
|
| 5425 | return false;
|
| 5426 |
|
| 5427 | if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
|
| 5428 | return 0;
|
| 5429 |
|
| 5430 | rcu_read_lock();
|
| 5431 |
|
| 5432 | link = rcu_dereference(sdata->link[link_id]);
|
| 5433 | if (!link)
|
| 5434 | goto out;
|
| 5435 |
|
| 5436 | if (vif->type == NL80211_IFTYPE_AP) {
|
| 5437 | beacon = rcu_dereference(link->u.ap.beacon);
|
| 5438 | if (WARN_ON(!beacon || !beacon->tail))
|
| 5439 | goto out;
|
| 5440 | beacon_data = beacon->tail;
|
| 5441 | beacon_data_len = beacon->tail_len;
|
| 5442 | } else if (vif->type == NL80211_IFTYPE_ADHOC) {
|
| 5443 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
| 5444 |
|
| 5445 | beacon = rcu_dereference(ifibss->presp);
|
| 5446 | if (!beacon)
|
| 5447 | goto out;
|
| 5448 |
|
| 5449 | beacon_data = beacon->head;
|
| 5450 | beacon_data_len = beacon->head_len;
|
| 5451 | } else if (vif->type == NL80211_IFTYPE_MESH_POINT) {
|
| 5452 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
| 5453 |
|
| 5454 | beacon = rcu_dereference(ifmsh->beacon);
|
| 5455 | if (!beacon)
|
| 5456 | goto out;
|
| 5457 |
|
| 5458 | beacon_data = beacon->head;
|
| 5459 | beacon_data_len = beacon->head_len;
|
| 5460 | } else {
|
| 5461 | WARN_ON(1);
|
| 5462 | goto out;
|
| 5463 | }
|
| 5464 |
|
| 5465 | if (!beacon->cntdwn_counter_offsets[0])
|
| 5466 | goto out;
|
| 5467 |
|
| 5468 | if (WARN_ON_ONCE(beacon->cntdwn_counter_offsets[0] > beacon_data_len))
|
| 5469 | goto out;
|
| 5470 |
|
| 5471 | if (beacon_data[beacon->cntdwn_counter_offsets[0]] == 1)
|
| 5472 | ret = true;
|
| 5473 |
|
| 5474 | out:
|
| 5475 | rcu_read_unlock();
|
| 5476 |
|
| 5477 | return ret;
|
| 5478 | }
|
| 5479 | EXPORT_SYMBOL(ieee80211_beacon_cntdwn_is_complete);
|
| 5480 |
|
| 5481 | static int ieee80211_beacon_protect(struct sk_buff *skb,
|
| 5482 | struct ieee80211_local *local,
|
| 5483 | struct ieee80211_sub_if_data *sdata,
|
| 5484 | struct ieee80211_link_data *link)
|
| 5485 | {
|
| 5486 | ieee80211_tx_result res;
|
| 5487 | struct ieee80211_tx_data tx;
|
| 5488 | struct sk_buff *check_skb;
|
| 5489 |
|
| 5490 | memset(&tx, 0, sizeof(tx));
|
| 5491 | tx.key = rcu_dereference(link->default_beacon_key);
|
| 5492 | if (!tx.key)
|
| 5493 | return 0;
|
| 5494 |
|
| 5495 | if (unlikely(tx.key->flags & KEY_FLAG_TAINTED)) {
|
| 5496 | tx.key = NULL;
|
| 5497 | return -EINVAL;
|
| 5498 | }
|
| 5499 |
|
| 5500 | if (!(tx.key->conf.flags & IEEE80211_KEY_FLAG_SW_MGMT_TX) &&
|
| 5501 | tx.key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
|
| 5502 | IEEE80211_SKB_CB(skb)->control.hw_key = &tx.key->conf;
|
| 5503 |
|
| 5504 | tx.local = local;
|
| 5505 | tx.sdata = sdata;
|
| 5506 | __skb_queue_head_init(&tx.skbs);
|
| 5507 | __skb_queue_tail(&tx.skbs, skb);
|
| 5508 | res = ieee80211_tx_h_encrypt(&tx);
|
| 5509 | check_skb = __skb_dequeue(&tx.skbs);
|
| 5510 |
|
| 5511 | WARN_ON(check_skb != skb);
|
| 5512 | if (WARN_ON_ONCE(res != TX_CONTINUE))
|
| 5513 | return -EINVAL;
|
| 5514 |
|
| 5515 | return 0;
|
| 5516 | }
|
| 5517 |
|
| 5518 | int ieee80211_encrypt_tx_skb(struct sk_buff *skb)
|
| 5519 | {
|
| 5520 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
| 5521 | struct ieee80211_sub_if_data *sdata = NULL;
|
| 5522 | struct sk_buff *check_skb;
|
| 5523 | struct ieee80211_tx_data tx;
|
| 5524 | ieee80211_tx_result res;
|
| 5525 |
|
| 5526 | if (!info->control.hw_key)
|
| 5527 | return 0;
|
| 5528 |
|
| 5529 | memset(&tx, 0, sizeof(tx));
|
| 5530 | tx.key = container_of(info->control.hw_key, struct ieee80211_key, conf);
|
| 5531 |
|
| 5532 | info->control.hw_key = NULL;
|
| 5533 | __skb_queue_head_init(&tx.skbs);
|
| 5534 | __skb_queue_tail(&tx.skbs, skb);
|
| 5535 |
|
| 5536 | if (skb->dev)
|
| 5537 | sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
|
| 5538 | else if (info->control.vif)
|
| 5539 | sdata = vif_to_sdata(info->control.vif);
|
| 5540 |
|
| 5541 | if (WARN_ON(!sdata))
|
| 5542 | return -EINVAL;
|
| 5543 |
|
| 5544 | tx.sdata = sdata;
|
| 5545 | tx.local = sdata->local;
|
| 5546 | res = ieee80211_tx_h_encrypt(&tx);
|
| 5547 | check_skb = __skb_dequeue(&tx.skbs);
|
| 5548 |
|
| 5549 | WARN_ON(check_skb != skb);
|
| 5550 | if (WARN_ON_ONCE(res != TX_CONTINUE))
|
| 5551 | return -EINVAL;
|
| 5552 |
|
| 5553 | return 0;
|
| 5554 | }
|
| 5555 | EXPORT_SYMBOL_GPL(ieee80211_encrypt_tx_skb);
|
| 5556 |
|
| 5557 | static void
|
| 5558 | ieee80211_beacon_get_finish(struct ieee80211_hw *hw,
|
| 5559 | struct ieee80211_vif *vif,
|
| 5560 | struct ieee80211_link_data *link,
|
| 5561 | struct ieee80211_mutable_offsets *offs,
|
| 5562 | struct beacon_data *beacon,
|
| 5563 | struct sk_buff *skb,
|
| 5564 | struct ieee80211_chanctx_conf *chanctx_conf,
|
| 5565 | u16 csa_off_base)
|
| 5566 | {
|
| 5567 | struct ieee80211_local *local = hw_to_local(hw);
|
| 5568 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 5569 | struct ieee80211_tx_info *info;
|
| 5570 | enum nl80211_band band;
|
| 5571 | struct ieee80211_tx_rate_control txrc;
|
| 5572 |
|
| 5573 |
|
| 5574 | if (offs && beacon) {
|
| 5575 | u16 i;
|
| 5576 |
|
| 5577 | for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; i++) {
|
| 5578 | u16 csa_off = beacon->cntdwn_counter_offsets[i];
|
| 5579 |
|
| 5580 | if (!csa_off)
|
| 5581 | continue;
|
| 5582 |
|
| 5583 | offs->cntdwn_counter_offs[i] = csa_off_base + csa_off;
|
| 5584 | }
|
| 5585 | }
|
| 5586 |
|
| 5587 | band = chanctx_conf->def.chan->band;
|
| 5588 | info = IEEE80211_SKB_CB(skb);
|
| 5589 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
| 5590 | info->flags |= IEEE80211_TX_CTL_NO_ACK;
|
| 5591 | info->band = band;
|
| 5592 |
|
| 5593 | memset(&txrc, 0, sizeof(txrc));
|
| 5594 | txrc.hw = hw;
|
| 5595 | txrc.sband = local->hw.wiphy->bands[band];
|
| 5596 | txrc.bss_conf = link->conf;
|
| 5597 | txrc.skb = skb;
|
| 5598 | txrc.reported_rate.idx = -1;
|
| 5599 | if (sdata->beacon_rate_set && sdata->beacon_rateidx_mask[band])
|
| 5600 | txrc.rate_idx_mask = sdata->beacon_rateidx_mask[band];
|
| 5601 | else
|
| 5602 | txrc.rate_idx_mask = sdata->rc_rateidx_mask[band];
|
| 5603 | txrc.bss = true;
|
| 5604 | rate_control_get_rate(sdata, NULL, &txrc);
|
| 5605 |
|
| 5606 | info->control.vif = vif;
|
| 5607 | info->control.flags |= u32_encode_bits(link->link_id,
|
| 5608 | IEEE80211_TX_CTRL_MLO_LINK);
|
| 5609 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT |
|
| 5610 | IEEE80211_TX_CTL_ASSIGN_SEQ |
|
| 5611 | IEEE80211_TX_CTL_FIRST_FRAGMENT;
|
| 5612 | }
|
| 5613 |
|
| 5614 | static void
|
| 5615 | ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon,
|
| 5616 | u8 i)
|
| 5617 | {
|
| 5618 | if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt ||
|
| 5619 | i > beacon->mbssid_ies->cnt)
|
| 5620 | return;
|
| 5621 |
|
| 5622 | if (i < beacon->mbssid_ies->cnt) {
|
| 5623 | skb_put_data(skb, beacon->mbssid_ies->elem[i].data,
|
| 5624 | beacon->mbssid_ies->elem[i].len);
|
| 5625 |
|
| 5626 | if (beacon->rnr_ies && beacon->rnr_ies->cnt) {
|
| 5627 | skb_put_data(skb, beacon->rnr_ies->elem[i].data,
|
| 5628 | beacon->rnr_ies->elem[i].len);
|
| 5629 |
|
| 5630 | for (i = beacon->mbssid_ies->cnt; i < beacon->rnr_ies->cnt; i++)
|
| 5631 | skb_put_data(skb, beacon->rnr_ies->elem[i].data,
|
| 5632 | beacon->rnr_ies->elem[i].len);
|
| 5633 | }
|
| 5634 | return;
|
| 5635 | }
|
| 5636 |
|
| 5637 |
|
| 5638 | for (i = 0; i < beacon->mbssid_ies->cnt; i++)
|
| 5639 | skb_put_data(skb, beacon->mbssid_ies->elem[i].data,
|
| 5640 | beacon->mbssid_ies->elem[i].len);
|
| 5641 | }
|
| 5642 |
|
| 5643 | static struct sk_buff *
|
| 5644 | __ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
|
| 5645 | struct ieee80211_vif *vif,
|
| 5646 | struct ieee80211_link_data *link,
|
| 5647 | struct ieee80211_mutable_offsets *offs,
|
| 5648 | bool is_template,
|
| 5649 | struct beacon_data *beacon,
|
| 5650 | struct ieee80211_chanctx_conf *chanctx_conf,
|
| 5651 | u8 ema_index)
|
| 5652 | {
|
| 5653 | struct ieee80211_local *local = hw_to_local(hw);
|
| 5654 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 5655 | struct ieee80211_if_ap *ap = &sdata->u.ap;
|
| 5656 | struct sk_buff *skb = NULL;
|
| 5657 | u16 csa_off_base = 0;
|
| 5658 | int mbssid_len;
|
| 5659 |
|
| 5660 | if (beacon->cntdwn_counter_offsets[0]) {
|
| 5661 | if (!is_template)
|
| 5662 | ieee80211_beacon_update_cntdwn(vif, link->link_id);
|
| 5663 |
|
| 5664 | ieee80211_set_beacon_cntdwn(sdata, beacon, link);
|
| 5665 | }
|
| 5666 |
|
| 5667 | |
| 5668 | * tail length, maximum TIM length and multiple BSSID length
|
| 5669 |
|
| 5670 | mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies,
|
| 5671 | beacon->rnr_ies,
|
| 5672 | ema_index);
|
| 5673 |
|
| 5674 | skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
|
| 5675 | beacon->tail_len + 256 +
|
| 5676 | local->hw.extra_beacon_tailroom + mbssid_len);
|
| 5677 | if (!skb)
|
| 5678 | return NULL;
|
| 5679 |
|
| 5680 | skb_reserve(skb, local->tx_headroom);
|
| 5681 | skb_put_data(skb, beacon->head, beacon->head_len);
|
| 5682 |
|
| 5683 | ieee80211_beacon_add_tim(sdata, link, &ap->ps, skb, is_template);
|
| 5684 |
|
| 5685 | if (offs) {
|
| 5686 | offs->tim_offset = beacon->head_len;
|
| 5687 | offs->tim_length = skb->len - beacon->head_len;
|
| 5688 | offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
|
| 5689 |
|
| 5690 | if (mbssid_len) {
|
| 5691 | ieee80211_beacon_add_mbssid(skb, beacon, ema_index);
|
| 5692 | offs->mbssid_off = skb->len - mbssid_len;
|
| 5693 | }
|
| 5694 |
|
| 5695 |
|
| 5696 | csa_off_base = skb->len;
|
| 5697 | }
|
| 5698 |
|
| 5699 | if (beacon->tail)
|
| 5700 | skb_put_data(skb, beacon->tail, beacon->tail_len);
|
| 5701 |
|
| 5702 | if (ieee80211_beacon_protect(skb, local, sdata, link) < 0) {
|
| 5703 | dev_kfree_skb(skb);
|
| 5704 | return NULL;
|
| 5705 | }
|
| 5706 |
|
| 5707 | ieee80211_beacon_get_finish(hw, vif, link, offs, beacon, skb,
|
| 5708 | chanctx_conf, csa_off_base);
|
| 5709 | return skb;
|
| 5710 | }
|
| 5711 |
|
| 5712 | static bool ieee80211_s1g_need_long_beacon(struct ieee80211_sub_if_data *sdata,
|
| 5713 | struct ieee80211_link_data *link)
|
| 5714 | {
|
| 5715 | struct ps_data *ps = &sdata->u.ap.ps;
|
| 5716 |
|
| 5717 | if (ps->sb_count == 0)
|
| 5718 | ps->sb_count = link->conf->s1g_long_beacon_period - 1;
|
| 5719 | else
|
| 5720 | ps->sb_count--;
|
| 5721 |
|
| 5722 | return ps->sb_count == 0;
|
| 5723 | }
|
| 5724 |
|
| 5725 | static struct sk_buff *
|
| 5726 | ieee80211_s1g_short_beacon_get(struct ieee80211_hw *hw,
|
| 5727 | struct ieee80211_vif *vif,
|
| 5728 | struct ieee80211_link_data *link,
|
| 5729 | struct ieee80211_chanctx_conf *chanctx_conf,
|
| 5730 | struct s1g_short_beacon_data *sb,
|
| 5731 | bool is_template)
|
| 5732 | {
|
| 5733 | struct ieee80211_local *local = hw_to_local(hw);
|
| 5734 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 5735 | struct ieee80211_if_ap *ap = &sdata->u.ap;
|
| 5736 | struct sk_buff *skb;
|
| 5737 |
|
| 5738 | skb = dev_alloc_skb(local->tx_headroom + sb->short_head_len +
|
| 5739 | sb->short_tail_len + 256 +
|
| 5740 | local->hw.extra_beacon_tailroom);
|
| 5741 | if (!skb)
|
| 5742 | return NULL;
|
| 5743 |
|
| 5744 | skb_reserve(skb, local->tx_headroom);
|
| 5745 | skb_put_data(skb, sb->short_head, sb->short_head_len);
|
| 5746 |
|
| 5747 | ieee80211_beacon_add_tim(sdata, link, &ap->ps, skb, is_template);
|
| 5748 |
|
| 5749 | if (sb->short_tail)
|
| 5750 | skb_put_data(skb, sb->short_tail, sb->short_tail_len);
|
| 5751 |
|
| 5752 | ieee80211_beacon_get_finish(hw, vif, link, NULL, NULL, skb,
|
| 5753 | chanctx_conf, 0);
|
| 5754 | return skb;
|
| 5755 | }
|
| 5756 |
|
| 5757 | static struct sk_buff *
|
| 5758 | ieee80211_beacon_get_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
| 5759 | struct ieee80211_link_data *link,
|
| 5760 | struct ieee80211_mutable_offsets *offs,
|
| 5761 | bool is_template, struct beacon_data *beacon,
|
| 5762 | struct ieee80211_chanctx_conf *chanctx_conf,
|
| 5763 | u8 ema_index, struct s1g_short_beacon_data *s1g_sb)
|
| 5764 | {
|
| 5765 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 5766 |
|
| 5767 | if (!sdata->vif.cfg.s1g || !s1g_sb ||
|
| 5768 | ieee80211_s1g_need_long_beacon(sdata, link))
|
| 5769 | return __ieee80211_beacon_get_ap(hw, vif, link, offs,
|
| 5770 | is_template, beacon,
|
| 5771 | chanctx_conf, ema_index);
|
| 5772 |
|
| 5773 | return ieee80211_s1g_short_beacon_get(hw, vif, link, chanctx_conf,
|
| 5774 | s1g_sb, is_template);
|
| 5775 | }
|
| 5776 |
|
| 5777 | static struct ieee80211_ema_beacons *
|
| 5778 | ieee80211_beacon_get_ap_ema_list(struct ieee80211_hw *hw,
|
| 5779 | struct ieee80211_vif *vif,
|
| 5780 | struct ieee80211_link_data *link,
|
| 5781 | struct ieee80211_mutable_offsets *offs,
|
| 5782 | bool is_template, struct beacon_data *beacon,
|
| 5783 | struct ieee80211_chanctx_conf *chanctx_conf)
|
| 5784 | {
|
| 5785 | struct ieee80211_ema_beacons *ema = NULL;
|
| 5786 |
|
| 5787 | if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt)
|
| 5788 | return NULL;
|
| 5789 |
|
| 5790 | ema = kzalloc_flex(*ema, bcn, beacon->mbssid_ies->cnt, GFP_ATOMIC);
|
| 5791 | if (!ema)
|
| 5792 | return NULL;
|
| 5793 |
|
| 5794 | for (ema->cnt = 0; ema->cnt < beacon->mbssid_ies->cnt; ema->cnt++) {
|
| 5795 | ema->bcn[ema->cnt].skb =
|
| 5796 | ieee80211_beacon_get_ap(hw, vif, link,
|
| 5797 | &ema->bcn[ema->cnt].offs,
|
| 5798 | is_template, beacon,
|
| 5799 | chanctx_conf, ema->cnt, NULL);
|
| 5800 | if (!ema->bcn[ema->cnt].skb)
|
| 5801 | break;
|
| 5802 | }
|
| 5803 |
|
| 5804 | if (ema->cnt == beacon->mbssid_ies->cnt)
|
| 5805 | return ema;
|
| 5806 |
|
| 5807 | ieee80211_beacon_free_ema_list(ema);
|
| 5808 | return NULL;
|
| 5809 | }
|
| 5810 |
|
| 5811 | #define IEEE80211_INCLUDE_ALL_MBSSID_ELEMS -1
|
| 5812 |
|
| 5813 | static struct sk_buff *
|
| 5814 | __ieee80211_beacon_get(struct ieee80211_hw *hw,
|
| 5815 | struct ieee80211_vif *vif,
|
| 5816 | struct ieee80211_mutable_offsets *offs,
|
| 5817 | bool is_template,
|
| 5818 | unsigned int link_id,
|
| 5819 | int ema_index,
|
| 5820 | struct ieee80211_ema_beacons **ema_beacons)
|
| 5821 | {
|
| 5822 | struct ieee80211_local *local = hw_to_local(hw);
|
| 5823 | struct beacon_data *beacon = NULL;
|
| 5824 | struct sk_buff *skb = NULL;
|
| 5825 | struct ieee80211_sub_if_data *sdata = NULL;
|
| 5826 | struct ieee80211_chanctx_conf *chanctx_conf;
|
| 5827 | struct ieee80211_link_data *link;
|
| 5828 | struct s1g_short_beacon_data *s1g_short_bcn = NULL;
|
| 5829 |
|
| 5830 | rcu_read_lock();
|
| 5831 |
|
| 5832 | sdata = vif_to_sdata(vif);
|
| 5833 | link = rcu_dereference(sdata->link[link_id]);
|
| 5834 | if (!link)
|
| 5835 | goto out;
|
| 5836 | chanctx_conf =
|
| 5837 | rcu_dereference(link->conf->chanctx_conf);
|
| 5838 |
|
| 5839 | if (!ieee80211_sdata_running(sdata) || !chanctx_conf)
|
| 5840 | goto out;
|
| 5841 |
|
| 5842 | if (offs)
|
| 5843 | memset(offs, 0, sizeof(*offs));
|
| 5844 |
|
| 5845 | if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
| 5846 | beacon = rcu_dereference(link->u.ap.beacon);
|
| 5847 | if (!beacon)
|
| 5848 | goto out;
|
| 5849 |
|
| 5850 | if (vif->cfg.s1g && link->u.ap.s1g_short_beacon) {
|
| 5851 | s1g_short_bcn =
|
| 5852 | rcu_dereference(link->u.ap.s1g_short_beacon);
|
| 5853 | if (!s1g_short_bcn)
|
| 5854 | goto out;
|
| 5855 | }
|
| 5856 |
|
| 5857 | if (ema_beacons) {
|
| 5858 | *ema_beacons =
|
| 5859 | ieee80211_beacon_get_ap_ema_list(hw, vif, link,
|
| 5860 | offs,
|
| 5861 | is_template,
|
| 5862 | beacon,
|
| 5863 | chanctx_conf);
|
| 5864 | } else {
|
| 5865 | if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) {
|
| 5866 | if (ema_index >= beacon->mbssid_ies->cnt)
|
| 5867 | goto out;
|
| 5868 |
|
| 5869 | if (ema_index <= IEEE80211_INCLUDE_ALL_MBSSID_ELEMS)
|
| 5870 | ema_index = beacon->mbssid_ies->cnt;
|
| 5871 | } else {
|
| 5872 | ema_index = 0;
|
| 5873 | }
|
| 5874 |
|
| 5875 | skb = ieee80211_beacon_get_ap(hw, vif, link, offs,
|
| 5876 | is_template, beacon,
|
| 5877 | chanctx_conf, ema_index,
|
| 5878 | s1g_short_bcn);
|
| 5879 | }
|
| 5880 | } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
|
| 5881 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
| 5882 | struct ieee80211_hdr *hdr;
|
| 5883 |
|
| 5884 | beacon = rcu_dereference(ifibss->presp);
|
| 5885 | if (!beacon)
|
| 5886 | goto out;
|
| 5887 |
|
| 5888 | if (beacon->cntdwn_counter_offsets[0]) {
|
| 5889 | if (!is_template)
|
| 5890 | __ieee80211_beacon_update_cntdwn(link, beacon);
|
| 5891 |
|
| 5892 | ieee80211_set_beacon_cntdwn(sdata, beacon, link);
|
| 5893 | }
|
| 5894 |
|
| 5895 | skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
|
| 5896 | local->hw.extra_beacon_tailroom);
|
| 5897 | if (!skb)
|
| 5898 | goto out;
|
| 5899 | skb_reserve(skb, local->tx_headroom);
|
| 5900 | skb_put_data(skb, beacon->head, beacon->head_len);
|
| 5901 |
|
| 5902 | hdr = (struct ieee80211_hdr *) skb->data;
|
| 5903 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
| 5904 | IEEE80211_STYPE_BEACON);
|
| 5905 |
|
| 5906 | ieee80211_beacon_get_finish(hw, vif, link, offs, beacon, skb,
|
| 5907 | chanctx_conf, 0);
|
| 5908 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
| 5909 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
| 5910 |
|
| 5911 | beacon = rcu_dereference(ifmsh->beacon);
|
| 5912 | if (!beacon)
|
| 5913 | goto out;
|
| 5914 |
|
| 5915 | if (beacon->cntdwn_counter_offsets[0]) {
|
| 5916 | if (!is_template)
|
| 5917 | |
| 5918 | * decrementing it by one isn't correct, but
|
| 5919 | * for now we leave it consistent with overall
|
| 5920 | * mac80211's behavior.
|
| 5921 |
|
| 5922 | __ieee80211_beacon_update_cntdwn(link, beacon);
|
| 5923 |
|
| 5924 | ieee80211_set_beacon_cntdwn(sdata, beacon, link);
|
| 5925 | }
|
| 5926 |
|
| 5927 | if (ifmsh->sync_ops)
|
| 5928 | ifmsh->sync_ops->adjust_tsf(sdata, beacon);
|
| 5929 |
|
| 5930 | skb = dev_alloc_skb(local->tx_headroom +
|
| 5931 | beacon->head_len +
|
| 5932 | 256 +
|
| 5933 | beacon->tail_len +
|
| 5934 | local->hw.extra_beacon_tailroom);
|
| 5935 | if (!skb)
|
| 5936 | goto out;
|
| 5937 | skb_reserve(skb, local->tx_headroom);
|
| 5938 | skb_put_data(skb, beacon->head, beacon->head_len);
|
| 5939 | ieee80211_beacon_add_tim(sdata, link, &ifmsh->ps, skb,
|
| 5940 | is_template);
|
| 5941 |
|
| 5942 | if (offs) {
|
| 5943 | offs->tim_offset = beacon->head_len;
|
| 5944 | offs->tim_length = skb->len - beacon->head_len;
|
| 5945 | }
|
| 5946 |
|
| 5947 | skb_put_data(skb, beacon->tail, beacon->tail_len);
|
| 5948 | ieee80211_beacon_get_finish(hw, vif, link, offs, beacon, skb,
|
| 5949 | chanctx_conf, 0);
|
| 5950 | } else {
|
| 5951 | WARN_ON(1);
|
| 5952 | goto out;
|
| 5953 | }
|
| 5954 |
|
| 5955 | out:
|
| 5956 | rcu_read_unlock();
|
| 5957 | return skb;
|
| 5958 |
|
| 5959 | }
|
| 5960 |
|
| 5961 | struct sk_buff *
|
| 5962 | ieee80211_beacon_get_template(struct ieee80211_hw *hw,
|
| 5963 | struct ieee80211_vif *vif,
|
| 5964 | struct ieee80211_mutable_offsets *offs,
|
| 5965 | unsigned int link_id)
|
| 5966 | {
|
| 5967 | return __ieee80211_beacon_get(hw, vif, offs, true, link_id,
|
| 5968 | IEEE80211_INCLUDE_ALL_MBSSID_ELEMS, NULL);
|
| 5969 | }
|
| 5970 | EXPORT_SYMBOL(ieee80211_beacon_get_template);
|
| 5971 |
|
| 5972 | struct sk_buff *
|
| 5973 | ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw,
|
| 5974 | struct ieee80211_vif *vif,
|
| 5975 | struct ieee80211_mutable_offsets *offs,
|
| 5976 | unsigned int link_id, u8 ema_index)
|
| 5977 | {
|
| 5978 | return __ieee80211_beacon_get(hw, vif, offs, true, link_id, ema_index,
|
| 5979 | NULL);
|
| 5980 | }
|
| 5981 | EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_index);
|
| 5982 |
|
| 5983 | void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons)
|
| 5984 | {
|
| 5985 | u8 i;
|
| 5986 |
|
| 5987 | if (!ema_beacons)
|
| 5988 | return;
|
| 5989 |
|
| 5990 | for (i = 0; i < ema_beacons->cnt; i++)
|
| 5991 | kfree_skb(ema_beacons->bcn[i].skb);
|
| 5992 |
|
| 5993 | kfree(ema_beacons);
|
| 5994 | }
|
| 5995 | EXPORT_SYMBOL(ieee80211_beacon_free_ema_list);
|
| 5996 |
|
| 5997 | struct ieee80211_ema_beacons *
|
| 5998 | ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw,
|
| 5999 | struct ieee80211_vif *vif,
|
| 6000 | unsigned int link_id)
|
| 6001 | {
|
| 6002 | struct ieee80211_ema_beacons *ema_beacons = NULL;
|
| 6003 |
|
| 6004 | WARN_ON(__ieee80211_beacon_get(hw, vif, NULL, true, link_id, 0,
|
| 6005 | &ema_beacons));
|
| 6006 |
|
| 6007 | return ema_beacons;
|
| 6008 | }
|
| 6009 | EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_list);
|
| 6010 |
|
| 6011 | struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
|
| 6012 | struct ieee80211_vif *vif,
|
| 6013 | u16 *tim_offset, u16 *tim_length,
|
| 6014 | unsigned int link_id)
|
| 6015 | {
|
| 6016 | struct ieee80211_mutable_offsets offs = {};
|
| 6017 | struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false,
|
| 6018 | link_id,
|
| 6019 | IEEE80211_INCLUDE_ALL_MBSSID_ELEMS,
|
| 6020 | NULL);
|
| 6021 | struct sk_buff *copy;
|
| 6022 |
|
| 6023 | if (!bcn)
|
| 6024 | return bcn;
|
| 6025 |
|
| 6026 | if (tim_offset)
|
| 6027 | *tim_offset = offs.tim_offset;
|
| 6028 |
|
| 6029 | if (tim_length)
|
| 6030 | *tim_length = offs.tim_length;
|
| 6031 |
|
| 6032 | if (ieee80211_hw_check(hw, BEACON_TX_STATUS) ||
|
| 6033 | !hw_to_local(hw)->monitors)
|
| 6034 | return bcn;
|
| 6035 |
|
| 6036 |
|
| 6037 | copy = skb_copy(bcn, GFP_ATOMIC);
|
| 6038 | if (!copy)
|
| 6039 | return bcn;
|
| 6040 |
|
| 6041 | ieee80211_tx_monitor(hw_to_local(hw), copy, 1, NULL);
|
| 6042 |
|
| 6043 | return bcn;
|
| 6044 | }
|
| 6045 | EXPORT_SYMBOL(ieee80211_beacon_get_tim);
|
| 6046 |
|
| 6047 | struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,
|
| 6048 | struct ieee80211_vif *vif)
|
| 6049 | {
|
| 6050 | struct sk_buff *skb = NULL;
|
| 6051 | struct probe_resp *presp = NULL;
|
| 6052 | struct ieee80211_hdr *hdr;
|
| 6053 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 6054 |
|
| 6055 | if (sdata->vif.type != NL80211_IFTYPE_AP)
|
| 6056 | return NULL;
|
| 6057 |
|
| 6058 | rcu_read_lock();
|
| 6059 | presp = rcu_dereference(sdata->deflink.u.ap.probe_resp);
|
| 6060 | if (!presp)
|
| 6061 | goto out;
|
| 6062 |
|
| 6063 | skb = dev_alloc_skb(presp->len);
|
| 6064 | if (!skb)
|
| 6065 | goto out;
|
| 6066 |
|
| 6067 | skb_put_data(skb, presp->data, presp->len);
|
| 6068 |
|
| 6069 | hdr = (struct ieee80211_hdr *) skb->data;
|
| 6070 | memset(hdr->addr1, 0, sizeof(hdr->addr1));
|
| 6071 |
|
| 6072 | out:
|
| 6073 | rcu_read_unlock();
|
| 6074 | return skb;
|
| 6075 | }
|
| 6076 | EXPORT_SYMBOL(ieee80211_proberesp_get);
|
| 6077 |
|
| 6078 | struct sk_buff *ieee80211_get_fils_discovery_tmpl(struct ieee80211_hw *hw,
|
| 6079 | struct ieee80211_vif *vif,
|
| 6080 | unsigned int link_id)
|
| 6081 | {
|
| 6082 | struct sk_buff *skb = NULL;
|
| 6083 | struct fils_discovery_data *tmpl = NULL;
|
| 6084 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 6085 | struct ieee80211_link_data *link;
|
| 6086 |
|
| 6087 | if (sdata->vif.type != NL80211_IFTYPE_AP)
|
| 6088 | return NULL;
|
| 6089 |
|
| 6090 | if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS)
|
| 6091 | return NULL;
|
| 6092 |
|
| 6093 | guard(rcu)();
|
| 6094 | link = rcu_dereference(sdata->link[link_id]);
|
| 6095 | if (!link)
|
| 6096 | return NULL;
|
| 6097 |
|
| 6098 | tmpl = rcu_dereference(link->u.ap.fils_discovery);
|
| 6099 | if (!tmpl)
|
| 6100 | return NULL;
|
| 6101 |
|
| 6102 | skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + tmpl->len);
|
| 6103 | if (skb) {
|
| 6104 | skb_reserve(skb, sdata->local->hw.extra_tx_headroom);
|
| 6105 | skb_put_data(skb, tmpl->data, tmpl->len);
|
| 6106 | }
|
| 6107 |
|
| 6108 | return skb;
|
| 6109 | }
|
| 6110 | EXPORT_SYMBOL(ieee80211_get_fils_discovery_tmpl);
|
| 6111 |
|
| 6112 | struct sk_buff *
|
| 6113 | ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
|
| 6114 | struct ieee80211_vif *vif,
|
| 6115 | unsigned int link_id)
|
| 6116 | {
|
| 6117 | struct sk_buff *skb = NULL;
|
| 6118 | struct unsol_bcast_probe_resp_data *tmpl = NULL;
|
| 6119 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 6120 | struct ieee80211_link_data *link;
|
| 6121 |
|
| 6122 | if (sdata->vif.type != NL80211_IFTYPE_AP)
|
| 6123 | return NULL;
|
| 6124 |
|
| 6125 | if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS)
|
| 6126 | return NULL;
|
| 6127 |
|
| 6128 | guard(rcu)();
|
| 6129 | link = rcu_dereference(sdata->link[link_id]);
|
| 6130 | if (!link)
|
| 6131 | return NULL;
|
| 6132 |
|
| 6133 | tmpl = rcu_dereference(link->u.ap.unsol_bcast_probe_resp);
|
| 6134 | if (!tmpl)
|
| 6135 | return NULL;
|
| 6136 |
|
| 6137 | skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + tmpl->len);
|
| 6138 | if (skb) {
|
| 6139 | skb_reserve(skb, sdata->local->hw.extra_tx_headroom);
|
| 6140 | skb_put_data(skb, tmpl->data, tmpl->len);
|
| 6141 | }
|
| 6142 |
|
| 6143 | return skb;
|
| 6144 | }
|
| 6145 | EXPORT_SYMBOL(ieee80211_get_unsol_bcast_probe_resp_tmpl);
|
| 6146 |
|
| 6147 | struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
|
| 6148 | struct ieee80211_vif *vif)
|
| 6149 | {
|
| 6150 | struct ieee80211_sub_if_data *sdata;
|
| 6151 | struct ieee80211_pspoll *pspoll;
|
| 6152 | struct ieee80211_local *local;
|
| 6153 | struct sk_buff *skb;
|
| 6154 |
|
| 6155 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
|
| 6156 | return NULL;
|
| 6157 |
|
| 6158 | sdata = vif_to_sdata(vif);
|
| 6159 | local = sdata->local;
|
| 6160 |
|
| 6161 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll));
|
| 6162 | if (!skb)
|
| 6163 | return NULL;
|
| 6164 |
|
| 6165 | skb_reserve(skb, local->hw.extra_tx_headroom);
|
| 6166 |
|
| 6167 | pspoll = skb_put_zero(skb, sizeof(*pspoll));
|
| 6168 | pspoll->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
|
| 6169 | IEEE80211_STYPE_PSPOLL);
|
| 6170 | pspoll->aid = cpu_to_le16(sdata->vif.cfg.aid);
|
| 6171 |
|
| 6172 |
|
| 6173 | pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14);
|
| 6174 |
|
| 6175 | memcpy(pspoll->bssid, sdata->deflink.u.mgd.bssid, ETH_ALEN);
|
| 6176 | memcpy(pspoll->ta, vif->addr, ETH_ALEN);
|
| 6177 |
|
| 6178 | return skb;
|
| 6179 | }
|
| 6180 | EXPORT_SYMBOL(ieee80211_pspoll_get);
|
| 6181 |
|
| 6182 | struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
|
| 6183 | struct ieee80211_vif *vif,
|
| 6184 | int link_id, bool qos_ok)
|
| 6185 | {
|
| 6186 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
| 6187 | struct ieee80211_local *local = sdata->local;
|
| 6188 | struct ieee80211_link_data *link = NULL;
|
| 6189 | struct ieee80211_hdr_3addr *nullfunc;
|
| 6190 | struct sk_buff *skb;
|
| 6191 | bool qos = false;
|
| 6192 |
|
| 6193 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
|
| 6194 | return NULL;
|
| 6195 |
|
| 6196 | skb = dev_alloc_skb(local->hw.extra_tx_headroom +
|
| 6197 | sizeof(*nullfunc) + 2);
|
| 6198 | if (!skb)
|
| 6199 | return NULL;
|
| 6200 |
|
| 6201 | rcu_read_lock();
|
| 6202 | if (qos_ok) {
|
| 6203 | struct sta_info *sta;
|
| 6204 |
|
| 6205 | sta = sta_info_get(sdata, vif->cfg.ap_addr);
|
| 6206 | qos = sta && sta->sta.wme;
|
| 6207 | }
|
| 6208 |
|
| 6209 | if (link_id >= 0) {
|
| 6210 | link = rcu_dereference(sdata->link[link_id]);
|
| 6211 | if (WARN_ON_ONCE(!link)) {
|
| 6212 | rcu_read_unlock();
|
| 6213 | kfree_skb(skb);
|
| 6214 | return NULL;
|
| 6215 | }
|
| 6216 | }
|
| 6217 |
|
| 6218 | skb_reserve(skb, local->hw.extra_tx_headroom);
|
| 6219 |
|
| 6220 | nullfunc = skb_put_zero(skb, sizeof(*nullfunc));
|
| 6221 | nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
|
| 6222 | IEEE80211_STYPE_NULLFUNC |
|
| 6223 | IEEE80211_FCTL_TODS);
|
| 6224 | if (qos) {
|
| 6225 | __le16 qoshdr = cpu_to_le16(7);
|
| 6226 |
|
| 6227 | BUILD_BUG_ON((IEEE80211_STYPE_QOS_NULLFUNC |
|
| 6228 | IEEE80211_STYPE_NULLFUNC) !=
|
| 6229 | IEEE80211_STYPE_QOS_NULLFUNC);
|
| 6230 | nullfunc->frame_control |=
|
| 6231 | cpu_to_le16(IEEE80211_STYPE_QOS_NULLFUNC);
|
| 6232 | skb->priority = 7;
|
| 6233 | skb_set_queue_mapping(skb, IEEE80211_AC_VO);
|
| 6234 | skb_put_data(skb, &qoshdr, sizeof(qoshdr));
|
| 6235 | }
|
| 6236 |
|
| 6237 | if (link) {
|
| 6238 | memcpy(nullfunc->addr1, link->conf->bssid, ETH_ALEN);
|
| 6239 | memcpy(nullfunc->addr2, link->conf->addr, ETH_ALEN);
|
| 6240 | memcpy(nullfunc->addr3, link->conf->bssid, ETH_ALEN);
|
| 6241 | } else {
|
| 6242 | memcpy(nullfunc->addr1, vif->cfg.ap_addr, ETH_ALEN);
|
| 6243 | memcpy(nullfunc->addr2, vif->addr, ETH_ALEN);
|
| 6244 | memcpy(nullfunc->addr3, vif->cfg.ap_addr, ETH_ALEN);
|
| 6245 | }
|
| 6246 | rcu_read_unlock();
|
| 6247 |
|
| 6248 | return skb;
|
| 6249 | }
|
| 6250 | EXPORT_SYMBOL(ieee80211_nullfunc_get);
|
| 6251 |
|
| 6252 | struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
|
| 6253 | const u8 *src_addr,
|
| 6254 | const u8 *ssid, size_t ssid_len,
|
| 6255 | size_t tailroom)
|
| 6256 | {
|
| 6257 | struct ieee80211_local *local = hw_to_local(hw);
|
| 6258 | struct ieee80211_hdr_3addr *hdr;
|
| 6259 | struct sk_buff *skb;
|
| 6260 | size_t ie_ssid_len;
|
| 6261 | u8 *pos;
|
| 6262 |
|
| 6263 | ie_ssid_len = 2 + ssid_len;
|
| 6264 |
|
| 6265 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*hdr) +
|
| 6266 | ie_ssid_len + tailroom);
|
| 6267 | if (!skb)
|
| 6268 | return NULL;
|
| 6269 |
|
| 6270 | skb_reserve(skb, local->hw.extra_tx_headroom);
|
| 6271 |
|
| 6272 | hdr = skb_put_zero(skb, sizeof(*hdr));
|
| 6273 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
| 6274 | IEEE80211_STYPE_PROBE_REQ);
|
| 6275 | eth_broadcast_addr(hdr->addr1);
|
| 6276 | memcpy(hdr->addr2, src_addr, ETH_ALEN);
|
| 6277 | eth_broadcast_addr(hdr->addr3);
|
| 6278 |
|
| 6279 | pos = skb_put(skb, ie_ssid_len);
|
| 6280 | *pos++ = WLAN_EID_SSID;
|
| 6281 | *pos++ = ssid_len;
|
| 6282 | if (ssid_len)
|
| 6283 | memcpy(pos, ssid, ssid_len);
|
| 6284 | pos += ssid_len;
|
| 6285 |
|
| 6286 | return skb;
|
| 6287 | }
|
| 6288 | EXPORT_SYMBOL(ieee80211_probereq_get);
|
| 6289 |
|
| 6290 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
| 6291 | const void *frame, size_t frame_len,
|
| 6292 | const struct ieee80211_tx_info *frame_txctl,
|
| 6293 | struct ieee80211_rts *rts)
|
| 6294 | {
|
| 6295 | const struct ieee80211_hdr *hdr = frame;
|
| 6296 |
|
| 6297 | rts->frame_control =
|
| 6298 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
|
| 6299 | rts->duration = ieee80211_rts_duration(hw, vif, frame_len,
|
| 6300 | frame_txctl);
|
| 6301 | memcpy(rts->ra, hdr->addr1, sizeof(rts->ra));
|
| 6302 | memcpy(rts->ta, hdr->addr2, sizeof(rts->ta));
|
| 6303 | }
|
| 6304 | EXPORT_SYMBOL(ieee80211_rts_get);
|
| 6305 |
|
| 6306 | void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
| 6307 | const void *frame, size_t frame_len,
|
| 6308 | const struct ieee80211_tx_info *frame_txctl,
|
| 6309 | struct ieee80211_cts *cts)
|
| 6310 | {
|
| 6311 | const struct ieee80211_hdr *hdr = frame;
|
| 6312 |
|
| 6313 | cts->frame_control =
|
| 6314 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
|
| 6315 | cts->duration = ieee80211_ctstoself_duration(hw, vif,
|
| 6316 | frame_len, frame_txctl);
|
| 6317 | memcpy(cts->ra, hdr->addr1, sizeof(cts->ra));
|
| 6318 | }
|
| 6319 | EXPORT_SYMBOL(ieee80211_ctstoself_get);
|
| 6320 |
|
| 6321 | struct sk_buff *
|
| 6322 | ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
|
| 6323 | struct ieee80211_vif *vif)
|
| 6324 | {
|
| 6325 | struct ieee80211_local *local = hw_to_local(hw);
|
| 6326 | struct sk_buff *skb = NULL;
|
| 6327 | struct ieee80211_tx_data tx;
|
| 6328 | struct ieee80211_sub_if_data *sdata;
|
| 6329 | struct ps_data *ps;
|
| 6330 | struct ieee80211_tx_info *info;
|
| 6331 | struct ieee80211_chanctx_conf *chanctx_conf;
|
| 6332 |
|
| 6333 | sdata = vif_to_sdata(vif);
|
| 6334 |
|
| 6335 | rcu_read_lock();
|
| 6336 | chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
|
| 6337 |
|
| 6338 | if (!chanctx_conf)
|
| 6339 | goto out;
|
| 6340 |
|
| 6341 | if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
| 6342 | struct beacon_data *beacon =
|
| 6343 | rcu_dereference(sdata->deflink.u.ap.beacon);
|
| 6344 |
|
| 6345 | if (!beacon || !beacon->head)
|
| 6346 | goto out;
|
| 6347 |
|
| 6348 | ps = &sdata->u.ap.ps;
|
| 6349 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
| 6350 | ps = &sdata->u.mesh.ps;
|
| 6351 | } else {
|
| 6352 | goto out;
|
| 6353 | }
|
| 6354 |
|
| 6355 | if (ps->dtim_count != 0 || !ps->dtim_bc_mc)
|
| 6356 | goto out;
|
| 6357 |
|
| 6358 | while (1) {
|
| 6359 | skb = skb_dequeue(&ps->bc_buf);
|
| 6360 | if (!skb)
|
| 6361 | goto out;
|
| 6362 | local->total_ps_buffered--;
|
| 6363 |
|
| 6364 | if (!skb_queue_empty(&ps->bc_buf) && skb->len >= 2) {
|
| 6365 | struct ieee80211_hdr *hdr =
|
| 6366 | (struct ieee80211_hdr *) skb->data;
|
| 6367 | |
| 6368 | * MoreData flag in IEEE 802.11 header to inform PS
|
| 6369 | * STAs
|
| 6370 | hdr->frame_control |=
|
| 6371 | cpu_to_le16(IEEE80211_FCTL_MOREDATA);
|
| 6372 | }
|
| 6373 |
|
| 6374 | if (sdata->vif.type == NL80211_IFTYPE_AP)
|
| 6375 | sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
|
| 6376 | if (!ieee80211_tx_prepare(sdata, &tx, NULL, skb))
|
| 6377 | break;
|
| 6378 | ieee80211_free_txskb(hw, skb);
|
| 6379 | }
|
| 6380 |
|
| 6381 | info = IEEE80211_SKB_CB(skb);
|
| 6382 |
|
| 6383 | tx.flags |= IEEE80211_TX_PS_BUFFERED;
|
| 6384 | info->band = chanctx_conf->def.chan->band;
|
| 6385 |
|
| 6386 | if (invoke_tx_handlers(&tx))
|
| 6387 | skb = NULL;
|
| 6388 | out:
|
| 6389 | rcu_read_unlock();
|
| 6390 |
|
| 6391 | return skb;
|
| 6392 | }
|
| 6393 | EXPORT_SYMBOL(ieee80211_get_buffered_bc);
|
| 6394 |
|
| 6395 | int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid)
|
| 6396 | {
|
| 6397 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
|
| 6398 | struct ieee80211_sub_if_data *sdata = sta->sdata;
|
| 6399 | struct ieee80211_local *local = sdata->local;
|
| 6400 | int ret;
|
| 6401 | u32 queues;
|
| 6402 |
|
| 6403 | lockdep_assert_wiphy(local->hw.wiphy);
|
| 6404 |
|
| 6405 |
|
| 6406 | switch (sdata->vif.type) {
|
| 6407 | case NL80211_IFTYPE_STATION:
|
| 6408 | case NL80211_IFTYPE_AP:
|
| 6409 | case NL80211_IFTYPE_AP_VLAN:
|
| 6410 | break;
|
| 6411 | default:
|
| 6412 | WARN_ON(1);
|
| 6413 | return -EINVAL;
|
| 6414 | }
|
| 6415 |
|
| 6416 | if (WARN_ON(tid >= IEEE80211_NUM_UPS))
|
| 6417 | return -EINVAL;
|
| 6418 |
|
| 6419 | if (sta->reserved_tid == tid) {
|
| 6420 | ret = 0;
|
| 6421 | goto out;
|
| 6422 | }
|
| 6423 |
|
| 6424 | if (sta->reserved_tid != IEEE80211_TID_UNRESERVED) {
|
| 6425 | sdata_err(sdata, "TID reservation already active\n");
|
| 6426 | ret = -EALREADY;
|
| 6427 | goto out;
|
| 6428 | }
|
| 6429 |
|
| 6430 | ieee80211_stop_vif_queues(sdata->local, sdata,
|
| 6431 | IEEE80211_QUEUE_STOP_REASON_RESERVE_TID);
|
| 6432 |
|
| 6433 | synchronize_net();
|
| 6434 |
|
| 6435 |
|
| 6436 | if (ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION)) {
|
| 6437 | set_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
| 6438 | __ieee80211_stop_tx_ba_session(sta, tid,
|
| 6439 | AGG_STOP_LOCAL_REQUEST);
|
| 6440 | }
|
| 6441 |
|
| 6442 | queues = BIT(sdata->vif.hw_queue[ieee802_1d_to_ac[tid]]);
|
| 6443 | __ieee80211_flush_queues(local, sdata, queues, false);
|
| 6444 |
|
| 6445 | sta->reserved_tid = tid;
|
| 6446 |
|
| 6447 | ieee80211_wake_vif_queues(local, sdata,
|
| 6448 | IEEE80211_QUEUE_STOP_REASON_RESERVE_TID);
|
| 6449 |
|
| 6450 | if (ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION))
|
| 6451 | clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
| 6452 |
|
| 6453 | ret = 0;
|
| 6454 | out:
|
| 6455 | return ret;
|
| 6456 | }
|
| 6457 | EXPORT_SYMBOL(ieee80211_reserve_tid);
|
| 6458 |
|
| 6459 | void ieee80211_unreserve_tid(struct ieee80211_sta *pubsta, u8 tid)
|
| 6460 | {
|
| 6461 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
|
| 6462 | struct ieee80211_sub_if_data *sdata = sta->sdata;
|
| 6463 |
|
| 6464 | lockdep_assert_wiphy(sdata->local->hw.wiphy);
|
| 6465 |
|
| 6466 |
|
| 6467 | switch (sdata->vif.type) {
|
| 6468 | case NL80211_IFTYPE_STATION:
|
| 6469 | case NL80211_IFTYPE_AP:
|
| 6470 | case NL80211_IFTYPE_AP_VLAN:
|
| 6471 | break;
|
| 6472 | default:
|
| 6473 | WARN_ON(1);
|
| 6474 | return;
|
| 6475 | }
|
| 6476 |
|
| 6477 | if (tid != sta->reserved_tid) {
|
| 6478 | sdata_err(sdata, "TID to unreserve (%d) isn't reserved\n", tid);
|
| 6479 | return;
|
| 6480 | }
|
| 6481 |
|
| 6482 | sta->reserved_tid = IEEE80211_TID_UNRESERVED;
|
| 6483 | }
|
| 6484 | EXPORT_SYMBOL(ieee80211_unreserve_tid);
|
| 6485 |
|
| 6486 | void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
|
| 6487 | struct sk_buff *skb, int tid, int link_id,
|
| 6488 | enum nl80211_band band)
|
| 6489 | {
|
| 6490 | const struct ieee80211_hdr *hdr = (void *)skb->data;
|
| 6491 | int ac = ieee80211_ac_from_tid(tid);
|
| 6492 | unsigned int link;
|
| 6493 |
|
| 6494 | skb_reset_mac_header(skb);
|
| 6495 | skb_set_queue_mapping(skb, ac);
|
| 6496 | skb->priority = tid;
|
| 6497 |
|
| 6498 | skb->dev = sdata->dev;
|
| 6499 |
|
| 6500 | BUILD_BUG_ON(IEEE80211_LINK_UNSPECIFIED < IEEE80211_MLD_MAX_NUM_LINKS);
|
| 6501 | BUILD_BUG_ON(!FIELD_FIT(IEEE80211_TX_CTRL_MLO_LINK,
|
| 6502 | IEEE80211_LINK_UNSPECIFIED));
|
| 6503 |
|
| 6504 | if (!ieee80211_vif_is_mld(&sdata->vif)) {
|
| 6505 | link = 0;
|
| 6506 | } else if (link_id >= 0) {
|
| 6507 | link = link_id;
|
| 6508 | } else if (memcmp(sdata->vif.addr, hdr->addr2, ETH_ALEN) == 0) {
|
| 6509 |
|
| 6510 | link = IEEE80211_LINK_UNSPECIFIED;
|
| 6511 | } else {
|
| 6512 |
|
| 6513 | rcu_read_lock();
|
| 6514 | for (link = 0; link < ARRAY_SIZE(sdata->vif.link_conf); link++) {
|
| 6515 | struct ieee80211_bss_conf *link_conf;
|
| 6516 |
|
| 6517 | link_conf = rcu_dereference(sdata->vif.link_conf[link]);
|
| 6518 | if (!link_conf)
|
| 6519 | continue;
|
| 6520 | if (memcmp(link_conf->addr, hdr->addr2, ETH_ALEN) == 0)
|
| 6521 | break;
|
| 6522 | }
|
| 6523 | rcu_read_unlock();
|
| 6524 |
|
| 6525 | if (WARN_ON_ONCE(link == ARRAY_SIZE(sdata->vif.link_conf)))
|
| 6526 | link = ffs(sdata->vif.active_links) - 1;
|
| 6527 | }
|
| 6528 |
|
| 6529 | IEEE80211_SKB_CB(skb)->control.flags |=
|
| 6530 | u32_encode_bits(link, IEEE80211_TX_CTRL_MLO_LINK);
|
| 6531 |
|
| 6532 | |
| 6533 | * The other path calling ieee80211_xmit is from the tasklet,
|
| 6534 | * and while we can handle concurrent transmissions locking
|
| 6535 | * requirements are that we do not come into tx with bhs on.
|
| 6536 |
|
| 6537 | local_bh_disable();
|
| 6538 | IEEE80211_SKB_CB(skb)->band = band;
|
| 6539 | ieee80211_xmit(sdata, NULL, skb);
|
| 6540 | local_bh_enable();
|
| 6541 | }
|
| 6542 |
|
| 6543 | void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
|
| 6544 | struct sk_buff *skb, int tid, int link_id)
|
| 6545 | {
|
| 6546 | struct ieee80211_chanctx_conf *chanctx_conf;
|
| 6547 | enum nl80211_band band;
|
| 6548 |
|
| 6549 | rcu_read_lock();
|
| 6550 | if (sdata->vif.type == NL80211_IFTYPE_NAN ||
|
| 6551 | sdata->vif.type == NL80211_IFTYPE_NAN_DATA) {
|
| 6552 | band = NUM_NL80211_BANDS;
|
| 6553 | } else if (!ieee80211_vif_is_mld(&sdata->vif)) {
|
| 6554 | WARN_ON(link_id >= 0);
|
| 6555 | chanctx_conf =
|
| 6556 | rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
|
| 6557 | if (WARN_ON(!chanctx_conf)) {
|
| 6558 | rcu_read_unlock();
|
| 6559 | kfree_skb(skb);
|
| 6560 | return;
|
| 6561 | }
|
| 6562 | band = chanctx_conf->def.chan->band;
|
| 6563 | } else {
|
| 6564 | WARN_ON(link_id >= 0 &&
|
| 6565 | !(sdata->vif.active_links & BIT(link_id)));
|
| 6566 |
|
| 6567 | band = 0;
|
| 6568 | }
|
| 6569 |
|
| 6570 | __ieee80211_tx_skb_tid_band(sdata, skb, tid, link_id, band);
|
| 6571 | rcu_read_unlock();
|
| 6572 | }
|
| 6573 |
|
| 6574 | int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
| 6575 | const u8 *buf, size_t len,
|
| 6576 | const u8 *dest, __be16 proto, bool unencrypted,
|
| 6577 | int link_id, u64 cookie)
|
| 6578 | {
|
| 6579 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
| 6580 | struct ieee80211_local *local = sdata->local;
|
| 6581 | struct sta_info *sta;
|
| 6582 | struct sk_buff *skb;
|
| 6583 | struct ethhdr *ehdr;
|
| 6584 | u32 ctrl_flags = 0;
|
| 6585 | u32 flags = 0;
|
| 6586 | int err;
|
| 6587 |
|
| 6588 |
|
| 6589 | lockdep_assert_wiphy(local->hw.wiphy);
|
| 6590 |
|
| 6591 | |
| 6592 | * or Pre-Authentication
|
| 6593 |
|
| 6594 | if (proto != sdata->control_port_protocol &&
|
| 6595 | proto != cpu_to_be16(ETH_P_PREAUTH))
|
| 6596 | return -EINVAL;
|
| 6597 |
|
| 6598 | if (proto == sdata->control_port_protocol)
|
| 6599 | ctrl_flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO |
|
| 6600 | IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP;
|
| 6601 |
|
| 6602 | if (unencrypted)
|
| 6603 | flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
| 6604 |
|
| 6605 | if (cookie)
|
| 6606 | ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
| 6607 |
|
| 6608 | flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX;
|
| 6609 |
|
| 6610 | skb = dev_alloc_skb(local->hw.extra_tx_headroom +
|
| 6611 | sizeof(struct ethhdr) + len);
|
| 6612 | if (!skb)
|
| 6613 | return -ENOMEM;
|
| 6614 |
|
| 6615 | skb_reserve(skb, local->hw.extra_tx_headroom + sizeof(struct ethhdr));
|
| 6616 |
|
| 6617 | skb_put_data(skb, buf, len);
|
| 6618 |
|
| 6619 | ehdr = skb_push(skb, sizeof(struct ethhdr));
|
| 6620 | memcpy(ehdr->h_dest, dest, ETH_ALEN);
|
| 6621 |
|
| 6622 |
|
| 6623 | if (link_id < 0) {
|
| 6624 | ctrl_flags |= u32_encode_bits(IEEE80211_LINK_UNSPECIFIED,
|
| 6625 | IEEE80211_TX_CTRL_MLO_LINK);
|
| 6626 | memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN);
|
| 6627 | } else {
|
| 6628 | struct ieee80211_bss_conf *link_conf;
|
| 6629 |
|
| 6630 | ctrl_flags |= u32_encode_bits(link_id,
|
| 6631 | IEEE80211_TX_CTRL_MLO_LINK);
|
| 6632 |
|
| 6633 | rcu_read_lock();
|
| 6634 | link_conf = rcu_dereference(sdata->vif.link_conf[link_id]);
|
| 6635 | if (!link_conf) {
|
| 6636 | dev_kfree_skb(skb);
|
| 6637 | rcu_read_unlock();
|
| 6638 | return -ENOLINK;
|
| 6639 | }
|
| 6640 | memcpy(ehdr->h_source, link_conf->addr, ETH_ALEN);
|
| 6641 | rcu_read_unlock();
|
| 6642 | }
|
| 6643 |
|
| 6644 | ehdr->h_proto = proto;
|
| 6645 |
|
| 6646 | skb->dev = dev;
|
| 6647 | skb->protocol = proto;
|
| 6648 | skb_reset_network_header(skb);
|
| 6649 | skb_reset_mac_header(skb);
|
| 6650 |
|
| 6651 | if (local->hw.queues < IEEE80211_NUM_ACS)
|
| 6652 | goto start_xmit;
|
| 6653 |
|
| 6654 | |
| 6655 | * prioritization also happens for control port frames send over
|
| 6656 | * AF_PACKET
|
| 6657 |
|
| 6658 | rcu_read_lock();
|
| 6659 | err = ieee80211_lookup_ra_sta(sdata, skb, &sta, true);
|
| 6660 | if (err) {
|
| 6661 | dev_kfree_skb(skb);
|
| 6662 | rcu_read_unlock();
|
| 6663 | return err;
|
| 6664 | }
|
| 6665 |
|
| 6666 | if (!IS_ERR(sta)) {
|
| 6667 | u16 queue = ieee80211_select_queue(sdata, sta, skb);
|
| 6668 |
|
| 6669 | skb_set_queue_mapping(skb, queue);
|
| 6670 |
|
| 6671 | |
| 6672 | * for MLO STA, the SA should be the AP MLD address, but
|
| 6673 | * the link ID has been selected already
|
| 6674 |
|
| 6675 | if (sta && sta->sta.mlo)
|
| 6676 | memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN);
|
| 6677 | }
|
| 6678 | rcu_read_unlock();
|
| 6679 |
|
| 6680 | start_xmit:
|
| 6681 | local_bh_disable();
|
| 6682 | __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie);
|
| 6683 | local_bh_enable();
|
| 6684 |
|
| 6685 | return 0;
|
| 6686 | }
|
| 6687 |
|
| 6688 | int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
|
| 6689 | const u8 *buf, size_t len)
|
| 6690 | {
|
| 6691 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
| 6692 | struct ieee80211_local *local = sdata->local;
|
| 6693 | struct sk_buff *skb;
|
| 6694 |
|
| 6695 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + len +
|
| 6696 | 30 +
|
| 6697 | 18);
|
| 6698 | if (!skb)
|
| 6699 | return -ENOMEM;
|
| 6700 |
|
| 6701 | skb_reserve(skb, local->hw.extra_tx_headroom);
|
| 6702 | skb_put_data(skb, buf, len);
|
| 6703 |
|
| 6704 | skb->dev = dev;
|
| 6705 | skb->protocol = htons(ETH_P_802_3);
|
| 6706 | skb_reset_network_header(skb);
|
| 6707 | skb_reset_mac_header(skb);
|
| 6708 |
|
| 6709 | local_bh_disable();
|
| 6710 | __ieee80211_subif_start_xmit(skb, skb->dev, 0,
|
| 6711 | IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP,
|
| 6712 | 0);
|
| 6713 | local_bh_enable();
|
| 6714 |
|
| 6715 | return 0;
|
| 6716 | }
|