mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
wireless fixes for v6.12-rc5
The first set of wireless fixes for v6.12. We have been busy and have not been able to send this earlier, so there are more fixes than usual. The fixes are all over, both in stack and in drivers, but nothing special really standing out. -----BEGIN PGP SIGNATURE----- iQFFBAABCgAvFiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmcWl7MRHGt2YWxvQGtl cm5lbC5vcmcACgkQbhckVSbrbZv0Qgf/fQJKXkGJkvozrbJATkKHfHKUOphIl4Y8 /r3SlrsIL6qXZAUq5N+NH9vfUeKt5kkKG8Fc8yrJaygDLsV9v1LGiBSsb5eJ+PfM 4fCOdzPSrWG984dLwsCK8UGEzfQ1G4d6HckwubUMimK2X/m6wx/99fenjMAQvdWO rjAJmpAkgoT0Fvf8GD3joMBKKjMFr2KT8tgbfvwpyr9cXAPZYf35+74Nl84UjHiP rGTGN++NQuPMsYyYIPPA+eMNUnlUVyDah+UVmzsMp27YUdKBKjx23kRH6tKM/46H dWqpqEV50xshlPaotHoFg9+4KRrxnxwvFtGTsnbvHcuSnkPBUusAvw== =l6SI -----END PGP SIGNATURE----- Merge tag 'wireless-2024-10-21' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless wireless fixes for v6.12-rc5 The first set of wireless fixes for v6.12. We have been busy and have not been able to send this earlier, so there are more fixes than usual. The fixes are all over, both in stack and in drivers, but nothing special really standing out.
This commit is contained in:
commit
e31a8219fb
@ -3043,9 +3043,14 @@ ath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar,
|
||||
struct sk_buff *msdu)
|
||||
{
|
||||
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
|
||||
struct ath10k_mgmt_tx_pkt_addr *pkt_addr;
|
||||
struct ath10k_wmi *wmi = &ar->wmi;
|
||||
|
||||
idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id);
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
pkt_addr = idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
kfree(pkt_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2441,6 +2441,7 @@ wmi_process_mgmt_tx_comp(struct ath10k *ar, struct mgmt_tx_compl_params *param)
|
||||
dma_unmap_single(ar->dev, pkt_addr->paddr,
|
||||
msdu->len, DMA_TO_DEVICE);
|
||||
info = IEEE80211_SKB_CB(msdu);
|
||||
kfree(pkt_addr);
|
||||
|
||||
if (param->status) {
|
||||
info->flags &= ~IEEE80211_TX_STAT_ACK;
|
||||
@ -9612,6 +9613,7 @@ static int ath10k_wmi_mgmt_tx_clean_up_pending(int msdu_id, void *ptr,
|
||||
dma_unmap_single(ar->dev, pkt_addr->paddr,
|
||||
msdu->len, DMA_TO_DEVICE);
|
||||
ieee80211_free_txskb(ar->hw, msdu);
|
||||
kfree(pkt_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -5291,8 +5291,11 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
|
||||
hal_status == HAL_TLV_STATUS_PPDU_DONE) {
|
||||
rx_mon_stats->status_ppdu_done++;
|
||||
pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE;
|
||||
ath11k_dp_rx_mon_dest_process(ar, mac_id, budget, napi);
|
||||
pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
|
||||
if (!ab->hw_params.full_monitor_mode) {
|
||||
ath11k_dp_rx_mon_dest_process(ar, mac_id,
|
||||
budget, napi);
|
||||
pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
|
||||
}
|
||||
}
|
||||
|
||||
if (ppdu_info->peer_id == HAL_INVALID_PEERID ||
|
||||
|
@ -306,7 +306,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct wil6210_rtap {
|
||||
struct ieee80211_radiotap_header rthdr;
|
||||
struct ieee80211_radiotap_header_fixed rthdr;
|
||||
/* fields should be in the order of bits in rthdr.it_present */
|
||||
/* flags */
|
||||
u8 flags;
|
||||
|
@ -27,6 +27,7 @@ source "drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig"
|
||||
config BRCM_TRACING
|
||||
bool "Broadcom device tracing"
|
||||
depends on BRCMSMAC || BRCMFMAC
|
||||
depends on TRACING
|
||||
help
|
||||
If you say Y here, the Broadcom wireless drivers will register
|
||||
with ftrace to dump event information into the trace ringbuffer.
|
||||
|
@ -2518,7 +2518,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
|
||||
* to build this manually element by element, we can write it much
|
||||
* more efficiently than we can parse it. ORDER MATTERS HERE */
|
||||
struct ipw_rt_hdr {
|
||||
struct ieee80211_radiotap_header rt_hdr;
|
||||
struct ieee80211_radiotap_header_fixed rt_hdr;
|
||||
s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
|
||||
} *ipw_rt;
|
||||
|
||||
|
@ -1143,7 +1143,7 @@ struct ipw_prom_priv {
|
||||
* structure is provided regardless of any bits unset.
|
||||
*/
|
||||
struct ipw_rt_hdr {
|
||||
struct ieee80211_radiotap_header rt_hdr;
|
||||
struct ieee80211_radiotap_header_fixed rt_hdr;
|
||||
u64 rt_tsf; /* TSF */ /* XXX */
|
||||
u8 rt_flags; /* radiotap packet flags */
|
||||
u8 rt_rate; /* rate in 500kb/s */
|
||||
|
@ -3122,6 +3122,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
|
||||
struct il_cmd_meta *out_meta;
|
||||
dma_addr_t phys_addr;
|
||||
unsigned long flags;
|
||||
u8 *out_payload;
|
||||
u32 idx;
|
||||
u16 fix_size;
|
||||
|
||||
@ -3157,6 +3158,16 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
|
||||
out_cmd = txq->cmd[idx];
|
||||
out_meta = &txq->meta[idx];
|
||||
|
||||
/* The payload is in the same place in regular and huge
|
||||
* command buffers, but we need to let the compiler know when
|
||||
* we're using a larger payload buffer to avoid "field-
|
||||
* spanning write" warnings at run-time for huge commands.
|
||||
*/
|
||||
if (cmd->flags & CMD_SIZE_HUGE)
|
||||
out_payload = ((struct il_device_cmd_huge *)out_cmd)->cmd.payload;
|
||||
else
|
||||
out_payload = out_cmd->cmd.payload;
|
||||
|
||||
if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
|
||||
spin_unlock_irqrestore(&il->hcmd_lock, flags);
|
||||
return -ENOSPC;
|
||||
@ -3170,7 +3181,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
|
||||
out_meta->callback = cmd->callback;
|
||||
|
||||
out_cmd->hdr.cmd = cmd->id;
|
||||
memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
|
||||
memcpy(out_payload, cmd->data, cmd->len);
|
||||
|
||||
/* At this point, the out_cmd now has all of the incoming cmd
|
||||
* information */
|
||||
@ -4962,6 +4973,8 @@ il_pci_resume(struct device *device)
|
||||
*/
|
||||
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
|
||||
|
||||
_il_wr(il, CSR_INT, 0xffffffff);
|
||||
_il_wr(il, CSR_FH_INT_STATUS, 0xffffffff);
|
||||
il_enable_interrupts(il);
|
||||
|
||||
if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
|
||||
|
@ -560,6 +560,18 @@ struct il_device_cmd {
|
||||
|
||||
#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct il_device_cmd))
|
||||
|
||||
/**
|
||||
* struct il_device_cmd_huge
|
||||
*
|
||||
* For use when sending huge commands.
|
||||
*/
|
||||
struct il_device_cmd_huge {
|
||||
struct il_cmd_header hdr; /* uCode API */
|
||||
union {
|
||||
u8 payload[IL_MAX_CMD_SIZE - sizeof(struct il_cmd_header)];
|
||||
} __packed cmd;
|
||||
} __packed;
|
||||
|
||||
struct il_host_cmd {
|
||||
const void *data;
|
||||
unsigned long reply_page;
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
|
||||
struct tx_radiotap_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
u8 rate;
|
||||
u8 txpower;
|
||||
u8 rts_retries;
|
||||
@ -31,7 +31,7 @@ struct tx_radiotap_hdr {
|
||||
#define IEEE80211_FC_DSTODS 0x0300
|
||||
|
||||
struct rx_radiotap_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
u8 flags;
|
||||
u8 rate;
|
||||
u8 antsignal;
|
||||
|
@ -84,13 +84,16 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
|
||||
mutex_lock(&dev->mcu.mutex);
|
||||
|
||||
if (dev->mcu_ops->mcu_skb_prepare_msg) {
|
||||
orig_skb = skb;
|
||||
ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
retry:
|
||||
orig_skb = skb_get(skb);
|
||||
/* orig skb might be needed for retry, mcu_skb_send_msg consumes it */
|
||||
if (orig_skb)
|
||||
skb_get(orig_skb);
|
||||
ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@ -105,7 +108,7 @@ retry:
|
||||
do {
|
||||
skb = mt76_mcu_get_response(dev, expires);
|
||||
if (!skb && !test_bit(MT76_MCU_RESET, &dev->phy.state) &&
|
||||
retry++ < dev->mcu_ops->max_retry) {
|
||||
orig_skb && retry++ < dev->mcu_ops->max_retry) {
|
||||
dev_err(dev->dev, "Retry message %08x (seq %d)\n",
|
||||
cmd, seq);
|
||||
skb = orig_skb;
|
||||
|
@ -7,12 +7,12 @@
|
||||
#include "cfg80211.h"
|
||||
|
||||
struct wilc_wfi_radiotap_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
u8 rate;
|
||||
} __packed;
|
||||
|
||||
struct wilc_wfi_radiotap_cb_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
u8 rate;
|
||||
u8 dump;
|
||||
u16 tx_flags;
|
||||
|
@ -352,7 +352,6 @@ static const struct usb_device_id rtl8192d_usb_ids[] = {
|
||||
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8194, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8111, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x0193, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8171, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0xe194, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(0x2019, 0xab2c, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(0x2019, 0xab2d, rtl92du_hal_cfg)},
|
||||
|
@ -771,7 +771,6 @@ static void rtw_usb_dynamic_rx_agg_v1(struct rtw_dev *rtwdev, bool enable)
|
||||
u8 size, timeout;
|
||||
u16 val16;
|
||||
|
||||
rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC);
|
||||
rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN);
|
||||
rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7));
|
||||
|
||||
|
@ -6445,6 +6445,8 @@ static void _update_wl_info_v7(struct rtw89_dev *rtwdev, u8 rid)
|
||||
|
||||
/* todo DBCC related event */
|
||||
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] wl_info phy_now=%d\n", phy_now);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_BTC,
|
||||
"[BTC] rlink cnt_2g=%d cnt_5g=%d\n", cnt_2g, cnt_5g);
|
||||
|
||||
if (wl_rinfo->dbcc_en != rtwdev->dbcc_en) {
|
||||
wl_rinfo->dbcc_chg = 1;
|
||||
|
@ -3026,23 +3026,53 @@ static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev,
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
|
||||
static bool rtw89_pci_chip_is_manual_dac(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
|
||||
if (!rtwpci->enable_dac)
|
||||
return;
|
||||
|
||||
switch (chip->chip_id) {
|
||||
case RTL8852A:
|
||||
case RTL8852B:
|
||||
case RTL8851B:
|
||||
case RTL8852BT:
|
||||
break;
|
||||
return true;
|
||||
default:
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rtw89_pci_is_dac_compatible_bridge(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
|
||||
struct pci_dev *bridge = pci_upstream_bridge(rtwpci->pdev);
|
||||
|
||||
if (!rtw89_pci_chip_is_manual_dac(rtwdev))
|
||||
return true;
|
||||
|
||||
if (!bridge)
|
||||
return false;
|
||||
|
||||
switch (bridge->vendor) {
|
||||
case PCI_VENDOR_ID_INTEL:
|
||||
return true;
|
||||
case PCI_VENDOR_ID_ASMEDIA:
|
||||
if (bridge->device == 0x2806)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
|
||||
|
||||
if (!rtwpci->enable_dac)
|
||||
return;
|
||||
|
||||
if (!rtw89_pci_chip_is_manual_dac(rtwdev))
|
||||
return;
|
||||
|
||||
rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, RTW89_PCIE_BIT_EN_64BITS);
|
||||
}
|
||||
@ -3061,6 +3091,9 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!rtw89_pci_is_dac_compatible_bridge(rtwdev))
|
||||
goto no_dac;
|
||||
|
||||
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
|
||||
if (!ret) {
|
||||
rtwpci->enable_dac = true;
|
||||
@ -3073,6 +3106,7 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
|
||||
goto err_release_regions;
|
||||
}
|
||||
}
|
||||
no_dac:
|
||||
|
||||
resource_len = pci_resource_len(pdev, bar_id);
|
||||
rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len);
|
||||
|
@ -763,7 +763,7 @@ static const struct rhashtable_params hwsim_rht_params = {
|
||||
};
|
||||
|
||||
struct hwsim_radiotap_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
__le64 rt_tsft;
|
||||
u8 rt_flags;
|
||||
u8 rt_rate;
|
||||
@ -772,7 +772,7 @@ struct hwsim_radiotap_hdr {
|
||||
} __packed;
|
||||
|
||||
struct hwsim_radiotap_ack_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
u8 rt_flags;
|
||||
u8 pad;
|
||||
__le16 rt_channel;
|
||||
|
@ -6129,6 +6129,50 @@ void wiphy_delayed_work_cancel(struct wiphy *wiphy,
|
||||
void wiphy_delayed_work_flush(struct wiphy *wiphy,
|
||||
struct wiphy_delayed_work *dwork);
|
||||
|
||||
/**
|
||||
* wiphy_delayed_work_pending - Find out whether a wiphy delayable
|
||||
* work item is currently pending.
|
||||
*
|
||||
* @wiphy: the wiphy, for debug purposes
|
||||
* @dwork: the delayed work in question
|
||||
*
|
||||
* Return: true if timer is pending, false otherwise
|
||||
*
|
||||
* How wiphy_delayed_work_queue() works is by setting a timer which
|
||||
* when it expires calls wiphy_work_queue() to queue the wiphy work.
|
||||
* Because wiphy_delayed_work_queue() uses mod_timer(), if it is
|
||||
* called twice and the second call happens before the first call
|
||||
* deadline, the work will rescheduled for the second deadline and
|
||||
* won't run before that.
|
||||
*
|
||||
* wiphy_delayed_work_pending() can be used to detect if calling
|
||||
* wiphy_work_delayed_work_queue() would start a new work schedule
|
||||
* or delayed a previous one. As seen below it cannot be used to
|
||||
* detect precisely if the work has finished to execute nor if it
|
||||
* is currently executing.
|
||||
*
|
||||
* CPU0 CPU1
|
||||
* wiphy_delayed_work_queue(wk)
|
||||
* mod_timer(wk->timer)
|
||||
* wiphy_delayed_work_pending(wk) -> true
|
||||
*
|
||||
* [...]
|
||||
* expire_timers(wk->timer)
|
||||
* detach_timer(wk->timer)
|
||||
* wiphy_delayed_work_pending(wk) -> false
|
||||
* wk->timer->function() |
|
||||
* wiphy_work_queue(wk) | delayed work pending
|
||||
* list_add_tail() | returns false but
|
||||
* queue_work(cfg80211_wiphy_work) | wk->func() has not
|
||||
* | been run yet
|
||||
* [...] |
|
||||
* cfg80211_wiphy_work() |
|
||||
* wk->func() V
|
||||
*
|
||||
*/
|
||||
bool wiphy_delayed_work_pending(struct wiphy *wiphy,
|
||||
struct wiphy_delayed_work *dwork);
|
||||
|
||||
/**
|
||||
* enum ieee80211_ap_reg_power - regulatory power for an Access Point
|
||||
*
|
||||
|
@ -24,25 +24,27 @@
|
||||
* struct ieee80211_radiotap_header - base radiotap header
|
||||
*/
|
||||
struct ieee80211_radiotap_header {
|
||||
/**
|
||||
* @it_version: radiotap version, always 0
|
||||
*/
|
||||
uint8_t it_version;
|
||||
__struct_group(ieee80211_radiotap_header_fixed, hdr, __packed,
|
||||
/**
|
||||
* @it_version: radiotap version, always 0
|
||||
*/
|
||||
uint8_t it_version;
|
||||
|
||||
/**
|
||||
* @it_pad: padding (or alignment)
|
||||
*/
|
||||
uint8_t it_pad;
|
||||
/**
|
||||
* @it_pad: padding (or alignment)
|
||||
*/
|
||||
uint8_t it_pad;
|
||||
|
||||
/**
|
||||
* @it_len: overall radiotap header length
|
||||
*/
|
||||
__le16 it_len;
|
||||
/**
|
||||
* @it_len: overall radiotap header length
|
||||
*/
|
||||
__le16 it_len;
|
||||
|
||||
/**
|
||||
* @it_present: (first) present word
|
||||
*/
|
||||
__le32 it_present;
|
||||
/**
|
||||
* @it_present: (first) present word
|
||||
*/
|
||||
__le32 it_present;
|
||||
);
|
||||
|
||||
/**
|
||||
* @it_optional: all remaining presence bitmaps
|
||||
@ -50,6 +52,9 @@ struct ieee80211_radiotap_header {
|
||||
__le32 it_optional[];
|
||||
} __packed;
|
||||
|
||||
static_assert(offsetof(struct ieee80211_radiotap_header, it_optional) == sizeof(struct ieee80211_radiotap_header_fixed),
|
||||
"struct member likely outside of __struct_group()");
|
||||
|
||||
/* version is always 0 */
|
||||
#define PKTHDR_RADIOTAP_VERSION 0
|
||||
|
||||
|
@ -96,7 +96,7 @@ config MAC80211_DEBUGFS
|
||||
|
||||
config MAC80211_MESSAGE_TRACING
|
||||
bool "Trace all mac80211 debug messages"
|
||||
depends on MAC80211
|
||||
depends on MAC80211 && TRACING
|
||||
help
|
||||
Select this option to have mac80211 register the
|
||||
mac80211_msg trace subsystem with tracepoints to
|
||||
|
@ -3046,6 +3046,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
|
||||
enum nl80211_tx_power_setting txp_type = type;
|
||||
bool update_txp_type = false;
|
||||
bool has_monitor = false;
|
||||
int old_power = local->user_power_level;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
@ -3128,6 +3129,10 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
|
||||
}
|
||||
}
|
||||
|
||||
if (local->emulate_chanctx &&
|
||||
(old_power != local->user_power_level))
|
||||
ieee80211_hw_conf_chan(local);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3138,7 +3143,8 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy,
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
|
||||
if (local->ops->get_txpower)
|
||||
if (local->ops->get_txpower &&
|
||||
(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
|
||||
return drv_get_txpower(local, sdata, dbm);
|
||||
|
||||
if (local->emulate_chanctx)
|
||||
@ -4826,12 +4832,12 @@ void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
|
||||
ieee80211_color_change_finalize(link);
|
||||
}
|
||||
|
||||
void ieee80211_color_collision_detection_work(struct work_struct *work)
|
||||
void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work)
|
||||
{
|
||||
struct delayed_work *delayed_work = to_delayed_work(work);
|
||||
struct ieee80211_link_data *link =
|
||||
container_of(delayed_work, struct ieee80211_link_data,
|
||||
color_collision_detect_work);
|
||||
container_of(work, struct ieee80211_link_data,
|
||||
color_collision_detect_work.work);
|
||||
struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
|
||||
cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap,
|
||||
@ -4884,7 +4890,8 @@ ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
return;
|
||||
}
|
||||
|
||||
if (delayed_work_pending(&link->color_collision_detect_work)) {
|
||||
if (wiphy_delayed_work_pending(sdata->local->hw.wiphy,
|
||||
&link->color_collision_detect_work)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
@ -4893,9 +4900,9 @@ ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
/* queue the color collision detection event every 500 ms in order to
|
||||
* avoid sending too much netlink messages to userspace.
|
||||
*/
|
||||
ieee80211_queue_delayed_work(&sdata->local->hw,
|
||||
&link->color_collision_detect_work,
|
||||
msecs_to_jiffies(500));
|
||||
wiphy_delayed_work_queue(sdata->local->hw.wiphy,
|
||||
&link->color_collision_detect_work,
|
||||
msecs_to_jiffies(500));
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
@ -1053,7 +1053,7 @@ struct ieee80211_link_data {
|
||||
} csa;
|
||||
|
||||
struct wiphy_work color_change_finalize_work;
|
||||
struct delayed_work color_collision_detect_work;
|
||||
struct wiphy_delayed_work color_collision_detect_work;
|
||||
u64 color_bitmap;
|
||||
|
||||
/* context reservation -- protected with wiphy mutex */
|
||||
@ -2005,7 +2005,8 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
/* color change handling */
|
||||
void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work);
|
||||
void ieee80211_color_collision_detection_work(struct work_struct *work);
|
||||
void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work);
|
||||
|
||||
/* interface handling */
|
||||
#define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
|
||||
|
@ -987,6 +987,26 @@ void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ieee80211_key_iter(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_key *key,
|
||||
void (*iter)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
void *data),
|
||||
void *iter_data)
|
||||
{
|
||||
/* skip keys of station in removal process */
|
||||
if (key->sta && key->sta->removed)
|
||||
return;
|
||||
if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
||||
return;
|
||||
iter(hw, vif, key->sta ? &key->sta->sta : NULL,
|
||||
&key->conf, iter_data);
|
||||
}
|
||||
|
||||
void ieee80211_iter_keys(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
void (*iter)(struct ieee80211_hw *hw,
|
||||
@ -1005,16 +1025,13 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw,
|
||||
if (vif) {
|
||||
sdata = vif_to_sdata(vif);
|
||||
list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
|
||||
iter(hw, &sdata->vif,
|
||||
key->sta ? &key->sta->sta : NULL,
|
||||
&key->conf, iter_data);
|
||||
ieee80211_key_iter(hw, vif, key, iter, iter_data);
|
||||
} else {
|
||||
list_for_each_entry(sdata, &local->interfaces, list)
|
||||
list_for_each_entry_safe(key, tmp,
|
||||
&sdata->key_list, list)
|
||||
iter(hw, &sdata->vif,
|
||||
key->sta ? &key->sta->sta : NULL,
|
||||
&key->conf, iter_data);
|
||||
ieee80211_key_iter(hw, &sdata->vif, key,
|
||||
iter, iter_data);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_iter_keys);
|
||||
@ -1031,17 +1048,8 @@ _ieee80211_iter_keys_rcu(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct ieee80211_key *key;
|
||||
|
||||
list_for_each_entry_rcu(key, &sdata->key_list, list) {
|
||||
/* skip keys of station in removal process */
|
||||
if (key->sta && key->sta->removed)
|
||||
continue;
|
||||
if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
||||
continue;
|
||||
|
||||
iter(hw, &sdata->vif,
|
||||
key->sta ? &key->sta->sta : NULL,
|
||||
&key->conf, iter_data);
|
||||
}
|
||||
list_for_each_entry_rcu(key, &sdata->key_list, list)
|
||||
ieee80211_key_iter(hw, &sdata->vif, key, iter, iter_data);
|
||||
}
|
||||
|
||||
void ieee80211_iter_keys_rcu(struct ieee80211_hw *hw,
|
||||
|
@ -41,8 +41,8 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_csa_finalize_work);
|
||||
wiphy_work_init(&link->color_change_finalize_work,
|
||||
ieee80211_color_change_finalize_work);
|
||||
INIT_DELAYED_WORK(&link->color_collision_detect_work,
|
||||
ieee80211_color_collision_detection_work);
|
||||
wiphy_delayed_work_init(&link->color_collision_detect_work,
|
||||
ieee80211_color_collision_detection_work);
|
||||
INIT_LIST_HEAD(&link->assigned_chanctx_list);
|
||||
INIT_LIST_HEAD(&link->reserved_chanctx_list);
|
||||
wiphy_delayed_work_init(&link->dfs_cac_timer_work,
|
||||
@ -72,7 +72,8 @@ void ieee80211_link_stop(struct ieee80211_link_data *link)
|
||||
if (link->sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
ieee80211_mgd_stop_link(link);
|
||||
|
||||
cancel_delayed_work_sync(&link->color_collision_detect_work);
|
||||
wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
|
||||
&link->color_collision_detect_work);
|
||||
wiphy_work_cancel(link->sdata->local->hw.wiphy,
|
||||
&link->color_change_finalize_work);
|
||||
wiphy_work_cancel(link->sdata->local->hw.wiphy,
|
||||
|
@ -1704,6 +1704,13 @@ void wiphy_delayed_work_flush(struct wiphy *wiphy,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wiphy_delayed_work_flush);
|
||||
|
||||
bool wiphy_delayed_work_pending(struct wiphy *wiphy,
|
||||
struct wiphy_delayed_work *dwork)
|
||||
{
|
||||
return timer_pending(&dwork->timer);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wiphy_delayed_work_pending);
|
||||
|
||||
static int __init cfg80211_init(void)
|
||||
{
|
||||
int err;
|
||||
|
@ -3050,6 +3050,10 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy,
|
||||
freq = ieee80211_channel_to_freq_khz(ap_info->channel, band);
|
||||
data.channel = ieee80211_get_channel_khz(wiphy, freq);
|
||||
|
||||
/* Skip if RNR element specifies an unsupported channel */
|
||||
if (!data.channel)
|
||||
continue;
|
||||
|
||||
/* Skip if BSS entry generated from MBSSID or DIRECT source
|
||||
* frame data available already.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user