| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Common code for mac80211 Prism54 drivers |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 10 | 11 | * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al. |
|---|
| 11 | 12 | * - stlc45xx driver |
|---|
| 12 | 13 | * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|---|
| 13 | | - * |
|---|
| 14 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 15 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 16 | | - * published by the Free Software Foundation. |
|---|
| 17 | 14 | */ |
|---|
| 18 | 15 | |
|---|
| 19 | 16 | #include <linux/export.h> |
|---|
| .. | .. |
|---|
| 121 | 118 | } |
|---|
| 122 | 119 | if (unlikely(!target_skb)) { |
|---|
| 123 | 120 | if (priv->rx_end - last_addr >= len) { |
|---|
| 124 | | - target_skb = priv->tx_queue.prev; |
|---|
| 125 | | - if (!skb_queue_empty(&priv->tx_queue)) { |
|---|
| 121 | + target_skb = skb_peek_tail(&priv->tx_queue); |
|---|
| 122 | + if (target_skb) { |
|---|
| 126 | 123 | info = IEEE80211_SKB_CB(target_skb); |
|---|
| 127 | 124 | range = (void *)info->rate_driver_data; |
|---|
| 128 | 125 | target_addr = range->end_addr; |
|---|
| .. | .. |
|---|
| 142 | 139 | unlikely(GET_HW_QUEUE(skb) == P54_QUEUE_BEACON)) |
|---|
| 143 | 140 | priv->beacon_req_id = data->req_id; |
|---|
| 144 | 141 | |
|---|
| 145 | | - __skb_queue_after(&priv->tx_queue, target_skb, skb); |
|---|
| 142 | + if (target_skb) |
|---|
| 143 | + __skb_queue_after(&priv->tx_queue, target_skb, skb); |
|---|
| 144 | + else |
|---|
| 145 | + __skb_queue_head(&priv->tx_queue, skb); |
|---|
| 146 | 146 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); |
|---|
| 147 | 147 | return 0; |
|---|
| 148 | 148 | } |
|---|
| .. | .. |
|---|
| 331 | 331 | u16 freq = le16_to_cpu(hdr->freq); |
|---|
| 332 | 332 | size_t header_len = sizeof(*hdr); |
|---|
| 333 | 333 | u32 tsf32; |
|---|
| 334 | + __le16 fc; |
|---|
| 334 | 335 | u8 rate = hdr->rate & 0xf; |
|---|
| 335 | 336 | |
|---|
| 336 | 337 | /* |
|---|
| .. | .. |
|---|
| 379 | 380 | |
|---|
| 380 | 381 | skb_pull(skb, header_len); |
|---|
| 381 | 382 | skb_trim(skb, le16_to_cpu(hdr->len)); |
|---|
| 383 | + |
|---|
| 384 | + fc = ((struct ieee80211_hdr *)skb->data)->frame_control; |
|---|
| 385 | + if (ieee80211_is_probe_resp(fc) || ieee80211_is_beacon(fc)) |
|---|
| 386 | + rx_status->boottime_ns = ktime_get_boottime_ns(); |
|---|
| 387 | + |
|---|
| 382 | 388 | if (unlikely(priv->hw->conf.flags & IEEE80211_CONF_PS)) |
|---|
| 383 | 389 | p54_pspoll_workaround(priv, skb); |
|---|
| 384 | 390 | |
|---|