mirror of
https://github.com/torvalds/linux
synced 2024-09-19 18:46:35 +00:00
Merge wireless into wireless-next
There are a number of upcoming things in both the stack and drivers that would otherwise conflict, so merge wireless to wireless-next to be able to avoid those conflicts. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
commit
10f5ae2194
|
@ -651,7 +651,7 @@ struct b43_iv {
|
|||
union {
|
||||
__be16 d16;
|
||||
__be32 d32;
|
||||
} data __packed;
|
||||
} __packed data;
|
||||
} __packed;
|
||||
|
||||
|
||||
|
|
|
@ -379,7 +379,7 @@ struct b43legacy_iv {
|
|||
union {
|
||||
__be16 d16;
|
||||
__be32 d32;
|
||||
} data __packed;
|
||||
} __packed data;
|
||||
} __packed;
|
||||
|
||||
#define B43legacy_PHYMODE(phytype) (1 << (phytype))
|
||||
|
|
|
@ -1039,6 +1039,11 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
|
|||
struct brcmf_sdio_dev *sdiodev;
|
||||
struct brcmf_bus *bus_if;
|
||||
|
||||
if (!id) {
|
||||
dev_err(&func->dev, "Error no sdio_device_id passed for %x:%x\n", func->vendor, func->device);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
brcmf_dbg(SDIO, "Enter\n");
|
||||
brcmf_dbg(SDIO, "Class=%x\n", func->class);
|
||||
brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
|
||||
|
|
|
@ -2394,6 +2394,9 @@ static void brcmf_pcie_debugfs_create(struct device *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Forward declaration for pci_match_id() call */
|
||||
static const struct pci_device_id brcmf_pcie_devid_table[];
|
||||
|
||||
static int
|
||||
brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
|
@ -2404,6 +2407,14 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
struct brcmf_core *core;
|
||||
struct brcmf_bus *bus;
|
||||
|
||||
if (!id) {
|
||||
id = pci_match_id(brcmf_pcie_devid_table, pdev);
|
||||
if (!id) {
|
||||
pci_err(pdev, "Error could not find pci_device_id for %x:%x\n", pdev->vendor, pdev->device);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device);
|
||||
|
||||
ret = -ENOMEM;
|
||||
|
|
|
@ -1331,6 +1331,9 @@ brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo)
|
|||
brcmf_usb_detach(devinfo);
|
||||
}
|
||||
|
||||
/* Forward declaration for usb_match_id() call */
|
||||
static const struct usb_device_id brcmf_usb_devid_table[];
|
||||
|
||||
static int
|
||||
brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
{
|
||||
|
@ -1342,6 +1345,14 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
u32 num_of_eps;
|
||||
u8 endpoint_num, ep;
|
||||
|
||||
if (!id) {
|
||||
id = usb_match_id(intf, brcmf_usb_devid_table);
|
||||
if (!id) {
|
||||
dev_err(&intf->dev, "Error could not find matching usb_device_id\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
brcmf_dbg(USB, "Enter 0x%04x:0x%04x\n", id->idVendor, id->idProduct);
|
||||
|
||||
devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC);
|
||||
|
|
|
@ -38,7 +38,7 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = {
|
|||
},
|
||||
{ .ident = "ASUS",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek COMPUTER INC."),
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
},
|
||||
},
|
||||
{ .ident = "GOOGLE-HP",
|
||||
|
|
|
@ -1664,14 +1664,10 @@ static __le32 iwl_get_mon_reg(struct iwl_fw_runtime *fwrt, u32 alloc_id,
|
|||
}
|
||||
|
||||
static void *
|
||||
iwl_dump_ini_mon_fill_header(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_dump_ini_region_data *reg_data,
|
||||
iwl_dump_ini_mon_fill_header(struct iwl_fw_runtime *fwrt, u32 alloc_id,
|
||||
struct iwl_fw_ini_monitor_dump *data,
|
||||
const struct iwl_fw_mon_regs *addrs)
|
||||
{
|
||||
struct iwl_fw_ini_region_tlv *reg = (void *)reg_data->reg_tlv->data;
|
||||
u32 alloc_id = le32_to_cpu(reg->dram_alloc_id);
|
||||
|
||||
if (!iwl_trans_grab_nic_access(fwrt->trans)) {
|
||||
IWL_ERR(fwrt, "Failed to get monitor header\n");
|
||||
return NULL;
|
||||
|
@ -1702,8 +1698,10 @@ iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt,
|
|||
void *data, u32 data_len)
|
||||
{
|
||||
struct iwl_fw_ini_monitor_dump *mon_dump = (void *)data;
|
||||
struct iwl_fw_ini_region_tlv *reg = (void *)reg_data->reg_tlv->data;
|
||||
u32 alloc_id = le32_to_cpu(reg->dram_alloc_id);
|
||||
|
||||
return iwl_dump_ini_mon_fill_header(fwrt, reg_data, mon_dump,
|
||||
return iwl_dump_ini_mon_fill_header(fwrt, alloc_id, mon_dump,
|
||||
&fwrt->trans->cfg->mon_dram_regs);
|
||||
}
|
||||
|
||||
|
@ -1713,8 +1711,10 @@ iwl_dump_ini_mon_smem_fill_header(struct iwl_fw_runtime *fwrt,
|
|||
void *data, u32 data_len)
|
||||
{
|
||||
struct iwl_fw_ini_monitor_dump *mon_dump = (void *)data;
|
||||
struct iwl_fw_ini_region_tlv *reg = (void *)reg_data->reg_tlv->data;
|
||||
u32 alloc_id = le32_to_cpu(reg->internal_buffer.alloc_id);
|
||||
|
||||
return iwl_dump_ini_mon_fill_header(fwrt, reg_data, mon_dump,
|
||||
return iwl_dump_ini_mon_fill_header(fwrt, alloc_id, mon_dump,
|
||||
&fwrt->trans->cfg->mon_smem_regs);
|
||||
}
|
||||
|
||||
|
@ -1725,7 +1725,10 @@ iwl_dump_ini_mon_dbgi_fill_header(struct iwl_fw_runtime *fwrt,
|
|||
{
|
||||
struct iwl_fw_ini_monitor_dump *mon_dump = (void *)data;
|
||||
|
||||
return iwl_dump_ini_mon_fill_header(fwrt, reg_data, mon_dump,
|
||||
return iwl_dump_ini_mon_fill_header(fwrt,
|
||||
/* no offset calculation later */
|
||||
IWL_FW_INI_ALLOCATION_ID_DBGC1,
|
||||
mon_dump,
|
||||
&fwrt->trans->cfg->mon_dbgi_regs);
|
||||
}
|
||||
|
||||
|
|
|
@ -2732,17 +2732,13 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait,
|
|||
if (wowlan_info_ver < 2) {
|
||||
struct iwl_wowlan_info_notif_v1 *notif_v1 = (void *)pkt->data;
|
||||
|
||||
notif = kmemdup(notif_v1,
|
||||
offsetofend(struct iwl_wowlan_info_notif,
|
||||
received_beacons),
|
||||
GFP_ATOMIC);
|
||||
|
||||
notif = kmemdup(notif_v1, sizeof(*notif), GFP_ATOMIC);
|
||||
if (!notif)
|
||||
return false;
|
||||
|
||||
notif->tid_tear_down = notif_v1->tid_tear_down;
|
||||
notif->station_id = notif_v1->station_id;
|
||||
|
||||
memset_after(notif, 0, station_id);
|
||||
} else {
|
||||
notif = (void *)pkt->data;
|
||||
}
|
||||
|
|
|
@ -526,6 +526,11 @@ iwl_mvm_ftm_put_target(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
rcu_read_lock();
|
||||
|
||||
sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id]);
|
||||
if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
|
||||
rcu_read_unlock();
|
||||
return PTR_ERR_OR_ZERO(sta);
|
||||
}
|
||||
|
||||
if (sta->mfp && (peer->ftm.trigger_based || peer->ftm.non_trigger_based))
|
||||
FTM_PUT_FLAG(PMF);
|
||||
|
||||
|
|
|
@ -1092,7 +1092,7 @@ static const struct dmi_system_id dmi_tas_approved_list[] = {
|
|||
},
|
||||
{ .ident = "LENOVO",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Lenovo"),
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
},
|
||||
},
|
||||
{ .ident = "DELL",
|
||||
|
@ -1756,8 +1756,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
|||
iwl_mvm_tas_init(mvm);
|
||||
iwl_mvm_leds_sync(mvm);
|
||||
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_RFIM_SUPPORT)) {
|
||||
if (iwl_rfi_supported(mvm)) {
|
||||
if (iwl_mvm_eval_dsm_rfi(mvm) == DSM_VALUE_RFI_ENABLE)
|
||||
iwl_rfi_send_config_cmd(mvm, NULL);
|
||||
}
|
||||
|
|
|
@ -127,11 +127,13 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
if (mvmvif->link[i]->phy_ctxt)
|
||||
count++;
|
||||
|
||||
/* FIXME: IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM should be
|
||||
* defined per HW
|
||||
*/
|
||||
if (count >= IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM)
|
||||
return -EINVAL;
|
||||
if (vif->type == NL80211_IFTYPE_AP) {
|
||||
if (count > mvm->fw->ucode_capa.num_beacons)
|
||||
return -EOPNOTSUPP;
|
||||
/* this should be per HW or such */
|
||||
} else if (count >= IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
/* Catch early if driver tries to activate or deactivate a link
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2022 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018-2023 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
@ -3591,7 +3591,8 @@ static bool iwl_mvm_vif_conf_from_sta(struct iwl_mvm *mvm,
|
|||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
unsigned int i;
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
unsigned int link_id;
|
||||
|
||||
/* Beacon interval check - firmware will crash if the beacon
|
||||
* interval is less than 16. We can't avoid connecting at all,
|
||||
|
@ -3600,14 +3601,11 @@ static bool iwl_mvm_vif_conf_from_sta(struct iwl_mvm *mvm,
|
|||
* wpa_s will blocklist the AP...
|
||||
*/
|
||||
|
||||
for_each_set_bit(i, (unsigned long *)&sta->valid_links,
|
||||
IEEE80211_MLD_MAX_NUM_LINKS) {
|
||||
struct ieee80211_link_sta *link_sta =
|
||||
link_sta_dereference_protected(sta, i);
|
||||
for_each_sta_active_link(vif, sta, link_sta, link_id) {
|
||||
struct ieee80211_bss_conf *link_conf =
|
||||
link_conf_dereference_protected(vif, i);
|
||||
link_conf_dereference_protected(vif, link_id);
|
||||
|
||||
if (!link_conf || !link_sta)
|
||||
if (!link_conf)
|
||||
continue;
|
||||
|
||||
if (link_conf->beacon_int < IWL_MVM_MIN_BEACON_INTERVAL_TU) {
|
||||
|
@ -3629,24 +3627,23 @@ static void iwl_mvm_vif_set_he_support(struct ieee80211_hw *hw,
|
|||
bool is_sta)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
unsigned int i;
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
unsigned int link_id;
|
||||
|
||||
for_each_set_bit(i, (unsigned long *)&sta->valid_links,
|
||||
IEEE80211_MLD_MAX_NUM_LINKS) {
|
||||
struct ieee80211_link_sta *link_sta =
|
||||
link_sta_dereference_protected(sta, i);
|
||||
for_each_sta_active_link(vif, sta, link_sta, link_id) {
|
||||
struct ieee80211_bss_conf *link_conf =
|
||||
link_conf_dereference_protected(vif, i);
|
||||
link_conf_dereference_protected(vif, link_id);
|
||||
|
||||
if (!link_conf || !link_sta || !mvmvif->link[i])
|
||||
if (!link_conf || !mvmvif->link[link_id])
|
||||
continue;
|
||||
|
||||
link_conf->he_support = link_sta->he_cap.has_he;
|
||||
|
||||
if (is_sta) {
|
||||
mvmvif->link[i]->he_ru_2mhz_block = false;
|
||||
mvmvif->link[link_id]->he_ru_2mhz_block = false;
|
||||
if (link_sta->he_cap.has_he)
|
||||
iwl_mvm_check_he_obss_narrow_bw_ru(hw, vif, i,
|
||||
iwl_mvm_check_he_obss_narrow_bw_ru(hw, vif,
|
||||
link_id,
|
||||
link_conf);
|
||||
}
|
||||
}
|
||||
|
@ -3659,6 +3656,7 @@ iwl_mvm_sta_state_notexist_to_none(struct iwl_mvm *mvm,
|
|||
const struct iwl_mvm_sta_state_ops *callbacks)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
|
@ -3683,15 +3681,9 @@ iwl_mvm_sta_state_notexist_to_none(struct iwl_mvm *mvm,
|
|||
NL80211_TDLS_SETUP);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sta->link); i++) {
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
|
||||
link_sta = link_sta_dereference_protected(sta, i);
|
||||
if (!link_sta)
|
||||
continue;
|
||||
|
||||
for_each_sta_active_link(vif, sta, link_sta, i)
|
||||
link_sta->agg.max_rc_amsdu_len = 1;
|
||||
}
|
||||
|
||||
ieee80211_sta_recalc_aggregates(sta);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
|
||||
|
@ -3709,7 +3701,8 @@ iwl_mvm_sta_state_auth_to_assoc(struct ieee80211_hw *hw,
|
|||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
unsigned int i;
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
unsigned int link_id;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
|
@ -3735,14 +3728,13 @@ iwl_mvm_sta_state_auth_to_assoc(struct ieee80211_hw *hw,
|
|||
if (!mvm->mld_api_is_used)
|
||||
goto out;
|
||||
|
||||
for_each_set_bit(i, (unsigned long *)&sta->valid_links,
|
||||
IEEE80211_MLD_MAX_NUM_LINKS) {
|
||||
for_each_sta_active_link(vif, sta, link_sta, link_id) {
|
||||
struct ieee80211_bss_conf *link_conf =
|
||||
link_conf_dereference_protected(vif, i);
|
||||
link_conf_dereference_protected(vif, link_id);
|
||||
|
||||
if (WARN_ON(!link_conf))
|
||||
return -EINVAL;
|
||||
if (!mvmvif->link[i])
|
||||
if (!mvmvif->link[link_id])
|
||||
continue;
|
||||
|
||||
iwl_mvm_link_changed(mvm, vif, link_conf,
|
||||
|
@ -3869,6 +3861,9 @@ int iwl_mvm_mac_sta_state_common(struct ieee80211_hw *hw,
|
|||
* from the AP now.
|
||||
*/
|
||||
iwl_mvm_reset_cca_40mhz_workaround(mvm, vif);
|
||||
|
||||
/* Also free dup data just in case any assertions below fail */
|
||||
kfree(mvm_sta->dup_data);
|
||||
}
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
|
|
@ -906,11 +906,12 @@ iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw,
|
|||
n_active++;
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_AP &&
|
||||
n_active > mvm->fw->ucode_capa.num_beacons)
|
||||
return -EOPNOTSUPP;
|
||||
else if (n_active > 1)
|
||||
if (vif->type == NL80211_IFTYPE_AP) {
|
||||
if (n_active > mvm->fw->ucode_capa.num_beacons)
|
||||
return -EOPNOTSUPP;
|
||||
} else if (n_active > 1) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
|
||||
|
|
|
@ -677,15 +677,15 @@ int iwl_mvm_mld_add_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
ret = iwl_mvm_mld_alloc_sta_links(mvm, vif, sta);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
spin_lock_init(&mvm_sta->lock);
|
||||
spin_lock_init(&mvm_sta->lock);
|
||||
|
||||
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
|
||||
ret = iwl_mvm_alloc_sta_after_restart(mvm, vif, sta);
|
||||
else
|
||||
ret = iwl_mvm_sta_init(mvm, vif, sta, IWL_MVM_INVALID_STA,
|
||||
STATION_TYPE_PEER);
|
||||
} else {
|
||||
ret = iwl_mvm_alloc_sta_after_restart(mvm, vif, sta);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
@ -738,7 +738,7 @@ int iwl_mvm_mld_update_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
unsigned int link_id;
|
||||
int ret = 0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
|
@ -801,8 +801,6 @@ int iwl_mvm_mld_rm_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
kfree(mvm_sta->dup_data);
|
||||
|
||||
/* flush its queues here since we are freeing mvm_sta */
|
||||
for_each_sta_active_link(vif, sta, link_sta, link_id) {
|
||||
struct iwl_mvm_link_sta *mvm_link_sta =
|
||||
|
|
|
@ -2368,6 +2368,7 @@ u32 iwl_mvm_get_sec_flags(struct iwl_mvm *mvm,
|
|||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *keyconf);
|
||||
|
||||
bool iwl_rfi_supported(struct iwl_mvm *mvm);
|
||||
int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm,
|
||||
struct iwl_rfi_lut_entry *rfi_table);
|
||||
struct iwl_rfi_freq_table_resp_cmd *iwl_rfi_get_freq_table(struct iwl_mvm *mvm);
|
||||
|
|
|
@ -445,6 +445,11 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
|
|||
struct iwl_mcc_update_resp *mcc_resp = (void *)pkt->data;
|
||||
|
||||
n_channels = __le32_to_cpu(mcc_resp->n_channels);
|
||||
if (iwl_rx_packet_payload_len(pkt) !=
|
||||
struct_size(mcc_resp, channels, n_channels)) {
|
||||
resp_cp = ERR_PTR(-EINVAL);
|
||||
goto exit;
|
||||
}
|
||||
resp_len = sizeof(struct iwl_mcc_update_resp) +
|
||||
n_channels * sizeof(__le32);
|
||||
resp_cp = kmemdup(mcc_resp, resp_len, GFP_KERNEL);
|
||||
|
@ -456,6 +461,11 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
|
|||
struct iwl_mcc_update_resp_v3 *mcc_resp_v3 = (void *)pkt->data;
|
||||
|
||||
n_channels = __le32_to_cpu(mcc_resp_v3->n_channels);
|
||||
if (iwl_rx_packet_payload_len(pkt) !=
|
||||
struct_size(mcc_resp_v3, channels, n_channels)) {
|
||||
resp_cp = ERR_PTR(-EINVAL);
|
||||
goto exit;
|
||||
}
|
||||
resp_len = sizeof(struct iwl_mcc_update_resp) +
|
||||
n_channels * sizeof(__le32);
|
||||
resp_cp = kzalloc(resp_len, GFP_KERNEL);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2020 - 2021 Intel Corporation
|
||||
* Copyright (C) 2020 - 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "mvm.h"
|
||||
|
@ -70,6 +70,16 @@ static const struct iwl_rfi_lut_entry iwl_rfi_table[IWL_RFI_LUT_SIZE] = {
|
|||
PHY_BAND_6, PHY_BAND_6,}},
|
||||
};
|
||||
|
||||
bool iwl_rfi_supported(struct iwl_mvm *mvm)
|
||||
{
|
||||
/* The feature depends on a platform bugfix, so for now
|
||||
* it's always disabled.
|
||||
* When the platform support detection is implemented we should
|
||||
* check FW TLV and platform support instead.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, struct iwl_rfi_lut_entry *rfi_table)
|
||||
{
|
||||
int ret;
|
||||
|
@ -81,7 +91,7 @@ int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, struct iwl_rfi_lut_entry *rfi_t
|
|||
.len[0] = sizeof(cmd),
|
||||
};
|
||||
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_RFIM_SUPPORT))
|
||||
if (!iwl_rfi_supported(mvm))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
@ -113,7 +123,7 @@ struct iwl_rfi_freq_table_resp_cmd *iwl_rfi_get_freq_table(struct iwl_mvm *mvm)
|
|||
.flags = CMD_WANT_SKB,
|
||||
};
|
||||
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_RFIM_SUPPORT))
|
||||
if (!iwl_rfi_supported(mvm))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
|
|
@ -2691,6 +2691,8 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
|
|||
return;
|
||||
|
||||
lq_sta = mvm_sta;
|
||||
|
||||
spin_lock(&lq_sta->pers.lock);
|
||||
iwl_mvm_hwrate_to_tx_rate_v1(lq_sta->last_rate_n_flags,
|
||||
info->band, &info->control.rates[0]);
|
||||
info->control.rates[0].count = 1;
|
||||
|
@ -2705,6 +2707,7 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
|
|||
iwl_mvm_hwrate_to_tx_rate_v1(last_ucode_rate, info->band,
|
||||
&txrc->reported_rate);
|
||||
}
|
||||
spin_unlock(&lq_sta->pers.lock);
|
||||
}
|
||||
|
||||
static void *rs_drv_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
|
||||
|
|
|
@ -691,6 +691,11 @@ void iwl_mvm_reorder_timer_expired(struct timer_list *t)
|
|||
|
||||
rcu_read_lock();
|
||||
sta = rcu_dereference(buf->mvm->fw_id_to_mac_id[sta_id]);
|
||||
if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
/* SN is set to the last expired frame + 1 */
|
||||
|
@ -712,6 +717,8 @@ void iwl_mvm_reorder_timer_expired(struct timer_list *t)
|
|||
entries[index].e.reorder_time +
|
||||
1 + RX_REORDER_BUF_TIMEOUT_MQ);
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock(&buf->lock);
|
||||
}
|
||||
|
||||
|
@ -2512,7 +2519,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
|||
RCU_INIT_POINTER(mvm->csa_tx_blocked_vif, NULL);
|
||||
/* Unblock BCAST / MCAST station */
|
||||
iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, false);
|
||||
cancel_delayed_work_sync(&mvm->cs_tx_unblock_dwork);
|
||||
cancel_delayed_work(&mvm->cs_tx_unblock_dwork);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@ static void iwl_mvm_rx_agg_session_expired(struct timer_list *t)
|
|||
* A-MDPU and hence the timer continues to run. Then, the
|
||||
* timer expires and sta is NULL.
|
||||
*/
|
||||
if (!sta)
|
||||
if (IS_ERR_OR_NULL(sta))
|
||||
goto unlock;
|
||||
|
||||
mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
@ -2082,9 +2082,6 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
|
|||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
if (iwl_mvm_has_new_rx_api(mvm))
|
||||
kfree(mvm_sta->dup_data);
|
||||
|
||||
ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -3778,6 +3775,9 @@ static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
|
|||
u8 sta_id = mvmvif->deflink.ap_sta_id;
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta)))
|
||||
return NULL;
|
||||
|
||||
return sta->addr;
|
||||
}
|
||||
|
||||
|
@ -3815,6 +3815,11 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
|
|||
|
||||
if (keyconf->cipher == WLAN_CIPHER_SUITE_TKIP) {
|
||||
addr = iwl_mvm_get_mac_addr(mvm, vif, sta);
|
||||
if (!addr) {
|
||||
IWL_ERR(mvm, "Failed to find mac address\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* get phase 1 key from mac80211 */
|
||||
ieee80211_get_key_rx_seq(keyconf, 0, &seq);
|
||||
ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
|
||||
|
|
|
@ -1931,7 +1931,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
|
|||
mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, sta_id);
|
||||
|
||||
sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
|
||||
if (WARN_ON_ONCE(!sta || !sta->wme)) {
|
||||
if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta) || !sta->wme)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -914,7 +914,10 @@ void mt7615_mac_sta_poll(struct mt7615_dev *dev)
|
|||
|
||||
msta = list_first_entry(&sta_poll_list, struct mt7615_sta,
|
||||
poll_list);
|
||||
|
||||
spin_lock_bh(&dev->sta_poll_lock);
|
||||
list_del_init(&msta->poll_list);
|
||||
spin_unlock_bh(&dev->sta_poll_lock);
|
||||
|
||||
addr = mt7615_mac_wtbl_addr(dev, msta->wcid.idx) + 19 * 4;
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ enum {
|
|||
#define MT_TXS5_MPDU_TX_CNT GENMASK(31, 23)
|
||||
|
||||
#define MT_TXS6_MPDU_FAIL_CNT GENMASK(31, 23)
|
||||
|
||||
#define MT_TXS7_MPDU_RETRY_BYTE GENMASK(22, 0)
|
||||
#define MT_TXS7_MPDU_RETRY_CNT GENMASK(31, 23)
|
||||
|
||||
/* RXD DW0 */
|
||||
|
|
|
@ -608,7 +608,8 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
|
|||
/* PPDU based reporting */
|
||||
if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) {
|
||||
stats->tx_bytes +=
|
||||
le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE);
|
||||
le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) -
|
||||
le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE);
|
||||
stats->tx_packets +=
|
||||
le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_CNT);
|
||||
stats->tx_failed +=
|
||||
|
|
|
@ -1004,10 +1004,10 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
|
|||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_vif *vif = info->control.vif;
|
||||
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
|
||||
u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
|
||||
u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
|
||||
bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
|
||||
struct mt7996_vif *mvif;
|
||||
u16 tx_count = 15;
|
||||
u32 val;
|
||||
bool beacon = !!(changed & (BSS_CHANGED_BEACON |
|
||||
|
@ -1015,7 +1015,8 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
|
|||
bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
|
||||
BSS_CHANGED_FILS_DISCOVERY));
|
||||
|
||||
if (vif) {
|
||||
mvif = vif ? (struct mt7996_vif *)vif->drv_priv : NULL;
|
||||
if (mvif) {
|
||||
omac_idx = mvif->mt76.omac_idx;
|
||||
wmm_idx = mvif->mt76.wmm_idx;
|
||||
band_idx = mvif->mt76.band_idx;
|
||||
|
@ -1081,14 +1082,18 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
|
|||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
bool mcast = ieee80211_is_data(hdr->frame_control) &&
|
||||
is_multicast_ether_addr(hdr->addr1);
|
||||
u8 idx = mvif->basic_rates_idx;
|
||||
u8 idx = MT7996_BASIC_RATES_TBL;
|
||||
|
||||
if (mcast && mvif->mcast_rates_idx)
|
||||
idx = mvif->mcast_rates_idx;
|
||||
else if (beacon && mvif->beacon_rates_idx)
|
||||
idx = mvif->beacon_rates_idx;
|
||||
if (mvif) {
|
||||
if (mcast && mvif->mcast_rates_idx)
|
||||
idx = mvif->mcast_rates_idx;
|
||||
else if (beacon && mvif->beacon_rates_idx)
|
||||
idx = mvif->beacon_rates_idx;
|
||||
else
|
||||
idx = mvif->basic_rates_idx;
|
||||
}
|
||||
|
||||
txwi[6] |= FIELD_PREP(MT_TXD6_TX_RATE, idx);
|
||||
txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE, idx));
|
||||
txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1851,6 +1851,7 @@ struct rtl8xxxu_priv {
|
|||
u32 rege9c;
|
||||
u32 regeb4;
|
||||
u32 regebc;
|
||||
u32 regrcr;
|
||||
int next_mbox;
|
||||
int nr_out_eps;
|
||||
|
||||
|
|
|
@ -4245,6 +4245,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
|
|||
RCR_ACCEPT_MGMT_FRAME | RCR_HTC_LOC_CTRL |
|
||||
RCR_APPEND_PHYSTAT | RCR_APPEND_ICV | RCR_APPEND_MIC;
|
||||
rtl8xxxu_write32(priv, REG_RCR, val32);
|
||||
priv->regrcr = val32;
|
||||
|
||||
if (fops->init_reg_rxfltmap) {
|
||||
/* Accept all data frames */
|
||||
|
@ -6722,7 +6723,7 @@ static void rtl8xxxu_configure_filter(struct ieee80211_hw *hw,
|
|||
unsigned int *total_flags, u64 multicast)
|
||||
{
|
||||
struct rtl8xxxu_priv *priv = hw->priv;
|
||||
u32 rcr = rtl8xxxu_read32(priv, REG_RCR);
|
||||
u32 rcr = priv->regrcr;
|
||||
|
||||
dev_dbg(&priv->udev->dev, "%s: changed_flags %08x, total_flags %08x\n",
|
||||
__func__, changed_flags, *total_flags);
|
||||
|
@ -6768,6 +6769,7 @@ static void rtl8xxxu_configure_filter(struct ieee80211_hw *hw,
|
|||
*/
|
||||
|
||||
rtl8xxxu_write32(priv, REG_RCR, rcr);
|
||||
priv->regrcr = rcr;
|
||||
|
||||
*total_flags &= (FIF_ALLMULTI | FIF_FCSFAIL | FIF_BCN_PRBRESP_PROMISC |
|
||||
FIF_CONTROL | FIF_OTHER_BSS | FIF_PSPOLL |
|
||||
|
|
|
@ -88,15 +88,6 @@ static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
|
|||
}
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_PS) {
|
||||
if (hw->conf.flags & IEEE80211_CONF_PS) {
|
||||
rtwdev->ps_enabled = true;
|
||||
} else {
|
||||
rtwdev->ps_enabled = false;
|
||||
rtw_leave_lps(rtwdev);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
|
||||
rtw_set_channel(rtwdev);
|
||||
|
||||
|
@ -215,6 +206,7 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw,
|
|||
config |= PORT_SET_BCN_CTRL;
|
||||
rtw_vif_port_config(rtwdev, rtwvif, config);
|
||||
rtw_core_port_switch(rtwdev, vif);
|
||||
rtw_recalc_lps(rtwdev, vif);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
|
@ -246,6 +238,7 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
|
|||
config |= PORT_SET_BCN_CTRL;
|
||||
rtw_vif_port_config(rtwdev, rtwvif, config);
|
||||
clear_bit(rtwvif->port, rtwdev->hw_port);
|
||||
rtw_recalc_lps(rtwdev, NULL);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
@ -440,6 +433,9 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
|
|||
if (changed & BSS_CHANGED_ERP_SLOT)
|
||||
rtw_conf_tx(rtwdev, rtwvif);
|
||||
|
||||
if (changed & BSS_CHANGED_PS)
|
||||
rtw_recalc_lps(rtwdev, NULL);
|
||||
|
||||
rtw_vif_port_config(rtwdev, rtwvif, config);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
@ -920,7 +916,7 @@ static void rtw_ops_sta_rc_update(struct ieee80211_hw *hw,
|
|||
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
|
||||
|
||||
if (changed & IEEE80211_RC_BW_CHANGED)
|
||||
rtw_update_sta_info(rtwdev, si, true);
|
||||
ieee80211_queue_work(rtwdev->hw, &si->rc_work);
|
||||
}
|
||||
|
||||
const struct ieee80211_ops rtw_ops = {
|
||||
|
|
|
@ -271,8 +271,8 @@ static void rtw_watch_dog_work(struct work_struct *work)
|
|||
* more than two stations associated to the AP, then we can not enter
|
||||
* lps, because fw does not handle the overlapped beacon interval
|
||||
*
|
||||
* mac80211 should iterate vifs and determine if driver can enter
|
||||
* ps by passing IEEE80211_CONF_PS to us, all we need to do is to
|
||||
* rtw_recalc_lps() iterate vifs and determine if driver can enter
|
||||
* ps by vif->type and vif->cfg.ps, all we need to do here is to
|
||||
* get that vif and check if device is having traffic more than the
|
||||
* threshold.
|
||||
*/
|
||||
|
@ -319,6 +319,17 @@ static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
|
|||
return mac_id;
|
||||
}
|
||||
|
||||
static void rtw_sta_rc_work(struct work_struct *work)
|
||||
{
|
||||
struct rtw_sta_info *si = container_of(work, struct rtw_sta_info,
|
||||
rc_work);
|
||||
struct rtw_dev *rtwdev = si->rtwdev;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw_update_sta_info(rtwdev, si, true);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
|
@ -329,12 +340,14 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
|
|||
if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
|
||||
return -ENOSPC;
|
||||
|
||||
si->rtwdev = rtwdev;
|
||||
si->sta = sta;
|
||||
si->vif = vif;
|
||||
si->init_ra_lv = 1;
|
||||
ewma_rssi_init(&si->avg_rssi);
|
||||
for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
|
||||
rtw_txq_init(rtwdev, sta->txq[i]);
|
||||
INIT_WORK(&si->rc_work, rtw_sta_rc_work);
|
||||
|
||||
rtw_update_sta_info(rtwdev, si, true);
|
||||
rtw_fw_media_status_report(rtwdev, si->mac_id, true);
|
||||
|
@ -353,6 +366,8 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
|
|||
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
|
||||
int i;
|
||||
|
||||
cancel_work_sync(&si->rc_work);
|
||||
|
||||
rtw_release_macid(rtwdev, si->mac_id);
|
||||
if (fw_exist)
|
||||
rtw_fw_media_status_report(rtwdev, si->mac_id, false);
|
||||
|
|
|
@ -743,6 +743,7 @@ struct rtw_txq {
|
|||
DECLARE_EWMA(rssi, 10, 16);
|
||||
|
||||
struct rtw_sta_info {
|
||||
struct rtw_dev *rtwdev;
|
||||
struct ieee80211_sta *sta;
|
||||
struct ieee80211_vif *vif;
|
||||
|
||||
|
@ -767,6 +768,8 @@ struct rtw_sta_info {
|
|||
|
||||
bool use_cfg_mask;
|
||||
struct cfg80211_bitrate_mask *mask;
|
||||
|
||||
struct work_struct rc_work;
|
||||
};
|
||||
|
||||
enum rtw_bfee_role {
|
||||
|
|
|
@ -299,3 +299,46 @@ void rtw_leave_lps_deep(struct rtw_dev *rtwdev)
|
|||
|
||||
__rtw_leave_lps_deep(rtwdev);
|
||||
}
|
||||
|
||||
struct rtw_vif_recalc_lps_iter_data {
|
||||
struct rtw_dev *rtwdev;
|
||||
struct ieee80211_vif *found_vif;
|
||||
int count;
|
||||
};
|
||||
|
||||
static void __rtw_vif_recalc_lps(struct rtw_vif_recalc_lps_iter_data *data,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
if (data->count < 0)
|
||||
return;
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_STATION) {
|
||||
data->count = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
data->count++;
|
||||
data->found_vif = vif;
|
||||
}
|
||||
|
||||
static void rtw_vif_recalc_lps_iter(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
__rtw_vif_recalc_lps(data, vif);
|
||||
}
|
||||
|
||||
void rtw_recalc_lps(struct rtw_dev *rtwdev, struct ieee80211_vif *new_vif)
|
||||
{
|
||||
struct rtw_vif_recalc_lps_iter_data data = { .rtwdev = rtwdev };
|
||||
|
||||
if (new_vif)
|
||||
__rtw_vif_recalc_lps(&data, new_vif);
|
||||
rtw_iterate_vifs(rtwdev, rtw_vif_recalc_lps_iter, &data);
|
||||
|
||||
if (data.count == 1 && data.found_vif->cfg.ps) {
|
||||
rtwdev->ps_enabled = true;
|
||||
} else {
|
||||
rtwdev->ps_enabled = false;
|
||||
rtw_leave_lps(rtwdev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,4 +23,6 @@ void rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id);
|
|||
void rtw_leave_lps(struct rtw_dev *rtwdev);
|
||||
void rtw_leave_lps_deep(struct rtw_dev *rtwdev);
|
||||
enum rtw_lps_deep_mode rtw_get_lps_deep_mode(struct rtw_dev *rtwdev);
|
||||
void rtw_recalc_lps(struct rtw_dev *rtwdev, struct ieee80211_vif *new_vif);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -87,11 +87,6 @@ static void rtw_sdio_writew(struct rtw_dev *rtwdev, u16 val, u32 addr,
|
|||
u8 buf[2];
|
||||
int i;
|
||||
|
||||
if (rtw_sdio_use_memcpy_io(rtwdev, addr, 2)) {
|
||||
sdio_writew(rtwsdio->sdio_func, val, addr, err_ret);
|
||||
return;
|
||||
}
|
||||
|
||||
*(__le16 *)buf = cpu_to_le16(val);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
@ -125,9 +120,6 @@ static u16 rtw_sdio_readw(struct rtw_dev *rtwdev, u32 addr, int *err_ret)
|
|||
u8 buf[2];
|
||||
int i;
|
||||
|
||||
if (rtw_sdio_use_memcpy_io(rtwdev, addr, 2))
|
||||
return sdio_readw(rtwsdio->sdio_func, addr, err_ret);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
buf[i] = sdio_readb(rtwsdio->sdio_func, addr + i, err_ret);
|
||||
if (*err_ret)
|
||||
|
|
|
@ -78,7 +78,7 @@ struct rtw_usb {
|
|||
u8 pipe_interrupt;
|
||||
u8 pipe_in;
|
||||
u8 out_ep[RTW_USB_EP_MAX];
|
||||
u8 qsel_to_ep[TX_DESC_QSEL_MAX];
|
||||
int qsel_to_ep[TX_DESC_QSEL_MAX];
|
||||
u8 usb_txagg_num;
|
||||
|
||||
struct workqueue_struct *txwq, *rxwq;
|
||||
|
|
|
@ -2619,9 +2619,6 @@ static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwv
|
|||
rtwvif->tdls_peer)
|
||||
return;
|
||||
|
||||
if (rtwdev->total_sta_assoc > 1)
|
||||
return;
|
||||
|
||||
if (rtwvif->offchan)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1467,6 +1467,8 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
|
|||
.wde_size4 = {RTW89_WDE_PG_64, 0, 4096,},
|
||||
/* PCIE 64 */
|
||||
.wde_size6 = {RTW89_WDE_PG_64, 512, 0,},
|
||||
/* 8852B PCIE SCC */
|
||||
.wde_size7 = {RTW89_WDE_PG_64, 510, 2,},
|
||||
/* DLFW */
|
||||
.wde_size9 = {RTW89_WDE_PG_64, 0, 1024,},
|
||||
/* 8852C DLFW */
|
||||
|
@ -1491,6 +1493,8 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
|
|||
.wde_qt4 = {0, 0, 0, 0,},
|
||||
/* PCIE 64 */
|
||||
.wde_qt6 = {448, 48, 0, 16,},
|
||||
/* 8852B PCIE SCC */
|
||||
.wde_qt7 = {446, 48, 0, 16,},
|
||||
/* 8852C DLFW */
|
||||
.wde_qt17 = {0, 0, 0, 0,},
|
||||
/* 8852C PCIE SCC */
|
||||
|
|
|
@ -794,6 +794,7 @@ struct rtw89_mac_size_set {
|
|||
const struct rtw89_dle_size wde_size0;
|
||||
const struct rtw89_dle_size wde_size4;
|
||||
const struct rtw89_dle_size wde_size6;
|
||||
const struct rtw89_dle_size wde_size7;
|
||||
const struct rtw89_dle_size wde_size9;
|
||||
const struct rtw89_dle_size wde_size18;
|
||||
const struct rtw89_dle_size wde_size19;
|
||||
|
@ -806,6 +807,7 @@ struct rtw89_mac_size_set {
|
|||
const struct rtw89_wde_quota wde_qt0;
|
||||
const struct rtw89_wde_quota wde_qt4;
|
||||
const struct rtw89_wde_quota wde_qt6;
|
||||
const struct rtw89_wde_quota wde_qt7;
|
||||
const struct rtw89_wde_quota wde_qt17;
|
||||
const struct rtw89_wde_quota wde_qt18;
|
||||
const struct rtw89_ple_quota ple_qt4;
|
||||
|
|
|
@ -89,15 +89,6 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
|
|||
!(hw->conf.flags & IEEE80211_CONF_IDLE))
|
||||
rtw89_leave_ips(rtwdev);
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_PS) {
|
||||
if (hw->conf.flags & IEEE80211_CONF_PS) {
|
||||
rtwdev->lps_enabled = true;
|
||||
} else {
|
||||
rtw89_leave_lps(rtwdev);
|
||||
rtwdev->lps_enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
|
||||
rtw89_config_entity_chandef(rtwdev, RTW89_SUB_ENTITY_0,
|
||||
&hw->conf.chandef);
|
||||
|
@ -168,6 +159,8 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
|
|||
rtw89_core_txq_init(rtwdev, vif->txq);
|
||||
|
||||
rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START);
|
||||
|
||||
rtw89_recalc_lps(rtwdev);
|
||||
out:
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
|
@ -192,6 +185,7 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
|
|||
rtw89_mac_remove_vif(rtwdev, rtwvif);
|
||||
rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
|
||||
list_del_init(&rtwvif->list);
|
||||
rtw89_recalc_lps(rtwdev);
|
||||
rtw89_enter_ips_by_hwflags(rtwdev);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
@ -451,6 +445,9 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
|
|||
if (changed & BSS_CHANGED_CQM)
|
||||
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
|
||||
|
||||
if (changed & BSS_CHANGED_PS)
|
||||
rtw89_recalc_lps(rtwdev);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
|
|
|
@ -252,3 +252,29 @@ void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
|
|||
rtw89_p2p_disable_all_noa(rtwdev, vif);
|
||||
rtw89_p2p_update_noa(rtwdev, vif);
|
||||
}
|
||||
|
||||
void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct ieee80211_vif *vif, *found_vif = NULL;
|
||||
struct rtw89_vif *rtwvif;
|
||||
int count = 0;
|
||||
|
||||
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
|
||||
vif = rtwvif_to_vif(rtwvif);
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_STATION) {
|
||||
count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
count++;
|
||||
found_vif = vif;
|
||||
}
|
||||
|
||||
if (count == 1 && found_vif->cfg.ps) {
|
||||
rtwdev->lps_enabled = true;
|
||||
} else {
|
||||
rtw89_leave_lps(rtwdev);
|
||||
rtwdev->lps_enabled = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ void rtw89_enter_ips(struct rtw89_dev *rtwdev);
|
|||
void rtw89_leave_ips(struct rtw89_dev *rtwdev);
|
||||
void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl);
|
||||
void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
|
||||
void rtw89_recalc_lps(struct rtw89_dev *rtwdev);
|
||||
|
||||
static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
|
|
|
@ -18,25 +18,25 @@
|
|||
RTW8852B_FW_BASENAME "-" __stringify(RTW8852B_FW_FORMAT_MAX) ".bin"
|
||||
|
||||
static const struct rtw89_hfc_ch_cfg rtw8852b_hfc_chcfg_pcie[] = {
|
||||
{5, 343, grp_0}, /* ACH 0 */
|
||||
{5, 343, grp_0}, /* ACH 1 */
|
||||
{5, 343, grp_0}, /* ACH 2 */
|
||||
{5, 343, grp_0}, /* ACH 3 */
|
||||
{5, 341, grp_0}, /* ACH 0 */
|
||||
{5, 341, grp_0}, /* ACH 1 */
|
||||
{4, 342, grp_0}, /* ACH 2 */
|
||||
{4, 342, grp_0}, /* ACH 3 */
|
||||
{0, 0, grp_0}, /* ACH 4 */
|
||||
{0, 0, grp_0}, /* ACH 5 */
|
||||
{0, 0, grp_0}, /* ACH 6 */
|
||||
{0, 0, grp_0}, /* ACH 7 */
|
||||
{4, 344, grp_0}, /* B0MGQ */
|
||||
{4, 344, grp_0}, /* B0HIQ */
|
||||
{4, 342, grp_0}, /* B0MGQ */
|
||||
{4, 342, grp_0}, /* B0HIQ */
|
||||
{0, 0, grp_0}, /* B1MGQ */
|
||||
{0, 0, grp_0}, /* B1HIQ */
|
||||
{40, 0, 0} /* FWCMDQ */
|
||||
};
|
||||
|
||||
static const struct rtw89_hfc_pub_cfg rtw8852b_hfc_pubcfg_pcie = {
|
||||
448, /* Group 0 */
|
||||
446, /* Group 0 */
|
||||
0, /* Group 1 */
|
||||
448, /* Public Max */
|
||||
446, /* Public Max */
|
||||
0 /* WP threshold */
|
||||
};
|
||||
|
||||
|
@ -49,13 +49,13 @@ static const struct rtw89_hfc_param_ini rtw8852b_hfc_param_ini_pcie[] = {
|
|||
};
|
||||
|
||||
static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = {
|
||||
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size6,
|
||||
&rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6,
|
||||
&rtw89_mac_size.wde_qt6, &rtw89_mac_size.ple_qt18,
|
||||
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size7,
|
||||
&rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt7,
|
||||
&rtw89_mac_size.wde_qt7, &rtw89_mac_size.ple_qt18,
|
||||
&rtw89_mac_size.ple_qt58},
|
||||
[RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size6,
|
||||
&rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6,
|
||||
&rtw89_mac_size.wde_qt6, &rtw89_mac_size.ple_qt18,
|
||||
[RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size7,
|
||||
&rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt7,
|
||||
&rtw89_mac_size.wde_qt7, &rtw89_mac_size.ple_qt18,
|
||||
&rtw89_mac_size.ple_qt_52b_wow},
|
||||
[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9,
|
||||
&rtw89_mac_size.ple_size8, &rtw89_mac_size.wde_qt4,
|
||||
|
|
|
@ -5972,10 +5972,11 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
|
|||
ret = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
param.pmsr_capa = pmsr_capa;
|
||||
|
||||
ret = parse_pmsr_capa(info->attrs[HWSIM_ATTR_PMSR_SUPPORT], pmsr_capa, info);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
param.pmsr_capa = pmsr_capa;
|
||||
}
|
||||
|
||||
ret = mac80211_hwsim_new_radio(info, ¶m);
|
||||
|
|
|
@ -1583,9 +1583,10 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
|
|||
sdata_dereference(link->u.ap.unsol_bcast_probe_resp,
|
||||
sdata);
|
||||
|
||||
/* abort any running channel switch */
|
||||
/* abort any running channel switch or color change */
|
||||
mutex_lock(&local->mtx);
|
||||
link_conf->csa_active = false;
|
||||
link_conf->color_change_active = false;
|
||||
if (link->csa_block_tx) {
|
||||
ieee80211_wake_vif_queues(local, sdata,
|
||||
IEEE80211_QUEUE_STOP_REASON_CSA);
|
||||
|
|
|
@ -258,7 +258,8 @@ ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
static enum nl80211_chan_width
|
||||
ieee80211_get_chanctx_vif_max_required_bw(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_chanctx_conf *conf)
|
||||
struct ieee80211_chanctx *ctx,
|
||||
struct ieee80211_link_data *rsvd_for)
|
||||
{
|
||||
enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
struct ieee80211_vif *vif = &sdata->vif;
|
||||
|
@ -267,13 +268,14 @@ ieee80211_get_chanctx_vif_max_required_bw(struct ieee80211_sub_if_data *sdata,
|
|||
rcu_read_lock();
|
||||
for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) {
|
||||
enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
struct ieee80211_bss_conf *link_conf =
|
||||
rcu_dereference(sdata->vif.link_conf[link_id]);
|
||||
struct ieee80211_link_data *link =
|
||||
rcu_dereference(sdata->link[link_id]);
|
||||
|
||||
if (!link_conf)
|
||||
if (!link)
|
||||
continue;
|
||||
|
||||
if (rcu_access_pointer(link_conf->chanctx_conf) != conf)
|
||||
if (link != rsvd_for &&
|
||||
rcu_access_pointer(link->conf->chanctx_conf) != &ctx->conf)
|
||||
continue;
|
||||
|
||||
switch (vif->type) {
|
||||
|
@ -287,7 +289,7 @@ ieee80211_get_chanctx_vif_max_required_bw(struct ieee80211_sub_if_data *sdata,
|
|||
* point, so take the width from the chandef, but
|
||||
* account also for TDLS peers
|
||||
*/
|
||||
width = max(link_conf->chandef.width,
|
||||
width = max(link->conf->chandef.width,
|
||||
ieee80211_get_max_required_bw(sdata, link_id));
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
|
@ -296,7 +298,7 @@ ieee80211_get_chanctx_vif_max_required_bw(struct ieee80211_sub_if_data *sdata,
|
|||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
case NL80211_IFTYPE_OCB:
|
||||
width = link_conf->chandef.width;
|
||||
width = link->conf->chandef.width;
|
||||
break;
|
||||
case NL80211_IFTYPE_WDS:
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
|
@ -316,7 +318,8 @@ ieee80211_get_chanctx_vif_max_required_bw(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
static enum nl80211_chan_width
|
||||
ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx_conf *conf)
|
||||
struct ieee80211_chanctx *ctx,
|
||||
struct ieee80211_link_data *rsvd_for)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
|
@ -328,7 +331,8 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
|
|||
if (!ieee80211_sdata_running(sdata))
|
||||
continue;
|
||||
|
||||
width = ieee80211_get_chanctx_vif_max_required_bw(sdata, conf);
|
||||
width = ieee80211_get_chanctx_vif_max_required_bw(sdata, ctx,
|
||||
rsvd_for);
|
||||
|
||||
max_bw = max(max_bw, width);
|
||||
}
|
||||
|
@ -336,8 +340,8 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
|
|||
/* use the configured bandwidth in case of monitor interface */
|
||||
sdata = rcu_dereference(local->monitor_sdata);
|
||||
if (sdata &&
|
||||
rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) == conf)
|
||||
max_bw = max(max_bw, conf->def.width);
|
||||
rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) == &ctx->conf)
|
||||
max_bw = max(max_bw, ctx->conf.def.width);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
|
@ -349,8 +353,10 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
|
|||
* the max of min required widths of all the interfaces bound to this
|
||||
* channel context.
|
||||
*/
|
||||
static u32 _ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx)
|
||||
static u32
|
||||
_ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx,
|
||||
struct ieee80211_link_data *rsvd_for)
|
||||
{
|
||||
enum nl80211_chan_width max_bw;
|
||||
struct cfg80211_chan_def min_def;
|
||||
|
@ -370,7 +376,7 @@ static u32 _ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
|
|||
return 0;
|
||||
}
|
||||
|
||||
max_bw = ieee80211_get_chanctx_max_required_bw(local, &ctx->conf);
|
||||
max_bw = ieee80211_get_chanctx_max_required_bw(local, ctx, rsvd_for);
|
||||
|
||||
/* downgrade chandef up to max_bw */
|
||||
min_def = ctx->conf.def;
|
||||
|
@ -448,9 +454,10 @@ static void ieee80211_chan_bw_change(struct ieee80211_local *local,
|
|||
* channel context.
|
||||
*/
|
||||
void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx)
|
||||
struct ieee80211_chanctx *ctx,
|
||||
struct ieee80211_link_data *rsvd_for)
|
||||
{
|
||||
u32 changed = _ieee80211_recalc_chanctx_min_def(local, ctx);
|
||||
u32 changed = _ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for);
|
||||
|
||||
if (!changed)
|
||||
return;
|
||||
|
@ -464,10 +471,11 @@ void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
|
|||
ieee80211_chan_bw_change(local, ctx, false);
|
||||
}
|
||||
|
||||
static void ieee80211_change_chanctx(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx,
|
||||
struct ieee80211_chanctx *old_ctx,
|
||||
const struct cfg80211_chan_def *chandef)
|
||||
static void _ieee80211_change_chanctx(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx,
|
||||
struct ieee80211_chanctx *old_ctx,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
struct ieee80211_link_data *rsvd_for)
|
||||
{
|
||||
u32 changed;
|
||||
|
||||
|
@ -492,7 +500,7 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
|
|||
ieee80211_chan_bw_change(local, old_ctx, true);
|
||||
|
||||
if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) {
|
||||
ieee80211_recalc_chanctx_min_def(local, ctx);
|
||||
ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -502,7 +510,7 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
|
|||
|
||||
/* check if min chanctx also changed */
|
||||
changed = IEEE80211_CHANCTX_CHANGE_WIDTH |
|
||||
_ieee80211_recalc_chanctx_min_def(local, ctx);
|
||||
_ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for);
|
||||
drv_change_chanctx(local, ctx, changed);
|
||||
|
||||
if (!local->use_chanctx) {
|
||||
|
@ -514,6 +522,14 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
|
|||
ieee80211_chan_bw_change(local, old_ctx, false);
|
||||
}
|
||||
|
||||
static void ieee80211_change_chanctx(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx,
|
||||
struct ieee80211_chanctx *old_ctx,
|
||||
const struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
_ieee80211_change_chanctx(local, ctx, old_ctx, chandef, NULL);
|
||||
}
|
||||
|
||||
static struct ieee80211_chanctx *
|
||||
ieee80211_find_chanctx(struct ieee80211_local *local,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
|
@ -638,7 +654,7 @@ ieee80211_alloc_chanctx(struct ieee80211_local *local,
|
|||
ctx->conf.rx_chains_dynamic = 1;
|
||||
ctx->mode = mode;
|
||||
ctx->conf.radar_enabled = false;
|
||||
ieee80211_recalc_chanctx_min_def(local, ctx);
|
||||
_ieee80211_recalc_chanctx_min_def(local, ctx, NULL);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
@ -855,6 +871,9 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
|
|||
}
|
||||
|
||||
if (new_ctx) {
|
||||
/* recalc considering the link we'll use it for now */
|
||||
ieee80211_recalc_chanctx_min_def(local, new_ctx, link);
|
||||
|
||||
ret = drv_assign_vif_chanctx(local, sdata, link->conf, new_ctx);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
@ -873,12 +892,12 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
|
|||
ieee80211_recalc_chanctx_chantype(local, curr_ctx);
|
||||
ieee80211_recalc_smps_chanctx(local, curr_ctx);
|
||||
ieee80211_recalc_radar_chanctx(local, curr_ctx);
|
||||
ieee80211_recalc_chanctx_min_def(local, curr_ctx);
|
||||
ieee80211_recalc_chanctx_min_def(local, curr_ctx, NULL);
|
||||
}
|
||||
|
||||
if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
|
||||
ieee80211_recalc_txpower(sdata, false);
|
||||
ieee80211_recalc_chanctx_min_def(local, new_ctx);
|
||||
ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL);
|
||||
}
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
|
||||
|
@ -1270,7 +1289,7 @@ ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link)
|
|||
|
||||
ieee80211_link_update_chandef(link, &link->reserved_chandef);
|
||||
|
||||
ieee80211_change_chanctx(local, new_ctx, old_ctx, chandef);
|
||||
_ieee80211_change_chanctx(local, new_ctx, old_ctx, chandef, link);
|
||||
|
||||
vif_chsw[0].vif = &sdata->vif;
|
||||
vif_chsw[0].old_ctx = &old_ctx->conf;
|
||||
|
@ -1300,7 +1319,7 @@ ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link)
|
|||
if (ieee80211_chanctx_refcount(local, old_ctx) == 0)
|
||||
ieee80211_free_chanctx(local, old_ctx);
|
||||
|
||||
ieee80211_recalc_chanctx_min_def(local, new_ctx);
|
||||
ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL);
|
||||
ieee80211_recalc_smps_chanctx(local, new_ctx);
|
||||
ieee80211_recalc_radar_chanctx(local, new_ctx);
|
||||
|
||||
|
@ -1665,7 +1684,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
|
|||
ieee80211_recalc_chanctx_chantype(local, ctx);
|
||||
ieee80211_recalc_smps_chanctx(local, ctx);
|
||||
ieee80211_recalc_radar_chanctx(local, ctx);
|
||||
ieee80211_recalc_chanctx_min_def(local, ctx);
|
||||
ieee80211_recalc_chanctx_min_def(local, ctx, NULL);
|
||||
|
||||
list_for_each_entry_safe(link, link_tmp, &ctx->reserved_links,
|
||||
reserved_chanctx_list) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* HE handling
|
||||
*
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2019 - 2022 Intel Corporation
|
||||
* Copyright(c) 2019 - 2023 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "ieee80211_i.h"
|
||||
|
@ -114,6 +114,7 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
|
|||
struct link_sta_info *link_sta)
|
||||
{
|
||||
struct ieee80211_sta_he_cap *he_cap = &link_sta->pub->he_cap;
|
||||
const struct ieee80211_sta_he_cap *own_he_cap_ptr;
|
||||
struct ieee80211_sta_he_cap own_he_cap;
|
||||
struct ieee80211_he_cap_elem *he_cap_ie_elem = (void *)he_cap_ie;
|
||||
u8 he_ppe_size;
|
||||
|
@ -123,12 +124,16 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
memset(he_cap, 0, sizeof(*he_cap));
|
||||
|
||||
if (!he_cap_ie ||
|
||||
!ieee80211_get_he_iftype_cap(sband,
|
||||
ieee80211_vif_type_p2p(&sdata->vif)))
|
||||
if (!he_cap_ie)
|
||||
return;
|
||||
|
||||
own_he_cap = sband->iftype_data->he_cap;
|
||||
own_he_cap_ptr =
|
||||
ieee80211_get_he_iftype_cap(sband,
|
||||
ieee80211_vif_type_p2p(&sdata->vif));
|
||||
if (!own_he_cap_ptr)
|
||||
return;
|
||||
|
||||
own_he_cap = *own_he_cap_ptr;
|
||||
|
||||
/* Make sure size is OK */
|
||||
mcs_nss_size = ieee80211_he_mcs_nss_size(he_cap_ie_elem);
|
||||
|
|
|
@ -2541,7 +2541,8 @@ int ieee80211_chanctx_refcount(struct ieee80211_local *local,
|
|||
void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *chanctx);
|
||||
void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx);
|
||||
struct ieee80211_chanctx *ctx,
|
||||
struct ieee80211_link_data *rsvd_for);
|
||||
bool ieee80211_is_radar_required(struct ieee80211_local *local);
|
||||
|
||||
void ieee80211_dfs_cac_timer(unsigned long data);
|
||||
|
|
|
@ -1217,6 +1217,7 @@ static void ieee80211_add_non_inheritance_elem(struct sk_buff *skb,
|
|||
const u16 *inner)
|
||||
{
|
||||
unsigned int skb_len = skb->len;
|
||||
bool at_extension = false;
|
||||
bool added = false;
|
||||
int i, j;
|
||||
u8 *len, *list_len = NULL;
|
||||
|
@ -1228,7 +1229,6 @@ static void ieee80211_add_non_inheritance_elem(struct sk_buff *skb,
|
|||
for (i = 0; i < PRESENT_ELEMS_MAX && outer[i]; i++) {
|
||||
u16 elem = outer[i];
|
||||
bool have_inner = false;
|
||||
bool at_extension = false;
|
||||
|
||||
/* should at least be sorted in the sense of normal -> ext */
|
||||
WARN_ON(at_extension && elem < PRESENT_ELEM_EXT_OFFS);
|
||||
|
@ -1257,8 +1257,14 @@ static void ieee80211_add_non_inheritance_elem(struct sk_buff *skb,
|
|||
}
|
||||
*list_len += 1;
|
||||
skb_put_u8(skb, (u8)elem);
|
||||
added = true;
|
||||
}
|
||||
|
||||
/* if we added a list but no extension list, make a zero-len one */
|
||||
if (added && (!at_extension || !list_len))
|
||||
skb_put_u8(skb, 0);
|
||||
|
||||
/* if nothing added remove extension element completely */
|
||||
if (!added)
|
||||
skb_trim(skb, skb_len);
|
||||
else
|
||||
|
|
|
@ -4965,7 +4965,9 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
|||
}
|
||||
|
||||
if (unlikely(rx->sta && rx->sta->sta.mlo) &&
|
||||
is_unicast_ether_addr(hdr->addr1)) {
|
||||
is_unicast_ether_addr(hdr->addr1) &&
|
||||
!ieee80211_is_probe_resp(hdr->frame_control) &&
|
||||
!ieee80211_is_beacon(hdr->frame_control)) {
|
||||
/* translate to MLD addresses */
|
||||
if (ether_addr_equal(link->conf->addr, hdr->addr1))
|
||||
ether_addr_copy(hdr->addr1, rx->sdata->vif.addr);
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
__entry->min_freq_offset = (c)->chan ? (c)->chan->freq_offset : 0; \
|
||||
__entry->min_chan_width = (c)->width; \
|
||||
__entry->min_center_freq1 = (c)->center_freq1; \
|
||||
__entry->freq1_offset = (c)->freq1_offset; \
|
||||
__entry->min_freq1_offset = (c)->freq1_offset; \
|
||||
__entry->min_center_freq2 = (c)->center_freq2;
|
||||
#define MIN_CHANDEF_PR_FMT " min_control:%d.%03d MHz min_width:%d min_center: %d.%03d/%d MHz"
|
||||
#define MIN_CHANDEF_PR_ARG __entry->min_control_freq, __entry->min_freq_offset, \
|
||||
|
|
|
@ -3775,6 +3775,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
|
|||
ieee80211_tx_result r;
|
||||
struct ieee80211_vif *vif = txq->vif;
|
||||
int q = vif->hw_queue[txq->ac];
|
||||
unsigned long flags;
|
||||
bool q_stopped;
|
||||
|
||||
WARN_ON_ONCE(softirq_count() == 0);
|
||||
|
@ -3783,9 +3784,9 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
|
|||
return NULL;
|
||||
|
||||
begin:
|
||||
spin_lock(&local->queue_stop_reason_lock);
|
||||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||
q_stopped = local->queue_stop_reasons[q];
|
||||
spin_unlock(&local->queue_stop_reason_lock);
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||
|
||||
if (unlikely(q_stopped)) {
|
||||
/* mark for waking later */
|
||||
|
@ -5511,7 +5512,7 @@ ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw,
|
|||
{
|
||||
struct ieee80211_ema_beacons *ema_beacons = NULL;
|
||||
|
||||
WARN_ON(__ieee80211_beacon_get(hw, vif, NULL, false, link_id, 0,
|
||||
WARN_ON(__ieee80211_beacon_get(hw, vif, NULL, true, link_id, 0,
|
||||
&ema_beacons));
|
||||
|
||||
return ema_beacons;
|
||||
|
|
|
@ -3097,7 +3097,7 @@ void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
chanctx = container_of(chanctx_conf, struct ieee80211_chanctx,
|
||||
conf);
|
||||
ieee80211_recalc_chanctx_min_def(local, chanctx);
|
||||
ieee80211_recalc_chanctx_min_def(local, chanctx, NULL);
|
||||
}
|
||||
unlock:
|
||||
mutex_unlock(&local->chanctx_mtx);
|
||||
|
|
|
@ -368,12 +368,12 @@ static void cfg80211_sched_scan_stop_wk(struct work_struct *work)
|
|||
rdev = container_of(work, struct cfg80211_registered_device,
|
||||
sched_scan_stop_wk);
|
||||
|
||||
rtnl_lock();
|
||||
wiphy_lock(&rdev->wiphy);
|
||||
list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) {
|
||||
if (req->nl_owner_dead)
|
||||
cfg80211_stop_sched_scan_req(rdev, req, false);
|
||||
}
|
||||
rtnl_unlock();
|
||||
wiphy_unlock(&rdev->wiphy);
|
||||
}
|
||||
|
||||
static void cfg80211_propagate_radar_detect_wk(struct work_struct *work)
|
||||
|
|
|
@ -10723,6 +10723,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
|
|||
if (!info->attrs[NL80211_ATTR_MLD_ADDR])
|
||||
return -EINVAL;
|
||||
req.ap_mld_addr = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
|
||||
if (!is_valid_ether_addr(req.ap_mld_addr))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
|
||||
|
|
|
@ -2440,11 +2440,11 @@ static void reg_leave_invalid_chans(struct wiphy *wiphy)
|
|||
struct wireless_dev *wdev;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
wiphy_lock(wiphy);
|
||||
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
|
||||
if (!reg_wdev_chan_valid(wiphy, wdev))
|
||||
cfg80211_leave(rdev, wdev);
|
||||
wiphy_unlock(wiphy);
|
||||
}
|
||||
|
||||
static void reg_check_chans_work(struct work_struct *work)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright 2016 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2022 Intel Corporation
|
||||
* Copyright (C) 2018-2023 Intel Corporation
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -540,6 +540,10 @@ static int cfg80211_parse_ap_info(struct cfg80211_colocated_ap *entry,
|
|||
/* skip the TBTT offset */
|
||||
pos++;
|
||||
|
||||
/* ignore entries with invalid BSSID */
|
||||
if (!is_valid_ether_addr(pos))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(entry->bssid, pos, ETH_ALEN);
|
||||
pos += ETH_ALEN;
|
||||
|
||||
|
|
Loading…
Reference in a new issue