mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 07:23:14 +00:00
ath.git patches for v6.10
ath drivers now have no remaining sparse warnings, otherwise smaller fixes and some refactoring. ath11k * P2P support for QCA6390, WCN6855 and QCA2066 -----BEGIN PGP SIGNATURE----- iQFLBAABCgA1FiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmYMOQsXHHF1aWNfa3Zh bG9AcXVpY2luYy5jb20ACgkQbhckVSbrbZvycgf+PVR1nswT+ZMYWfbGoDYe04Ah Kvccpordskt9A6GmasZlxQmzCik2dyGAOI5JJ/LPDhs/uYcRIu59DSkLlDz93EFk n6jiaDi6Y3HQpAULn1u1CHow5gkBWYnfIQH7aTP7H1nuD+ApBYhPIkYTQmZkMewi unz4VwaBNJZhQPfM4DDKr/FQ0OMyNtv1EDFNVhX/HU/JB1EvGPT6key4HSFXDGFy fkHt2pj3TMlK530AbRwEVZ0D+6uNtT1Qmon5MWtSqzjTt1TmI4TLv1nrINVdg5qD yVc+iQ7myCL7cbX0bI6HDHSIqJUvycx191jxLOk7TzkfsKL0oeR+fFeEpledng== =+Ku3 -----END PGP SIGNATURE----- Merge tag 'ath-next-20240402' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath ath.git patches for v6.10 ath drivers now have no remaining sparse warnings, otherwise smaller fixes and some refactoring. ath11k * P2P support for QCA6390, WCN6855 and QCA2066
This commit is contained in:
commit
0ccf50df61
@ -100,7 +100,7 @@ static ssize_t ath10k_thermal_show_temp(struct device *dev,
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
/* display in millidegree celsius */
|
||||
ret = snprintf(buf, PAGE_SIZE, "%d\n", temperature * 1000);
|
||||
ret = sysfs_emit(buf, "%d\n", temperature * 1000);
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
|
@ -1763,12 +1763,32 @@ void ath10k_wmi_put_wmi_channel(struct ath10k *ar, struct wmi_channel *ch,
|
||||
|
||||
int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
|
||||
{
|
||||
unsigned long time_left;
|
||||
unsigned long time_left, i;
|
||||
|
||||
time_left = wait_for_completion_timeout(&ar->wmi.service_ready,
|
||||
WMI_SERVICE_READY_TIMEOUT_HZ);
|
||||
if (!time_left)
|
||||
return -ETIMEDOUT;
|
||||
if (!time_left) {
|
||||
/* Sometimes the PCI HIF doesn't receive interrupt
|
||||
* for the service ready message even if the buffer
|
||||
* was completed. PCIe sniffer shows that it's
|
||||
* because the corresponding CE ring doesn't fires
|
||||
* it. Workaround here by polling CE rings once.
|
||||
*/
|
||||
ath10k_warn(ar, "failed to receive service ready completion, polling..\n");
|
||||
|
||||
for (i = 0; i < CE_COUNT; i++)
|
||||
ath10k_hif_send_complete_check(ar, i, 1);
|
||||
|
||||
time_left = wait_for_completion_timeout(&ar->wmi.service_ready,
|
||||
WMI_SERVICE_READY_TIMEOUT_HZ);
|
||||
if (!time_left) {
|
||||
ath10k_warn(ar, "polling timed out\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
ath10k_warn(ar, "service ready completion received, continuing normally\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,8 @@ ath11k-y += core.o \
|
||||
dbring.o \
|
||||
hw.o \
|
||||
pcic.o \
|
||||
fw.o
|
||||
fw.o \
|
||||
p2p.o
|
||||
|
||||
ath11k-$(CONFIG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o
|
||||
ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o
|
||||
|
@ -247,7 +247,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP),
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_P2P_DEVICE) |
|
||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO),
|
||||
.supports_monitor = false,
|
||||
.full_monitor_mode = false,
|
||||
.supports_shadow_regs = true,
|
||||
@ -416,7 +419,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP),
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_P2P_DEVICE) |
|
||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO),
|
||||
.supports_monitor = false,
|
||||
.full_monitor_mode = false,
|
||||
.supports_shadow_regs = true,
|
||||
@ -501,7 +507,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP),
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_P2P_DEVICE) |
|
||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO),
|
||||
.supports_monitor = false,
|
||||
.supports_shadow_regs = true,
|
||||
.idle_ps = true,
|
||||
@ -750,7 +759,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP),
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_P2P_DEVICE) |
|
||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO),
|
||||
.supports_monitor = false,
|
||||
.full_monitor_mode = false,
|
||||
.supports_shadow_regs = true,
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
@ -980,7 +980,7 @@ int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
|
||||
debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
|
||||
&fops_simulate_fw_crash);
|
||||
|
||||
debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
|
||||
debugfs_create_file("soc_dp_stats", 0400, ab->debugfs_soc, ab,
|
||||
&fops_soc_dp_stats);
|
||||
|
||||
if (ab->hw_params.sram_dump.start != 0)
|
||||
|
@ -1231,14 +1231,7 @@ static int ath11k_mac_vif_setup_ps(struct ath11k_vif *arvif)
|
||||
|
||||
enable_ps = arvif->ps;
|
||||
|
||||
if (!arvif->is_started) {
|
||||
/* mac80211 can update vif powersave state while disconnected.
|
||||
* Firmware doesn't behave nicely and consumes more power than
|
||||
* necessary if PS is disabled on a non-started vdev. Hence
|
||||
* force-enable PS for non-running vdevs.
|
||||
*/
|
||||
psmode = WMI_STA_PS_MODE_ENABLED;
|
||||
} else if (enable_ps) {
|
||||
if (enable_ps) {
|
||||
psmode = WMI_STA_PS_MODE_ENABLED;
|
||||
param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
|
||||
|
||||
@ -1430,10 +1423,67 @@ static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
|
||||
struct sk_buff *bcn)
|
||||
static int ath11k_mac_setup_bcn_p2p_ie(struct ath11k_vif *arvif,
|
||||
struct sk_buff *bcn)
|
||||
{
|
||||
struct ath11k *ar = arvif->ar;
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
const u8 *p2p_ie;
|
||||
int ret;
|
||||
|
||||
mgmt = (void *)bcn->data;
|
||||
p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
|
||||
mgmt->u.beacon.variable,
|
||||
bcn->len - (mgmt->u.beacon.variable -
|
||||
bcn->data));
|
||||
if (!p2p_ie)
|
||||
return -ENOENT;
|
||||
|
||||
ret = ath11k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to submit P2P GO bcn ie for vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath11k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
|
||||
u8 oui_type, size_t ie_offset)
|
||||
{
|
||||
size_t len;
|
||||
const u8 *next, *end;
|
||||
u8 *ie;
|
||||
|
||||
if (WARN_ON(skb->len < ie_offset))
|
||||
return -EINVAL;
|
||||
|
||||
ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
|
||||
skb->data + ie_offset,
|
||||
skb->len - ie_offset);
|
||||
if (!ie)
|
||||
return -ENOENT;
|
||||
|
||||
len = ie[1] + 2;
|
||||
end = skb->data + skb->len;
|
||||
next = ie + len;
|
||||
|
||||
if (WARN_ON(next > end))
|
||||
return -EINVAL;
|
||||
|
||||
memmove(ie, next, end - next);
|
||||
skb_trim(skb, skb->len - len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
|
||||
struct sk_buff *bcn)
|
||||
{
|
||||
struct ath11k_base *ab = arvif->ar->ab;
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
int ret = 0;
|
||||
u8 *ies;
|
||||
|
||||
ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
|
||||
@ -1451,6 +1501,32 @@ static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
|
||||
arvif->wpaie_present = true;
|
||||
else
|
||||
arvif->wpaie_present = false;
|
||||
|
||||
if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
|
||||
return ret;
|
||||
|
||||
ret = ath11k_mac_setup_bcn_p2p_ie(arvif, bcn);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to setup P2P GO bcn ie: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* P2P IE is inserted by firmware automatically (as
|
||||
* configured above) so remove it from the base beacon
|
||||
* template to avoid duplicate P2P IEs in beacon frames.
|
||||
*/
|
||||
ret = ath11k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA,
|
||||
WLAN_OUI_TYPE_WFA_P2P,
|
||||
offsetof(struct ieee80211_mgmt,
|
||||
u.beacon.variable));
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to remove P2P vendor ie: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
|
||||
@ -1472,10 +1548,12 @@ static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (tx_arvif == arvif)
|
||||
ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb);
|
||||
else
|
||||
if (tx_arvif == arvif) {
|
||||
if (ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb))
|
||||
return -EINVAL;
|
||||
} else {
|
||||
arvif->wpaie_present = tx_arvif->wpaie_present;
|
||||
}
|
||||
|
||||
for (i = 0; i < beacons->cnt; i++) {
|
||||
if (tx_arvif != arvif && !nontx_vif_params_set)
|
||||
@ -1534,10 +1612,12 @@ static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif)
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (tx_arvif == arvif)
|
||||
ath11k_mac_set_vif_params(tx_arvif, bcn);
|
||||
else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn))
|
||||
if (tx_arvif == arvif) {
|
||||
if (ath11k_mac_set_vif_params(tx_arvif, bcn))
|
||||
return -EINVAL;
|
||||
} else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0);
|
||||
kfree_skb(bcn);
|
||||
@ -3996,6 +4076,9 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw,
|
||||
arg->vdev_id = arvif->vdev_id;
|
||||
arg->scan_id = ATH11K_SCAN_ID;
|
||||
|
||||
if (ar->ab->hw_params.single_pdev_only)
|
||||
arg->scan_f_filter_prb_req = 1;
|
||||
|
||||
if (req->ie_len) {
|
||||
arg->extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL);
|
||||
if (!arg->extraie.ptr) {
|
||||
@ -6570,17 +6653,26 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
arvif->vdev_type = WMI_VDEV_TYPE_STA;
|
||||
if (vif->p2p)
|
||||
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT;
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_MESH_11S;
|
||||
fallthrough;
|
||||
case NL80211_IFTYPE_AP:
|
||||
arvif->vdev_type = WMI_VDEV_TYPE_AP;
|
||||
if (vif->p2p)
|
||||
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO;
|
||||
break;
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
|
||||
ar->monitor_vdev_id = bit;
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
arvif->vdev_type = WMI_VDEV_TYPE_STA;
|
||||
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN_ON(1);
|
||||
break;
|
||||
@ -9253,9 +9345,11 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
|
||||
arg->dwell_time_passive = scan_time_msec;
|
||||
arg->max_scan_time = scan_time_msec;
|
||||
arg->scan_f_passive = 1;
|
||||
arg->scan_f_filter_prb_req = 1;
|
||||
arg->burst_duration = duration;
|
||||
|
||||
if (!ar->ab->hw_params.single_pdev_only)
|
||||
arg->scan_f_filter_prb_req = 1;
|
||||
|
||||
ret = ath11k_start_scan(ar, arg);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to start roc scan: %d\n", ret);
|
||||
@ -9857,12 +9951,18 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
|
||||
struct ieee80211_iface_combination *combinations;
|
||||
struct ieee80211_iface_limit *limits;
|
||||
int n_limits;
|
||||
bool p2p;
|
||||
|
||||
p2p = ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
|
||||
combinations = kzalloc(sizeof(*combinations), GFP_KERNEL);
|
||||
if (!combinations)
|
||||
return -ENOMEM;
|
||||
|
||||
n_limits = 2;
|
||||
if (p2p)
|
||||
n_limits = 3;
|
||||
else
|
||||
n_limits = 2;
|
||||
|
||||
limits = kcalloc(n_limits, sizeof(*limits), GFP_KERNEL);
|
||||
if (!limits) {
|
||||
@ -9870,39 +9970,29 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
limits[0].types |= BIT(NL80211_IFTYPE_STATION);
|
||||
limits[1].types |= BIT(NL80211_IFTYPE_AP);
|
||||
if (IS_ENABLED(CONFIG_MAC80211_MESH) &&
|
||||
ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT))
|
||||
limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT);
|
||||
|
||||
combinations[0].limits = limits;
|
||||
combinations[0].n_limits = n_limits;
|
||||
combinations[0].beacon_int_infra_match = true;
|
||||
combinations[0].beacon_int_min_gcd = 100;
|
||||
|
||||
if (ab->hw_params.support_dual_stations) {
|
||||
limits[0].max = 2;
|
||||
limits[0].types |= BIT(NL80211_IFTYPE_STATION);
|
||||
|
||||
limits[1].max = 1;
|
||||
limits[1].types |= BIT(NL80211_IFTYPE_AP);
|
||||
if (IS_ENABLED(CONFIG_MAC80211_MESH) &&
|
||||
ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT))
|
||||
limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT);
|
||||
|
||||
combinations[0].limits = limits;
|
||||
combinations[0].n_limits = 2;
|
||||
combinations[0].max_interfaces = ab->hw_params.num_vdevs;
|
||||
combinations[0].num_different_channels = 2;
|
||||
combinations[0].beacon_int_infra_match = true;
|
||||
combinations[0].beacon_int_min_gcd = 100;
|
||||
} else {
|
||||
limits[0].max = 1;
|
||||
limits[0].types |= BIT(NL80211_IFTYPE_STATION);
|
||||
|
||||
limits[1].max = 16;
|
||||
limits[1].types |= BIT(NL80211_IFTYPE_AP);
|
||||
|
||||
if (IS_ENABLED(CONFIG_MAC80211_MESH) &&
|
||||
ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT))
|
||||
limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT);
|
||||
|
||||
combinations[0].limits = limits;
|
||||
combinations[0].n_limits = 2;
|
||||
combinations[0].max_interfaces = 16;
|
||||
combinations[0].num_different_channels = 1;
|
||||
combinations[0].beacon_int_infra_match = true;
|
||||
combinations[0].beacon_int_min_gcd = 100;
|
||||
combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
|
||||
BIT(NL80211_CHAN_WIDTH_20) |
|
||||
BIT(NL80211_CHAN_WIDTH_40) |
|
||||
@ -9911,6 +10001,13 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
|
||||
BIT(NL80211_CHAN_WIDTH_160);
|
||||
}
|
||||
|
||||
if (p2p) {
|
||||
limits[1].types |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO);
|
||||
limits[2].max = 1;
|
||||
limits[2].types |= BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
}
|
||||
|
||||
ar->hw->wiphy->iface_combinations = combinations;
|
||||
ar->hw->wiphy->n_iface_combinations = 1;
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#define MHI_TIMEOUT_DEFAULT_MS 20000
|
||||
#define RDDM_DUMP_SIZE 0x420000
|
||||
#define MHI_CB_INVALID 0xff
|
||||
|
||||
static const struct mhi_channel_config ath11k_mhi_channels_qca6390[] = {
|
||||
{
|
||||
@ -158,9 +159,8 @@ void ath11k_mhi_set_mhictrl_reset(struct ath11k_base *ab)
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_PCI, "mhistatus 0x%x\n", val);
|
||||
|
||||
/* Observed on QCA6390 that after SOC_GLOBAL_RESET, MHISTATUS
|
||||
* has SYSERR bit set and thus need to set MHICTRL_RESET
|
||||
* to clear SYSERR.
|
||||
/* After SOC_GLOBAL_RESET, MHISTATUS may still have SYSERR bit set
|
||||
* and thus need to set MHICTRL_RESET to clear SYSERR.
|
||||
*/
|
||||
ath11k_pcic_write32(ab, MHICTRL, MHICTRL_RESET_MASK);
|
||||
|
||||
@ -269,6 +269,7 @@ static void ath11k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
|
||||
enum mhi_callback cb)
|
||||
{
|
||||
struct ath11k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev);
|
||||
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_BOOT, "notify status reason %s\n",
|
||||
ath11k_mhi_op_callback_to_str(cb));
|
||||
@ -279,12 +280,21 @@ static void ath11k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
|
||||
break;
|
||||
case MHI_CB_EE_RDDM:
|
||||
ath11k_warn(ab, "firmware crashed: MHI_CB_EE_RDDM\n");
|
||||
if (ab_pci->mhi_pre_cb == MHI_CB_EE_RDDM) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_BOOT,
|
||||
"do not queue again for consecutive RDDM event\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)))
|
||||
queue_work(ab->workqueue_aux, &ab->reset_work);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ab_pci->mhi_pre_cb = cb;
|
||||
}
|
||||
|
||||
static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl,
|
||||
@ -397,6 +407,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
|
||||
goto free_controller;
|
||||
}
|
||||
|
||||
ab_pci->mhi_pre_cb = MHI_CB_INVALID;
|
||||
ret = mhi_register_controller(mhi_ctrl, ath11k_mhi_config);
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed to register to mhi bus, err = %d\n", ret);
|
||||
|
149
drivers/net/wireless/ath/ath11k/p2p.c
Normal file
149
drivers/net/wireless/ath/ath11k/p2p.c
Normal file
@ -0,0 +1,149 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "core.h"
|
||||
#include "wmi.h"
|
||||
#include "mac.h"
|
||||
#include "p2p.h"
|
||||
|
||||
static void ath11k_p2p_noa_ie_fill(u8 *data, size_t len,
|
||||
const struct ath11k_wmi_p2p_noa_info *noa)
|
||||
{
|
||||
struct ieee80211_p2p_noa_attr *noa_attr;
|
||||
u8 noa_descriptors, ctwindow;
|
||||
bool oppps;
|
||||
__le16 *noa_attr_len;
|
||||
u16 attr_len;
|
||||
int i;
|
||||
|
||||
ctwindow = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_CTWIN_TU);
|
||||
oppps = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS);
|
||||
noa_descriptors = u32_get_bits(noa->noa_attr,
|
||||
WMI_P2P_NOA_INFO_DESC_NUM);
|
||||
|
||||
/* P2P IE */
|
||||
data[0] = WLAN_EID_VENDOR_SPECIFIC;
|
||||
data[1] = len - 2;
|
||||
data[2] = (WLAN_OUI_WFA >> 16) & 0xff;
|
||||
data[3] = (WLAN_OUI_WFA >> 8) & 0xff;
|
||||
data[4] = (WLAN_OUI_WFA >> 0) & 0xff;
|
||||
data[5] = WLAN_OUI_TYPE_WFA_P2P;
|
||||
|
||||
/* NOA ATTR */
|
||||
data[6] = IEEE80211_P2P_ATTR_ABSENCE_NOTICE;
|
||||
noa_attr_len = (__le16 *)&data[7]; /* 2 bytes */
|
||||
noa_attr = (struct ieee80211_p2p_noa_attr *)&data[9];
|
||||
|
||||
noa_attr->index = u32_get_bits(noa->noa_attr,
|
||||
WMI_P2P_NOA_INFO_INDEX);
|
||||
noa_attr->oppps_ctwindow = ctwindow;
|
||||
if (oppps)
|
||||
noa_attr->oppps_ctwindow |= IEEE80211_P2P_OPPPS_ENABLE_BIT;
|
||||
|
||||
for (i = 0; i < noa_descriptors; i++) {
|
||||
noa_attr->desc[i].count = noa->descriptors[i].type_count;
|
||||
noa_attr->desc[i].duration =
|
||||
cpu_to_le32(noa->descriptors[i].duration);
|
||||
noa_attr->desc[i].interval =
|
||||
cpu_to_le32(noa->descriptors[i].interval);
|
||||
noa_attr->desc[i].start_time =
|
||||
cpu_to_le32(noa->descriptors[i].start_time);
|
||||
}
|
||||
|
||||
attr_len = 2; /* index + oppps_ctwindow */
|
||||
attr_len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc);
|
||||
*noa_attr_len = __cpu_to_le16(attr_len);
|
||||
}
|
||||
|
||||
static size_t
|
||||
ath11k_p2p_noa_ie_len_compute(const struct ath11k_wmi_p2p_noa_info *noa)
|
||||
{
|
||||
size_t len = 0;
|
||||
u8 noa_descriptors = u32_get_bits(noa->noa_attr,
|
||||
WMI_P2P_NOA_INFO_DESC_NUM);
|
||||
|
||||
if (!(noa_descriptors) &&
|
||||
!(u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS)))
|
||||
return 0;
|
||||
|
||||
len += 1 + 1 + 4; /* EID + len + OUI */
|
||||
len += 1 + 2; /* noa attr + attr len */
|
||||
len += 1 + 1; /* index + oppps_ctwindow */
|
||||
len += noa_descriptors *
|
||||
sizeof(struct ieee80211_p2p_noa_desc);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void ath11k_p2p_noa_ie_assign(struct ath11k_vif *arvif, void *ie,
|
||||
size_t len)
|
||||
{
|
||||
struct ath11k *ar = arvif->ar;
|
||||
|
||||
lockdep_assert_held(&ar->data_lock);
|
||||
|
||||
kfree(arvif->u.ap.noa_data);
|
||||
|
||||
arvif->u.ap.noa_data = ie;
|
||||
arvif->u.ap.noa_len = len;
|
||||
}
|
||||
|
||||
static void __ath11k_p2p_noa_update(struct ath11k_vif *arvif,
|
||||
const struct ath11k_wmi_p2p_noa_info *noa)
|
||||
{
|
||||
struct ath11k *ar = arvif->ar;
|
||||
void *ie;
|
||||
size_t len;
|
||||
|
||||
lockdep_assert_held(&ar->data_lock);
|
||||
|
||||
ath11k_p2p_noa_ie_assign(arvif, NULL, 0);
|
||||
|
||||
len = ath11k_p2p_noa_ie_len_compute(noa);
|
||||
if (!len)
|
||||
return;
|
||||
|
||||
ie = kmalloc(len, GFP_ATOMIC);
|
||||
if (!ie)
|
||||
return;
|
||||
|
||||
ath11k_p2p_noa_ie_fill(ie, len, noa);
|
||||
ath11k_p2p_noa_ie_assign(arvif, ie, len); }
|
||||
|
||||
void ath11k_p2p_noa_update(struct ath11k_vif *arvif,
|
||||
const struct ath11k_wmi_p2p_noa_info *noa)
|
||||
{
|
||||
struct ath11k *ar = arvif->ar;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
__ath11k_p2p_noa_update(arvif, noa);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
|
||||
static void ath11k_p2p_noa_update_vdev_iter(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
|
||||
struct ath11k_p2p_noa_arg *arg = data;
|
||||
|
||||
if (arvif->vdev_id != arg->vdev_id)
|
||||
return;
|
||||
|
||||
ath11k_p2p_noa_update(arvif, arg->noa);
|
||||
}
|
||||
|
||||
void ath11k_p2p_noa_update_by_vdev_id(struct ath11k *ar, u32 vdev_id,
|
||||
const struct ath11k_wmi_p2p_noa_info *noa)
|
||||
{
|
||||
struct ath11k_p2p_noa_arg arg = {
|
||||
.vdev_id = vdev_id,
|
||||
.noa = noa,
|
||||
};
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(ar->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
ath11k_p2p_noa_update_vdev_iter,
|
||||
&arg);
|
||||
}
|
22
drivers/net/wireless/ath/ath11k/p2p.h
Normal file
22
drivers/net/wireless/ath/ath11k/p2p.h
Normal file
@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_P2P_H
|
||||
#define ATH11K_P2P_H
|
||||
|
||||
#include "wmi.h"
|
||||
|
||||
struct ath11k_wmi_p2p_noa_info;
|
||||
|
||||
struct ath11k_p2p_noa_arg {
|
||||
u32 vdev_id;
|
||||
const struct ath11k_wmi_p2p_noa_info *noa;
|
||||
};
|
||||
|
||||
void ath11k_p2p_noa_update(struct ath11k_vif *arvif,
|
||||
const struct ath11k_wmi_p2p_noa_info *noa);
|
||||
void ath11k_p2p_noa_update_by_vdev_id(struct ath11k *ar, u32 vdev_id,
|
||||
const struct ath11k_wmi_p2p_noa_info *noa);
|
||||
#endif
|
@ -64,6 +64,7 @@ struct ath11k_pci {
|
||||
char amss_path[100];
|
||||
struct mhi_controller *mhi_ctrl;
|
||||
const struct ath11k_msi_config *msi_config;
|
||||
enum mhi_callback mhi_pre_cb;
|
||||
u32 register_window;
|
||||
|
||||
/* protects register_window above */
|
||||
|
@ -101,7 +101,7 @@ static ssize_t ath11k_thermal_show_temp(struct device *dev,
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
/* display in millidegree Celsius */
|
||||
ret = snprintf(buf, PAGE_SIZE, "%d\n", temperature * 1000);
|
||||
ret = sysfs_emit(buf, "%d\n", temperature * 1000);
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "hw.h"
|
||||
#include "peer.h"
|
||||
#include "testmode.h"
|
||||
#include "p2p.h"
|
||||
|
||||
struct wmi_tlv_policy {
|
||||
size_t min_len;
|
||||
@ -154,6 +155,10 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = {
|
||||
.min_len = sizeof(struct wmi_per_chain_rssi_stats) },
|
||||
[WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT] = {
|
||||
.min_len = sizeof(struct wmi_twt_add_dialog_event) },
|
||||
[WMI_TAG_P2P_NOA_INFO] = {
|
||||
.min_len = sizeof(struct ath11k_wmi_p2p_noa_info) },
|
||||
[WMI_TAG_P2P_NOA_EVENT] = {
|
||||
.min_len = sizeof(struct wmi_p2p_noa_event) },
|
||||
};
|
||||
|
||||
#define PRIMAP(_hw_mode_) \
|
||||
@ -981,7 +986,7 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
|
||||
FIELD_PREP(WMI_TLV_LEN, 0);
|
||||
|
||||
/* Note: This is a nested TLV containing:
|
||||
* [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv]..
|
||||
* [wmi_tlv][ath11k_wmi_p2p_noa_descriptor][wmi_tlv]..
|
||||
*/
|
||||
|
||||
ptr += sizeof(*tlv);
|
||||
@ -1704,6 +1709,45 @@ int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
|
||||
const u8 *p2p_ie)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct wmi_p2p_go_set_beacon_ie_cmd *cmd;
|
||||
size_t p2p_ie_len, aligned_len;
|
||||
struct wmi_tlv *tlv;
|
||||
struct sk_buff *skb;
|
||||
int ret, len;
|
||||
|
||||
p2p_ie_len = p2p_ie[1] + 2;
|
||||
aligned_len = roundup(p2p_ie_len, 4);
|
||||
|
||||
len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_p2p_go_set_beacon_ie_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_P2P_GO_SET_BEACON_IE) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
cmd->vdev_id = vdev_id;
|
||||
cmd->ie_buf_len = p2p_ie_len;
|
||||
|
||||
tlv = (struct wmi_tlv *)cmd->tlv;
|
||||
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
|
||||
FIELD_PREP(WMI_TLV_LEN, aligned_len);
|
||||
memcpy(tlv->value, p2p_ie, p2p_ie_len);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
|
||||
struct ieee80211_mutable_offsets *offs,
|
||||
struct sk_buff *bcn, u32 ema_params)
|
||||
@ -8606,6 +8650,64 @@ static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base *ab,
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static int ath11k_wmi_p2p_noa_event(struct ath11k_base *ab,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const void **tb;
|
||||
const struct wmi_p2p_noa_event *ev;
|
||||
const struct ath11k_wmi_p2p_noa_info *noa;
|
||||
struct ath11k *ar;
|
||||
int ret, vdev_id;
|
||||
u8 noa_descriptors;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ev = tb[WMI_TAG_P2P_NOA_EVENT];
|
||||
noa = tb[WMI_TAG_P2P_NOA_INFO];
|
||||
|
||||
if (!ev || !noa) {
|
||||
ret = -EPROTO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
vdev_id = ev->vdev_id;
|
||||
noa_descriptors = u32_get_bits(noa->noa_attr,
|
||||
WMI_P2P_NOA_INFO_DESC_NUM);
|
||||
|
||||
if (noa_descriptors > WMI_P2P_MAX_NOA_DESCRIPTORS) {
|
||||
ath11k_warn(ab, "invalid descriptor num %d in P2P NoA event\n",
|
||||
noa_descriptors);
|
||||
return -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
"wmi tlv p2p noa vdev_id %i descriptors %u\n",
|
||||
vdev_id, noa_descriptors);
|
||||
|
||||
rcu_read_lock();
|
||||
ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id);
|
||||
if (!ar) {
|
||||
ath11k_warn(ab, "invalid vdev id %d in P2P NoA event\n",
|
||||
vdev_id);
|
||||
ret = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ath11k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa);
|
||||
|
||||
unlock:
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_cmd_hdr *cmd_hdr;
|
||||
@ -8733,6 +8835,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
case WMI_GTK_OFFLOAD_STATUS_EVENTID:
|
||||
ath11k_wmi_gtk_offload_status_event(ab, skb);
|
||||
break;
|
||||
case WMI_P2P_NOA_EVENTID:
|
||||
ath11k_wmi_p2p_noa_event(ab, skb);
|
||||
break;
|
||||
default:
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id);
|
||||
break;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_WMI_H
|
||||
@ -60,13 +60,9 @@ struct wmi_tlv {
|
||||
#define WLAN_SCAN_MAX_HINT_BSSID 10
|
||||
#define MAX_RNR_BSS 5
|
||||
|
||||
#define WLAN_SCAN_MAX_HINT_S_SSID 10
|
||||
#define WLAN_SCAN_MAX_HINT_BSSID 10
|
||||
#define MAX_RNR_BSS 5
|
||||
|
||||
#define WLAN_SCAN_PARAMS_MAX_SSID 16
|
||||
#define WLAN_SCAN_PARAMS_MAX_BSSID 4
|
||||
#define WLAN_SCAN_PARAMS_MAX_IE_LEN 256
|
||||
#define WLAN_SCAN_PARAMS_MAX_IE_LEN 512
|
||||
|
||||
#define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1
|
||||
|
||||
@ -3444,34 +3440,6 @@ struct wmi_bssid_arg {
|
||||
const u8 *bssid;
|
||||
};
|
||||
|
||||
struct wmi_start_scan_arg {
|
||||
u32 scan_id;
|
||||
u32 scan_req_id;
|
||||
u32 vdev_id;
|
||||
u32 scan_priority;
|
||||
u32 notify_scan_events;
|
||||
u32 dwell_time_active;
|
||||
u32 dwell_time_passive;
|
||||
u32 min_rest_time;
|
||||
u32 max_rest_time;
|
||||
u32 repeat_probe_time;
|
||||
u32 probe_spacing_time;
|
||||
u32 idle_time;
|
||||
u32 max_scan_time;
|
||||
u32 probe_delay;
|
||||
u32 scan_ctrl_flags;
|
||||
|
||||
u32 ie_len;
|
||||
u32 n_channels;
|
||||
u32 n_ssids;
|
||||
u32 n_bssids;
|
||||
|
||||
u8 ie[WLAN_SCAN_PARAMS_MAX_IE_LEN];
|
||||
u32 channels[64];
|
||||
struct wmi_ssid_arg ssids[WLAN_SCAN_PARAMS_MAX_SSID];
|
||||
struct wmi_bssid_arg bssids[WLAN_SCAN_PARAMS_MAX_BSSID];
|
||||
};
|
||||
|
||||
#define WMI_SCAN_STOP_ONE 0x00000000
|
||||
#define WMI_SCN_STOP_VAP_ALL 0x01000000
|
||||
#define WMI_SCAN_STOP_ALL 0x04000000
|
||||
@ -3630,6 +3598,37 @@ struct wmi_ftm_event_msg {
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
#define WMI_P2P_MAX_NOA_DESCRIPTORS 4
|
||||
|
||||
struct wmi_p2p_noa_event {
|
||||
u32 vdev_id;
|
||||
} __packed;
|
||||
|
||||
struct ath11k_wmi_p2p_noa_descriptor {
|
||||
u32 type_count; /* 255: continuous schedule, 0: reserved */
|
||||
u32 duration; /* Absent period duration in micro seconds */
|
||||
u32 interval; /* Absent period interval in micro seconds */
|
||||
u32 start_time; /* 32 bit tsf time when in starts */
|
||||
} __packed;
|
||||
|
||||
#define WMI_P2P_NOA_INFO_CHANGED_FLAG BIT(0)
|
||||
#define WMI_P2P_NOA_INFO_INDEX GENMASK(15, 8)
|
||||
#define WMI_P2P_NOA_INFO_OPP_PS BIT(16)
|
||||
#define WMI_P2P_NOA_INFO_CTWIN_TU GENMASK(23, 17)
|
||||
#define WMI_P2P_NOA_INFO_DESC_NUM GENMASK(31, 24)
|
||||
|
||||
struct ath11k_wmi_p2p_noa_info {
|
||||
/* Bit 0 - Flag to indicate an update in NOA schedule
|
||||
* Bits 7-1 - Reserved
|
||||
* Bits 15-8 - Index (identifies the instance of NOA sub element)
|
||||
* Bit 16 - Opp PS state of the AP
|
||||
* Bits 23-17 - Ctwindow in TUs
|
||||
* Bits 31-24 - Number of NOA descriptors
|
||||
*/
|
||||
u32 noa_attr;
|
||||
struct ath11k_wmi_p2p_noa_descriptor descriptors[WMI_P2P_MAX_NOA_DESCRIPTORS];
|
||||
} __packed;
|
||||
|
||||
#define WMI_BEACON_TX_BUFFER_SIZE 512
|
||||
|
||||
#define WMI_EMA_TMPL_IDX_SHIFT 8
|
||||
@ -3653,6 +3652,13 @@ struct wmi_bcn_tmpl_cmd {
|
||||
u32 ema_params;
|
||||
} __packed;
|
||||
|
||||
struct wmi_p2p_go_set_beacon_ie_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
u32 ie_buf_len;
|
||||
u8 tlv[];
|
||||
} __packed;
|
||||
|
||||
struct wmi_key_seq_counter {
|
||||
u32 key_seq_counter_l;
|
||||
u32 key_seq_counter_h;
|
||||
@ -5740,8 +5746,6 @@ struct wmi_debug_log_config_cmd_fixed_param {
|
||||
u32 value;
|
||||
} __packed;
|
||||
|
||||
#define WMI_MAX_MEM_REQS 32
|
||||
|
||||
#define MAX_RADIOS 3
|
||||
|
||||
#define WMI_SERVICE_READY_TIMEOUT_HZ (5 * HZ)
|
||||
@ -6349,6 +6353,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
|
||||
struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len);
|
||||
int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
|
||||
struct sk_buff *frame);
|
||||
int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
|
||||
const u8 *p2p_ie);
|
||||
int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
|
||||
struct ieee80211_mutable_offsets *offs,
|
||||
struct sk_buff *bcn, u32 ema_param);
|
||||
|
@ -960,8 +960,9 @@ int ath12k_dp_service_srng(struct ath12k_base *ab,
|
||||
if (ab->hw_params->ring_mask->host2rxdma[grp_id]) {
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
|
||||
LIST_HEAD(list);
|
||||
|
||||
ath12k_dp_rx_bufs_replenish(ab, rx_ring, 0);
|
||||
ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0);
|
||||
}
|
||||
|
||||
/* TODO: Implement handler for other interrupts */
|
||||
@ -1146,11 +1147,11 @@ void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_vif *arvif)
|
||||
|
||||
static void ath12k_dp_cc_cleanup(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k_rx_desc_info *desc_info, *tmp;
|
||||
struct ath12k_rx_desc_info *desc_info;
|
||||
struct ath12k_tx_desc_info *tx_desc_info, *tmp1;
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
struct sk_buff *skb;
|
||||
int i;
|
||||
int i, j;
|
||||
u32 pool_id, tx_spt_page;
|
||||
|
||||
if (!dp->spt_info)
|
||||
@ -1159,16 +1160,23 @@ static void ath12k_dp_cc_cleanup(struct ath12k_base *ab)
|
||||
/* RX Descriptor cleanup */
|
||||
spin_lock_bh(&dp->rx_desc_lock);
|
||||
|
||||
list_for_each_entry_safe(desc_info, tmp, &dp->rx_desc_used_list, list) {
|
||||
list_del(&desc_info->list);
|
||||
skb = desc_info->skb;
|
||||
for (i = 0; i < ATH12K_NUM_RX_SPT_PAGES; i++) {
|
||||
desc_info = dp->spt_info->rxbaddr[i];
|
||||
|
||||
if (!skb)
|
||||
continue;
|
||||
for (j = 0; j < ATH12K_MAX_SPT_ENTRIES; j++) {
|
||||
if (!desc_info[j].in_use) {
|
||||
list_del(&desc_info[j].list);
|
||||
continue;
|
||||
}
|
||||
|
||||
dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(skb)->paddr,
|
||||
skb->len + skb_tailroom(skb), DMA_FROM_DEVICE);
|
||||
dev_kfree_skb_any(skb);
|
||||
skb = desc_info[j].skb;
|
||||
if (!skb)
|
||||
continue;
|
||||
|
||||
dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(skb)->paddr,
|
||||
skb->len + skb_tailroom(skb), DMA_FROM_DEVICE);
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ATH12K_NUM_RX_SPT_PAGES; i++) {
|
||||
@ -1444,7 +1452,6 @@ static int ath12k_dp_cc_init(struct ath12k_base *ab)
|
||||
u32 cmem_base;
|
||||
|
||||
INIT_LIST_HEAD(&dp->rx_desc_free_list);
|
||||
INIT_LIST_HEAD(&dp->rx_desc_used_list);
|
||||
spin_lock_init(&dp->rx_desc_lock);
|
||||
|
||||
for (i = 0; i < ATH12K_HW_MAX_QUEUES; i++) {
|
||||
|
@ -282,6 +282,8 @@ struct ath12k_rx_desc_info {
|
||||
struct sk_buff *skb;
|
||||
u32 cookie;
|
||||
u32 magic;
|
||||
u8 in_use : 1,
|
||||
reserved : 7;
|
||||
};
|
||||
|
||||
struct ath12k_tx_desc_info {
|
||||
@ -347,8 +349,7 @@ struct ath12k_dp {
|
||||
struct ath12k_spt_info *spt_info;
|
||||
u32 num_spt_pages;
|
||||
struct list_head rx_desc_free_list;
|
||||
struct list_head rx_desc_used_list;
|
||||
/* protects the free and used desc list */
|
||||
/* protects the free desc list */
|
||||
spinlock_t rx_desc_lock;
|
||||
|
||||
struct list_head tx_desc_free_list[ATH12K_HW_MAX_QUEUES];
|
||||
@ -377,8 +378,6 @@ struct ath12k_dp {
|
||||
/* peer meta data */
|
||||
#define HTT_TCL_META_DATA_PEER_ID GENMASK(15, 2)
|
||||
|
||||
#define HTT_TX_WBM_COMP_STATUS_OFFSET 8
|
||||
|
||||
/* HTT tx completion is overlaid in wbm_release_ring */
|
||||
#define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(16, 13)
|
||||
#define HTT_TX_WBM_COMP_INFO1_REINJECT_REASON GENMASK(3, 0)
|
||||
|
@ -261,9 +261,53 @@ static int ath12k_dp_purge_mon_ring(struct ath12k_base *ab)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static size_t ath12k_dp_list_cut_nodes(struct list_head *list,
|
||||
struct list_head *head,
|
||||
size_t count)
|
||||
{
|
||||
struct list_head *cur;
|
||||
struct ath12k_rx_desc_info *rx_desc;
|
||||
size_t nodes = 0;
|
||||
|
||||
if (!count) {
|
||||
INIT_LIST_HEAD(list);
|
||||
goto out;
|
||||
}
|
||||
|
||||
list_for_each(cur, head) {
|
||||
if (!count)
|
||||
break;
|
||||
|
||||
rx_desc = list_entry(cur, struct ath12k_rx_desc_info, list);
|
||||
rx_desc->in_use = true;
|
||||
|
||||
count--;
|
||||
nodes++;
|
||||
}
|
||||
|
||||
list_cut_before(list, head, cur);
|
||||
out:
|
||||
return nodes;
|
||||
}
|
||||
|
||||
static void ath12k_dp_rx_enqueue_free(struct ath12k_dp *dp,
|
||||
struct list_head *used_list)
|
||||
{
|
||||
struct ath12k_rx_desc_info *rx_desc, *safe;
|
||||
|
||||
/* Reset the use flag */
|
||||
list_for_each_entry_safe(rx_desc, safe, used_list, list)
|
||||
rx_desc->in_use = false;
|
||||
|
||||
spin_lock_bh(&dp->rx_desc_lock);
|
||||
list_splice_tail(used_list, &dp->rx_desc_free_list);
|
||||
spin_unlock_bh(&dp->rx_desc_lock);
|
||||
}
|
||||
|
||||
/* Returns number of Rx buffers replenished */
|
||||
int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab,
|
||||
struct dp_rxdma_ring *rx_ring,
|
||||
struct list_head *used_list,
|
||||
int req_entries)
|
||||
{
|
||||
struct ath12k_buffer_addr *desc;
|
||||
@ -292,6 +336,19 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab,
|
||||
req_entries = min(num_free, req_entries);
|
||||
num_remain = req_entries;
|
||||
|
||||
if (!num_remain)
|
||||
goto out;
|
||||
|
||||
/* Get the descriptor from free list */
|
||||
if (list_empty(used_list)) {
|
||||
spin_lock_bh(&dp->rx_desc_lock);
|
||||
req_entries = ath12k_dp_list_cut_nodes(used_list,
|
||||
&dp->rx_desc_free_list,
|
||||
num_remain);
|
||||
spin_unlock_bh(&dp->rx_desc_lock);
|
||||
num_remain = req_entries;
|
||||
}
|
||||
|
||||
while (num_remain > 0) {
|
||||
skb = dev_alloc_skb(DP_RX_BUFFER_SIZE +
|
||||
DP_RX_BUFFER_ALIGN_SIZE);
|
||||
@ -311,33 +368,20 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab,
|
||||
if (dma_mapping_error(ab->dev, paddr))
|
||||
goto fail_free_skb;
|
||||
|
||||
spin_lock_bh(&dp->rx_desc_lock);
|
||||
|
||||
/* Get desc from free list and store in used list
|
||||
* for cleanup purposes
|
||||
*
|
||||
* TODO: pass the removed descs rather than
|
||||
* add/read to optimize
|
||||
*/
|
||||
rx_desc = list_first_entry_or_null(&dp->rx_desc_free_list,
|
||||
rx_desc = list_first_entry_or_null(used_list,
|
||||
struct ath12k_rx_desc_info,
|
||||
list);
|
||||
if (!rx_desc) {
|
||||
spin_unlock_bh(&dp->rx_desc_lock);
|
||||
if (!rx_desc)
|
||||
goto fail_dma_unmap;
|
||||
}
|
||||
|
||||
rx_desc->skb = skb;
|
||||
cookie = rx_desc->cookie;
|
||||
list_del(&rx_desc->list);
|
||||
list_add_tail(&rx_desc->list, &dp->rx_desc_used_list);
|
||||
|
||||
spin_unlock_bh(&dp->rx_desc_lock);
|
||||
|
||||
desc = ath12k_hal_srng_src_get_next_entry(ab, srng);
|
||||
if (!desc)
|
||||
goto fail_buf_unassign;
|
||||
goto fail_dma_unmap;
|
||||
|
||||
list_del(&rx_desc->list);
|
||||
ATH12K_SKB_RXCB(skb)->paddr = paddr;
|
||||
|
||||
num_remain--;
|
||||
@ -345,26 +389,19 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab,
|
||||
ath12k_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr);
|
||||
}
|
||||
|
||||
ath12k_hal_srng_access_end(ab, srng);
|
||||
goto out;
|
||||
|
||||
spin_unlock_bh(&srng->lock);
|
||||
|
||||
return req_entries - num_remain;
|
||||
|
||||
fail_buf_unassign:
|
||||
spin_lock_bh(&dp->rx_desc_lock);
|
||||
list_del(&rx_desc->list);
|
||||
list_add_tail(&rx_desc->list, &dp->rx_desc_free_list);
|
||||
rx_desc->skb = NULL;
|
||||
spin_unlock_bh(&dp->rx_desc_lock);
|
||||
fail_dma_unmap:
|
||||
dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb),
|
||||
DMA_FROM_DEVICE);
|
||||
fail_free_skb:
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
out:
|
||||
ath12k_hal_srng_access_end(ab, srng);
|
||||
|
||||
if (!list_empty(used_list))
|
||||
ath12k_dp_rx_enqueue_free(dp, used_list);
|
||||
|
||||
spin_unlock_bh(&srng->lock);
|
||||
|
||||
return req_entries - num_remain;
|
||||
@ -422,13 +459,12 @@ static int ath12k_dp_rxdma_mon_ring_buf_setup(struct ath12k_base *ab,
|
||||
static int ath12k_dp_rxdma_ring_buf_setup(struct ath12k_base *ab,
|
||||
struct dp_rxdma_ring *rx_ring)
|
||||
{
|
||||
int num_entries;
|
||||
LIST_HEAD(list);
|
||||
|
||||
num_entries = rx_ring->refill_buf_ring.size /
|
||||
ath12k_hal_srng_get_entrysize(ab, HAL_RXDMA_BUF);
|
||||
rx_ring->bufs_max = rx_ring->refill_buf_ring.size /
|
||||
ath12k_hal_srng_get_entrysize(ab, HAL_RXDMA_BUF);
|
||||
|
||||
rx_ring->bufs_max = num_entries;
|
||||
ath12k_dp_rx_bufs_replenish(ab, rx_ring, num_entries);
|
||||
ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2585,6 +2621,7 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab,
|
||||
int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id,
|
||||
struct napi_struct *napi, int budget)
|
||||
{
|
||||
LIST_HEAD(rx_desc_used_list);
|
||||
struct ath12k_rx_desc_info *desc_info;
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
|
||||
@ -2637,9 +2674,7 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id,
|
||||
msdu = desc_info->skb;
|
||||
desc_info->skb = NULL;
|
||||
|
||||
spin_lock_bh(&dp->rx_desc_lock);
|
||||
list_move_tail(&desc_info->list, &dp->rx_desc_free_list);
|
||||
spin_unlock_bh(&dp->rx_desc_lock);
|
||||
list_add_tail(&desc_info->list, &rx_desc_used_list);
|
||||
|
||||
rxcb = ATH12K_SKB_RXCB(msdu);
|
||||
dma_unmap_single(ab->dev, rxcb->paddr,
|
||||
@ -2700,7 +2735,8 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id,
|
||||
if (!total_msdu_reaped)
|
||||
goto exit;
|
||||
|
||||
ath12k_dp_rx_bufs_replenish(ab, rx_ring, num_buffs_reaped);
|
||||
ath12k_dp_rx_bufs_replenish(ab, rx_ring, &rx_desc_used_list,
|
||||
num_buffs_reaped);
|
||||
|
||||
ath12k_dp_rx_process_received_packets(ab, napi, &msdu_list,
|
||||
ring_id);
|
||||
@ -3021,9 +3057,9 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar,
|
||||
}
|
||||
|
||||
desc_info->skb = defrag_skb;
|
||||
desc_info->in_use = true;
|
||||
|
||||
list_del(&desc_info->list);
|
||||
list_add_tail(&desc_info->list, &dp->rx_desc_used_list);
|
||||
spin_unlock_bh(&dp->rx_desc_lock);
|
||||
|
||||
ATH12K_SKB_RXCB(defrag_skb)->paddr = buf_paddr;
|
||||
@ -3085,9 +3121,9 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar,
|
||||
|
||||
err_free_desc:
|
||||
spin_lock_bh(&dp->rx_desc_lock);
|
||||
list_del(&desc_info->list);
|
||||
list_add_tail(&desc_info->list, &dp->rx_desc_free_list);
|
||||
desc_info->in_use = false;
|
||||
desc_info->skb = NULL;
|
||||
list_add_tail(&desc_info->list, &dp->rx_desc_free_list);
|
||||
spin_unlock_bh(&dp->rx_desc_lock);
|
||||
err_unmap_dma:
|
||||
dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb),
|
||||
@ -3304,6 +3340,7 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
|
||||
|
||||
static int
|
||||
ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc,
|
||||
struct list_head *used_list,
|
||||
bool drop, u32 cookie)
|
||||
{
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
@ -3333,9 +3370,8 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc,
|
||||
|
||||
msdu = desc_info->skb;
|
||||
desc_info->skb = NULL;
|
||||
spin_lock_bh(&ab->dp.rx_desc_lock);
|
||||
list_move_tail(&desc_info->list, &ab->dp.rx_desc_free_list);
|
||||
spin_unlock_bh(&ab->dp.rx_desc_lock);
|
||||
|
||||
list_add_tail(&desc_info->list, used_list);
|
||||
|
||||
rxcb = ATH12K_SKB_RXCB(msdu);
|
||||
dma_unmap_single(ar->ab->dev, rxcb->paddr,
|
||||
@ -3391,6 +3427,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
||||
struct hal_reo_dest_ring *reo_desc;
|
||||
struct dp_rxdma_ring *rx_ring;
|
||||
struct dp_srng *reo_except;
|
||||
LIST_HEAD(rx_desc_used_list);
|
||||
u32 desc_bank, num_msdus;
|
||||
struct hal_srng *srng;
|
||||
struct ath12k_dp *dp;
|
||||
@ -3458,7 +3495,9 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
||||
pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id);
|
||||
ar = ab->pdevs[pdev_id].ar;
|
||||
|
||||
if (!ath12k_dp_process_rx_err_buf(ar, reo_desc, drop,
|
||||
if (!ath12k_dp_process_rx_err_buf(ar, reo_desc,
|
||||
&rx_desc_used_list,
|
||||
drop,
|
||||
msdu_cookies[i]))
|
||||
tot_n_bufs_reaped++;
|
||||
}
|
||||
@ -3478,7 +3517,8 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
||||
|
||||
rx_ring = &dp->rx_refill_buf_ring;
|
||||
|
||||
ath12k_dp_rx_bufs_replenish(ab, rx_ring, tot_n_bufs_reaped);
|
||||
ath12k_dp_rx_bufs_replenish(ab, rx_ring, &rx_desc_used_list,
|
||||
tot_n_bufs_reaped);
|
||||
|
||||
return tot_n_bufs_reaped;
|
||||
}
|
||||
@ -3695,6 +3735,7 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar,
|
||||
int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
|
||||
struct napi_struct *napi, int budget)
|
||||
{
|
||||
LIST_HEAD(rx_desc_used_list);
|
||||
struct ath12k *ar;
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
struct dp_rxdma_ring *rx_ring;
|
||||
@ -3748,9 +3789,7 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
|
||||
msdu = desc_info->skb;
|
||||
desc_info->skb = NULL;
|
||||
|
||||
spin_lock_bh(&dp->rx_desc_lock);
|
||||
list_move_tail(&desc_info->list, &dp->rx_desc_free_list);
|
||||
spin_unlock_bh(&dp->rx_desc_lock);
|
||||
list_add_tail(&desc_info->list, &rx_desc_used_list);
|
||||
|
||||
rxcb = ATH12K_SKB_RXCB(msdu);
|
||||
dma_unmap_single(ab->dev, rxcb->paddr,
|
||||
@ -3786,7 +3825,8 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
|
||||
if (!num_buffs_reaped)
|
||||
goto done;
|
||||
|
||||
ath12k_dp_rx_bufs_replenish(ab, rx_ring, num_buffs_reaped);
|
||||
ath12k_dp_rx_bufs_replenish(ab, rx_ring, &rx_desc_used_list,
|
||||
num_buffs_reaped);
|
||||
|
||||
rcu_read_lock();
|
||||
while ((msdu = __skb_dequeue(&msdu_list))) {
|
||||
|
@ -118,6 +118,7 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id,
|
||||
int budget);
|
||||
int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab,
|
||||
struct dp_rxdma_ring *rx_ring,
|
||||
struct list_head *used_list,
|
||||
int req_entries);
|
||||
int ath12k_dp_rx_pdev_mon_attach(struct ath12k *ar);
|
||||
int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id);
|
||||
|
@ -414,7 +414,7 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab,
|
||||
struct ath12k_dp_htt_wbm_tx_status ts = {0};
|
||||
enum hal_wbm_htt_tx_comp_status wbm_status;
|
||||
|
||||
status_desc = desc + HTT_TX_WBM_COMP_STATUS_OFFSET;
|
||||
status_desc = desc;
|
||||
|
||||
wbm_status = le32_get_bits(status_desc->info0,
|
||||
HTT_TX_WBM_COMP_INFO0_STATUS);
|
||||
|
@ -1900,7 +1900,7 @@ static void ath12k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd,
|
||||
if (arg->bw_160)
|
||||
cmd->peer_flags |= cpu_to_le32(WMI_PEER_160MHZ);
|
||||
if (arg->bw_320)
|
||||
cmd->peer_flags |= cpu_to_le32(WMI_PEER_EXT_320MHZ);
|
||||
cmd->peer_flags_ext |= cpu_to_le32(WMI_PEER_EXT_320MHZ);
|
||||
|
||||
/* Typically if STBC is enabled for VHT it should be enabled
|
||||
* for HT as well
|
||||
|
@ -164,10 +164,6 @@ struct wmi_tlv {
|
||||
#define WLAN_SCAN_MAX_HINT_BSSID 10
|
||||
#define MAX_RNR_BSS 5
|
||||
|
||||
#define WLAN_SCAN_MAX_HINT_S_SSID 10
|
||||
#define WLAN_SCAN_MAX_HINT_BSSID 10
|
||||
#define MAX_RNR_BSS 5
|
||||
|
||||
#define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1
|
||||
|
||||
#define WMI_BA_MODE_BUFFER_SIZE_256 3
|
||||
@ -3357,34 +3353,6 @@ struct wmi_bssid_arg {
|
||||
const u8 *bssid;
|
||||
};
|
||||
|
||||
struct wmi_start_scan_arg {
|
||||
u32 scan_id;
|
||||
u32 scan_req_id;
|
||||
u32 vdev_id;
|
||||
u32 scan_priority;
|
||||
u32 notify_scan_events;
|
||||
u32 dwell_time_active;
|
||||
u32 dwell_time_passive;
|
||||
u32 min_rest_time;
|
||||
u32 max_rest_time;
|
||||
u32 repeat_probe_time;
|
||||
u32 probe_spacing_time;
|
||||
u32 idle_time;
|
||||
u32 max_scan_time;
|
||||
u32 probe_delay;
|
||||
u32 scan_ctrl_flags;
|
||||
|
||||
u32 ie_len;
|
||||
u32 n_channels;
|
||||
u32 n_ssids;
|
||||
u32 n_bssids;
|
||||
|
||||
u8 ie[WLAN_SCAN_PARAMS_MAX_IE_LEN];
|
||||
u32 channels[64];
|
||||
struct wmi_ssid_arg ssids[WLAN_SCAN_PARAMS_MAX_SSID];
|
||||
struct wmi_bssid_arg bssids[WLAN_SCAN_PARAMS_MAX_BSSID];
|
||||
};
|
||||
|
||||
#define WMI_SCAN_STOP_ONE 0x00000000
|
||||
#define WMI_SCAN_STOP_VAP_ALL 0x01000000
|
||||
#define WMI_SCAN_STOP_ALL 0x04000000
|
||||
@ -4776,8 +4744,6 @@ struct wmi_probe_tmpl_cmd {
|
||||
__le32 buf_len;
|
||||
} __packed;
|
||||
|
||||
#define WMI_MAX_MEM_REQS 32
|
||||
|
||||
#define MAX_RADIOS 3
|
||||
|
||||
#define WMI_SERVICE_READY_TIMEOUT_HZ (5 * HZ)
|
||||
|
@ -364,8 +364,7 @@ static void ath6kl_htc_tx_prep_pkt(struct htc_packet *packet, u8 flags,
|
||||
packet->buf -= HTC_HDR_LENGTH;
|
||||
hdr = (struct htc_frame_hdr *)packet->buf;
|
||||
|
||||
/* Endianess? */
|
||||
put_unaligned((u16)packet->act_len, &hdr->payld_len);
|
||||
put_unaligned_le16(packet->act_len, &hdr->payld_len);
|
||||
hdr->flags = flags;
|
||||
hdr->eid = packet->endpoint;
|
||||
hdr->ctrl[0] = ctrl0;
|
||||
|
@ -237,8 +237,7 @@ static int htc_issue_packets(struct htc_target *target,
|
||||
|
||||
packet->info.tx.flags |= HTC_FLAGS_TX_FIXUP_NETBUF;
|
||||
|
||||
/* Endianess? */
|
||||
put_unaligned((u16) payload_len, &htc_hdr->payld_len);
|
||||
put_unaligned_le16(payload_len, &htc_hdr->payld_len);
|
||||
htc_hdr->flags = packet->info.tx.flags;
|
||||
htc_hdr->eid = (u8) packet->endpoint;
|
||||
htc_hdr->ctrl[0] = 0;
|
||||
|
@ -39,6 +39,7 @@ extern int ath9k_modparam_nohwcrypt;
|
||||
extern int ath9k_led_blink;
|
||||
extern bool is_ath9k_unloaded;
|
||||
extern int ath9k_use_chanctx;
|
||||
extern int ath9k_use_msi;
|
||||
|
||||
/*************************/
|
||||
/* Descriptor Management */
|
||||
|
@ -76,7 +76,7 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
|
||||
static u32 ath9k_dump_4k_modal_eeprom(char *buf, u32 len, u32 size,
|
||||
struct modal_eep_4k_header *modal_hdr)
|
||||
{
|
||||
PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
|
||||
PR_EEP("Chain0 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[0]));
|
||||
PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
|
||||
PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
|
||||
PR_EEP("Switch Settle", modal_hdr->switchSettling);
|
||||
|
@ -79,8 +79,8 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
|
||||
static u32 ar9287_dump_modal_eeprom(char *buf, u32 len, u32 size,
|
||||
struct modal_eep_ar9287_header *modal_hdr)
|
||||
{
|
||||
PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
|
||||
PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
|
||||
PR_EEP("Chain0 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[0]));
|
||||
PR_EEP("Chain1 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[1]));
|
||||
PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
|
||||
PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
|
||||
PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
|
||||
|
@ -135,9 +135,9 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
|
||||
static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size,
|
||||
struct modal_eep_header *modal_hdr)
|
||||
{
|
||||
PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
|
||||
PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
|
||||
PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
|
||||
PR_EEP("Chain0 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[0]));
|
||||
PR_EEP("Chain1 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[1]));
|
||||
PR_EEP("Chain2 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[2]));
|
||||
PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
|
||||
PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
|
||||
PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
|
||||
|
@ -21,8 +21,6 @@
|
||||
#include <linux/module.h>
|
||||
#include "ath9k.h"
|
||||
|
||||
extern int ath9k_use_msi;
|
||||
|
||||
static const struct pci_device_id ath_pci_id_table[] = {
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
|
||||
|
@ -1674,8 +1674,14 @@ static void
|
||||
ath9k_set_moredata(struct ath_softc *sc, struct ath_buf *bf, bool val)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
u16 mask = cpu_to_le16(IEEE80211_FCTL_MOREDATA);
|
||||
u16 mask_val = mask * val;
|
||||
__le16 mask, mask_val;
|
||||
|
||||
mask = cpu_to_le16(IEEE80211_FCTL_MOREDATA);
|
||||
|
||||
if (val)
|
||||
mask_val = mask;
|
||||
else
|
||||
mask_val = 0;
|
||||
|
||||
hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data;
|
||||
if ((hdr->frame_control & mask) != mask_val) {
|
||||
|
@ -756,9 +756,9 @@ static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
|
||||
if (sta->deflink.vht_cap.vht_supported) {
|
||||
sta_priv->supported_rates.op_rate_mode = STA_11ac;
|
||||
sta_priv->supported_rates.vht_rx_mcs_map =
|
||||
sta->deflink.vht_cap.vht_mcs.rx_mcs_map;
|
||||
le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map);
|
||||
sta_priv->supported_rates.vht_tx_mcs_map =
|
||||
sta->deflink.vht_cap.vht_mcs.tx_mcs_map;
|
||||
le16_to_cpu(sta->deflink.vht_cap.vht_mcs.tx_mcs_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,7 +318,7 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
|
||||
memset(&status, 0, sizeof(status));
|
||||
|
||||
bd = (struct wcn36xx_rx_bd *)skb->data;
|
||||
buff_to_be((u32 *)bd, sizeof(*bd)/sizeof(u32));
|
||||
buff_to_be(bd, sizeof(*bd)/sizeof(u32));
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_RX_DUMP,
|
||||
"BD <<< ", (char *)bd,
|
||||
sizeof(struct wcn36xx_rx_bd));
|
||||
@ -692,7 +692,7 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
|
||||
/* MGMT and CTRL frames are handeld here*/
|
||||
wcn36xx_set_tx_mgmt(&bd, wcn, &vif_priv, skb, bcast);
|
||||
|
||||
buff_to_be((u32 *)&bd, sizeof(bd)/sizeof(u32));
|
||||
buff_to_be(&bd, sizeof(bd)/sizeof(u32));
|
||||
bd.tx_bd_sign = 0xbdbdbdbd;
|
||||
|
||||
ret = wcn36xx_dxe_tx_frame(wcn, vif_priv, &bd, skb, is_low);
|
||||
|
@ -100,11 +100,14 @@ enum wcn36xx_ampdu_state {
|
||||
#define RF_IRIS_WCN3660 0x3660
|
||||
#define RF_IRIS_WCN3680 0x3680
|
||||
|
||||
static inline void buff_to_be(u32 *buf, size_t len)
|
||||
static inline void buff_to_be(void *buf, size_t len)
|
||||
{
|
||||
__be32 *to = buf;
|
||||
u32 *from = buf;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
buf[i] = cpu_to_be32(buf[i]);
|
||||
to[i] = cpu_to_be32(from[i]);
|
||||
}
|
||||
|
||||
struct nv_data {
|
||||
|
@ -2735,7 +2735,7 @@ int wil_cfg80211_iface_combinations_from_fw(
|
||||
return 0;
|
||||
}
|
||||
|
||||
combo = conc->combos;
|
||||
combo = (const struct wil_fw_concurrency_combo *)(conc + 1);
|
||||
n_combos = le16_to_cpu(conc->n_combos);
|
||||
for (i = 0; i < n_combos; i++) {
|
||||
total_limits += combo->n_limits;
|
||||
@ -2751,7 +2751,7 @@ int wil_cfg80211_iface_combinations_from_fw(
|
||||
return -ENOMEM;
|
||||
iface_limit = (struct ieee80211_iface_limit *)(iface_combinations +
|
||||
n_combos);
|
||||
combo = conc->combos;
|
||||
combo = (const struct wil_fw_concurrency_combo *)(conc + 1);
|
||||
for (i = 0; i < n_combos; i++) {
|
||||
iface_combinations[i].max_interfaces = combo->max_interfaces;
|
||||
iface_combinations[i].num_different_channels =
|
||||
|
@ -93,7 +93,6 @@ struct wil_fw_record_concurrency { /* type == wil_fw_type_comment */
|
||||
/* number of concurrency combinations that follow */
|
||||
__le16 n_combos;
|
||||
/* keep last - combinations, variable size by n_combos */
|
||||
struct wil_fw_concurrency_combo combos[];
|
||||
} __packed;
|
||||
|
||||
/* brd file info encoded inside a comment record */
|
||||
|
@ -212,8 +212,8 @@ fw_handle_concurrency(struct wil6210_priv *wil, const void *data,
|
||||
}
|
||||
|
||||
n_combos = le16_to_cpu(rec->n_combos);
|
||||
remain = size - offsetof(struct wil_fw_record_concurrency, combos);
|
||||
combo = rec->combos;
|
||||
remain = size - sizeof(struct wil_fw_record_concurrency);
|
||||
combo = (const struct wil_fw_concurrency_combo *)(rec + 1);
|
||||
for (i = 0; i < n_combos; i++) {
|
||||
if (remain < sizeof(*combo))
|
||||
goto out_short;
|
||||
|
Loading…
Reference in New Issue
Block a user