Merge tag 'wireless-next-2024-09-04' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next
Kalle Valo says: ==================== pull-request: wireless-next-2024-09-04 here's a pull request to net-next tree, more info below. Please let me know if there are any problems. ==================== Conflicts: drivers/net/wireless/ath/ath12k/hw.c38055789d1("wifi: ath12k: use 128 bytes aligned iova in transmit path for WCN7850")8be12629b4("wifi: ath12k: restore ASPM for supported hardwares only") https://lore.kernel.org/87msldyj97.fsf@kernel.org Link: https://patch.msgid.link/20240904153205.64C11C4CEC2@smtp.kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/wireless/marvell,sd8787.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Marvell 8787/8897/8978/8997 (sd8787/sd8897/sd8978/sd8997/pcie8997) SDIO/PCIE devices
|
||||
|
||||
maintainers:
|
||||
- Brian Norris <briannorris@chromium.org>
|
||||
- Frank Li <Frank.Li@nxp.com>
|
||||
|
||||
description:
|
||||
This node provides properties for describing the Marvell SDIO/PCIE wireless device.
|
||||
The node is expected to be specified as a child node to the SDIO/PCIE controller that
|
||||
connects the device to the system.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- marvell,sd8787
|
||||
- marvell,sd8897
|
||||
- marvell,sd8978
|
||||
- marvell,sd8997
|
||||
- nxp,iw416
|
||||
- pci11ab,2b42
|
||||
- pci1b4b,2b42
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
wakeup-source: true
|
||||
|
||||
marvell,caldata-txpwrlimit-2g:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: Calibration data for the 2GHz band.
|
||||
maxItems: 566
|
||||
|
||||
marvell,caldata-txpwrlimit-5g-sub0:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: Calibration data for sub-band 0 in the 5GHz band.
|
||||
maxItems: 502
|
||||
|
||||
marvell,caldata-txpwrlimit-5g-sub1:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: Calibration data for sub-band 1 in the 5GHz band.
|
||||
maxItems: 688
|
||||
|
||||
marvell,caldata-txpwrlimit-5g-sub2:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: Calibration data for sub-band 2 in the 5GHz band.
|
||||
maxItems: 750
|
||||
|
||||
marvell,caldata-txpwrlimit-5g-sub3:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: Calibration data for sub-band 3 in the 5GHz band.
|
||||
maxItems: 502
|
||||
|
||||
marvell,wakeup-pin:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Provides the pin number for the wakeup pin from the device's point of
|
||||
view. The wakeup pin is used for the device to wake the host system
|
||||
from sleep. This property is only necessary if the wakeup pin is
|
||||
wired in a non-standard way, such that the default pin assignments
|
||||
are invalid.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
mmc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
wifi@1 {
|
||||
compatible = "marvell,sd8897";
|
||||
reg = <1>;
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
|
||||
marvell,wakeup-pin = <3>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
Marvell 8787/8897/8978/8997 (sd8787/sd8897/sd8978/sd8997/pcie8997) SDIO/PCIE devices
|
||||
------
|
||||
|
||||
This node provides properties for controlling the Marvell SDIO/PCIE wireless device.
|
||||
The node is expected to be specified as a child node to the SDIO/PCIE controller that
|
||||
connects the device to the system.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be one of the following:
|
||||
* "marvell,sd8787"
|
||||
* "marvell,sd8897"
|
||||
* "marvell,sd8978"
|
||||
* "marvell,sd8997"
|
||||
* "nxp,iw416"
|
||||
* "pci11ab,2b42"
|
||||
* "pci1b4b,2b42"
|
||||
|
||||
Optional properties:
|
||||
|
||||
- marvell,caldata* : A series of properties with marvell,caldata prefix,
|
||||
represent calibration data downloaded to the device during
|
||||
initialization. This is an array of unsigned 8-bit values.
|
||||
the properties should follow below property name and
|
||||
corresponding array length:
|
||||
"marvell,caldata-txpwrlimit-2g" (length = 566).
|
||||
"marvell,caldata-txpwrlimit-5g-sub0" (length = 502).
|
||||
"marvell,caldata-txpwrlimit-5g-sub1" (length = 688).
|
||||
"marvell,caldata-txpwrlimit-5g-sub2" (length = 750).
|
||||
"marvell,caldata-txpwrlimit-5g-sub3" (length = 502).
|
||||
- marvell,wakeup-pin : a wakeup pin number of wifi chip which will be configured
|
||||
to firmware. Firmware will wakeup the host using this pin
|
||||
during suspend/resume.
|
||||
- interrupts : interrupt pin number to the cpu. driver will request an irq based on
|
||||
this interrupt number. during system suspend, the irq will be enabled
|
||||
so that the wifi chip can wakeup host platform under certain condition.
|
||||
during system resume, the irq will be disabled to make sure
|
||||
unnecessary interrupt is not received.
|
||||
- vmmc-supply: a phandle of a regulator, supplying VCC to the card
|
||||
- mmc-pwrseq: phandle to the MMC power sequence node. See "mmc-pwrseq-*"
|
||||
for documentation of MMC power sequence bindings.
|
||||
|
||||
Example:
|
||||
|
||||
Tx power limit calibration data is configured in below example.
|
||||
The calibration data is an array of unsigned values, the length
|
||||
can vary between hw versions.
|
||||
IRQ pin 38 is used as system wakeup source interrupt. wakeup pin 3 is configured
|
||||
so that firmware can wakeup host using this device side pin.
|
||||
|
||||
&mmc3 {
|
||||
vmmc-supply = <&wlan_en_reg>;
|
||||
mmc-pwrseq = <&wifi_pwrseq>;
|
||||
bus-width = <4>;
|
||||
cap-power-off-card;
|
||||
keep-power-in-suspend;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
mwifiex: wifi@1 {
|
||||
compatible = "marvell,sd8897";
|
||||
reg = <1>;
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
marvell,caldata_00_txpwrlimit_2g_cfg_set = /bits/ 8 <
|
||||
0x01 0x00 0x06 0x00 0x08 0x02 0x89 0x01>;
|
||||
marvell,wakeup-pin = <3>;
|
||||
};
|
||||
};
|
||||
@@ -399,6 +399,7 @@ struct ath11k_vif {
|
||||
u8 bssid[ETH_ALEN];
|
||||
struct cfg80211_bitrate_mask bitrate_mask;
|
||||
struct delayed_work connection_loss_work;
|
||||
struct work_struct bcn_tx_work;
|
||||
int num_legacy_stations;
|
||||
int rtscts_prot_mode;
|
||||
int txpower;
|
||||
|
||||
@@ -2697,7 +2697,7 @@ try_again:
|
||||
if (unlikely(push_reason !=
|
||||
HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++;
|
||||
ab->soc_stats.hal_reo_error[ring_id]++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -6599,6 +6599,16 @@ static int ath11k_mac_vdev_delete(struct ath11k *ar, struct ath11k_vif *arvif)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath11k_mac_bcn_tx_work(struct work_struct *work)
|
||||
{
|
||||
struct ath11k_vif *arvif = container_of(work, struct ath11k_vif,
|
||||
bcn_tx_work);
|
||||
|
||||
mutex_lock(&arvif->ar->conf_mutex);
|
||||
ath11k_mac_bcn_tx_event(arvif);
|
||||
mutex_unlock(&arvif->ar->conf_mutex);
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
@@ -6637,6 +6647,7 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
|
||||
arvif->vif = vif;
|
||||
|
||||
INIT_LIST_HEAD(&arvif->list);
|
||||
INIT_WORK(&arvif->bcn_tx_work, ath11k_mac_bcn_tx_work);
|
||||
INIT_DELAYED_WORK(&arvif->connection_loss_work,
|
||||
ath11k_mac_vif_sta_connection_loss_work);
|
||||
|
||||
@@ -6879,6 +6890,7 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw,
|
||||
int i;
|
||||
|
||||
cancel_delayed_work_sync(&arvif->connection_loss_work);
|
||||
cancel_work_sync(&arvif->bcn_tx_work);
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
|
||||
@@ -7404,7 +7404,9 @@ static void ath11k_bcn_tx_status_event(struct ath11k_base *ab, struct sk_buff *s
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
ath11k_mac_bcn_tx_event(arvif);
|
||||
|
||||
queue_work(ab->workqueue, &arvif->bcn_tx_work);
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -1117,6 +1117,336 @@ ath12k_htt_print_tx_tqm_pdev_stats_tlv(const void *tag_buf, u16 tag_len,
|
||||
stats_req->buf_len = len;
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_htt_print_tx_de_cmn_stats_tlv(const void *tag_buf, u16 tag_len,
|
||||
struct debug_htt_stats_req *stats_req)
|
||||
{
|
||||
const struct ath12k_htt_tx_de_cmn_stats_tlv *htt_stats_buf = tag_buf;
|
||||
u8 *buf = stats_req->buf;
|
||||
u32 len = stats_req->buf_len;
|
||||
u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
|
||||
u32 mac_id_word;
|
||||
|
||||
if (tag_len < sizeof(*htt_stats_buf))
|
||||
return;
|
||||
|
||||
mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CMN_STATS_TLV:\n");
|
||||
len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
|
||||
len += scnprintf(buf + len, buf_len - len, "tcl2fw_entry_count = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->tcl2fw_entry_count));
|
||||
len += scnprintf(buf + len, buf_len - len, "not_to_fw = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->not_to_fw));
|
||||
len += scnprintf(buf + len, buf_len - len, "invalid_pdev_vdev_peer = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->invalid_pdev_vdev_peer));
|
||||
len += scnprintf(buf + len, buf_len - len, "tcl_res_invalid_addrx = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->tcl_res_invalid_addrx));
|
||||
len += scnprintf(buf + len, buf_len - len, "wbm2fw_entry_count = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->wbm2fw_entry_count));
|
||||
len += scnprintf(buf + len, buf_len - len, "invalid_pdev = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->invalid_pdev));
|
||||
len += scnprintf(buf + len, buf_len - len, "tcl_res_addrx_timeout = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->tcl_res_addrx_timeout));
|
||||
len += scnprintf(buf + len, buf_len - len, "invalid_vdev = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->invalid_vdev));
|
||||
len += scnprintf(buf + len, buf_len - len, "invalid_tcl_exp_frame_desc = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->invalid_tcl_exp_frame_desc));
|
||||
len += scnprintf(buf + len, buf_len - len, "vdev_id_mismatch_count = %u\n\n",
|
||||
le32_to_cpu(htt_stats_buf->vdev_id_mismatch_cnt));
|
||||
|
||||
stats_req->buf_len = len;
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_htt_print_tx_de_eapol_packets_stats_tlv(const void *tag_buf, u16 tag_len,
|
||||
struct debug_htt_stats_req *stats_req)
|
||||
{
|
||||
const struct ath12k_htt_tx_de_eapol_packets_stats_tlv *htt_stats_buf = tag_buf;
|
||||
u8 *buf = stats_req->buf;
|
||||
u32 len = stats_req->buf_len;
|
||||
u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
if (tag_len < sizeof(*htt_stats_buf))
|
||||
return;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"HTT_TX_DE_EAPOL_PACKETS_STATS_TLV:\n");
|
||||
len += scnprintf(buf + len, buf_len - len, "m1_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->m1_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "m2_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->m2_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "m3_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->m3_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "m4_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->m4_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "g1_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->g1_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "g2_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->g2_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "rc4_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->rc4_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "eap_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->eap_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "eapol_start_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->eapol_start_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "eapol_logoff_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->eapol_logoff_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "eapol_encap_asf_packets = %u\n\n",
|
||||
le32_to_cpu(htt_stats_buf->eapol_encap_asf_packets));
|
||||
|
||||
stats_req->buf_len = len;
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_htt_print_tx_de_classify_stats_tlv(const void *tag_buf, u16 tag_len,
|
||||
struct debug_htt_stats_req *stats_req)
|
||||
{
|
||||
const struct ath12k_htt_tx_de_classify_stats_tlv *htt_stats_buf = tag_buf;
|
||||
u8 *buf = stats_req->buf;
|
||||
u32 len = stats_req->buf_len;
|
||||
u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
if (tag_len < sizeof(*htt_stats_buf))
|
||||
return;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CLASSIFY_STATS_TLV:\n");
|
||||
len += scnprintf(buf + len, buf_len - len, "arp_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->arp_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "igmp_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->igmp_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "dhcp_packets = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->dhcp_packets));
|
||||
len += scnprintf(buf + len, buf_len - len, "host_inspected = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->host_inspected));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_included = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_included));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_valid_mcs = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_valid_mcs));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_valid_nss = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_valid_nss));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_valid_preamble_type = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_valid_preamble_type));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_valid_chainmask = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_valid_chainmask));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_valid_guard_interval = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_valid_guard_interval));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_valid_retries = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_valid_retries));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_valid_bw_info = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_valid_bw_info));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_valid_power = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_valid_power));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_valid_key_flags = 0x%x\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_valid_key_flags));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_valid_no_encryption = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_valid_no_encryption));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_entry_count = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_entry_count));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_priority_be = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_priority_be));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_priority_high = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_priority_high));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_priority_low = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_priority_low));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_be = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_be));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_over_sub = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_over_sub));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_bursty = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_bursty));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_interactive = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_interactive));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_periodic = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_periodic));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_alloc = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_hwqueue_alloc));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_created = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_hwqueue_created));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_send_to_host = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_hwqueue_send_to_host));
|
||||
len += scnprintf(buf + len, buf_len - len, "mcast_entry = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->mcast_entry));
|
||||
len += scnprintf(buf + len, buf_len - len, "bcast_entry = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->bcast_entry));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_update_peer_cache = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_update_peer_cache));
|
||||
len += scnprintf(buf + len, buf_len - len, "htt_learning_frame = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->htt_learning_frame));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_invalid_peer = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_invalid_peer));
|
||||
len += scnprintf(buf + len, buf_len - len, "mec_notify = %u\n\n",
|
||||
le32_to_cpu(htt_stats_buf->mec_notify));
|
||||
|
||||
stats_req->buf_len = len;
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_htt_print_tx_de_classify_failed_stats_tlv(const void *tag_buf, u16 tag_len,
|
||||
struct debug_htt_stats_req *stats_req)
|
||||
{
|
||||
const struct ath12k_htt_tx_de_classify_failed_stats_tlv *htt_stats_buf = tag_buf;
|
||||
u8 *buf = stats_req->buf;
|
||||
u32 len = stats_req->buf_len;
|
||||
u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
if (tag_len < sizeof(*htt_stats_buf))
|
||||
return;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"HTT_TX_DE_CLASSIFY_FAILED_STATS_TLV:\n");
|
||||
len += scnprintf(buf + len, buf_len - len, "ap_bss_peer_not_found = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->ap_bss_peer_not_found));
|
||||
len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_no_peer = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->ap_bcast_mcast_no_peer));
|
||||
len += scnprintf(buf + len, buf_len - len, "sta_delete_in_progress = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->sta_delete_in_progress));
|
||||
len += scnprintf(buf + len, buf_len - len, "ibss_no_bss_peer = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->ibss_no_bss_peer));
|
||||
len += scnprintf(buf + len, buf_len - len, "invalid_vdev_type = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->invalid_vdev_type));
|
||||
len += scnprintf(buf + len, buf_len - len, "invalid_ast_peer_entry = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->invalid_ast_peer_entry));
|
||||
len += scnprintf(buf + len, buf_len - len, "peer_entry_invalid = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->peer_entry_invalid));
|
||||
len += scnprintf(buf + len, buf_len - len, "ethertype_not_ip = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->ethertype_not_ip));
|
||||
len += scnprintf(buf + len, buf_len - len, "eapol_lookup_failed = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->eapol_lookup_failed));
|
||||
len += scnprintf(buf + len, buf_len - len, "qpeer_not_allow_data = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->qpeer_not_allow_data));
|
||||
len += scnprintf(buf + len, buf_len - len, "fse_tid_override = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fse_tid_override));
|
||||
len += scnprintf(buf + len, buf_len - len, "ipv6_jumbogram_zero_length = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->ipv6_jumbogram_zero_length));
|
||||
len += scnprintf(buf + len, buf_len - len, "qos_to_non_qos_in_prog = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->qos_to_non_qos_in_prog));
|
||||
len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_eapol = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->ap_bcast_mcast_eapol));
|
||||
len += scnprintf(buf + len, buf_len - len, "unicast_on_ap_bss_peer = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->unicast_on_ap_bss_peer));
|
||||
len += scnprintf(buf + len, buf_len - len, "ap_vdev_invalid = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->ap_vdev_invalid));
|
||||
len += scnprintf(buf + len, buf_len - len, "incomplete_llc = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->incomplete_llc));
|
||||
len += scnprintf(buf + len, buf_len - len, "eapol_duplicate_m3 = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->eapol_duplicate_m3));
|
||||
len += scnprintf(buf + len, buf_len - len, "eapol_duplicate_m4 = %u\n\n",
|
||||
le32_to_cpu(htt_stats_buf->eapol_duplicate_m4));
|
||||
|
||||
stats_req->buf_len = len;
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_htt_print_tx_de_classify_status_stats_tlv(const void *tag_buf, u16 tag_len,
|
||||
struct debug_htt_stats_req *stats_req)
|
||||
{
|
||||
const struct ath12k_htt_tx_de_classify_status_stats_tlv *htt_stats_buf = tag_buf;
|
||||
u8 *buf = stats_req->buf;
|
||||
u32 len = stats_req->buf_len;
|
||||
u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
if (tag_len < sizeof(*htt_stats_buf))
|
||||
return;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"HTT_TX_DE_CLASSIFY_STATUS_STATS_TLV:\n");
|
||||
len += scnprintf(buf + len, buf_len - len, "eok = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->eok));
|
||||
len += scnprintf(buf + len, buf_len - len, "classify_done = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->classify_done));
|
||||
len += scnprintf(buf + len, buf_len - len, "lookup_failed = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->lookup_failed));
|
||||
len += scnprintf(buf + len, buf_len - len, "send_host_dhcp = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->send_host_dhcp));
|
||||
len += scnprintf(buf + len, buf_len - len, "send_host_mcast = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->send_host_mcast));
|
||||
len += scnprintf(buf + len, buf_len - len, "send_host_unknown_dest = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->send_host_unknown_dest));
|
||||
len += scnprintf(buf + len, buf_len - len, "send_host = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->send_host));
|
||||
len += scnprintf(buf + len, buf_len - len, "status_invalid = %u\n\n",
|
||||
le32_to_cpu(htt_stats_buf->status_invalid));
|
||||
|
||||
stats_req->buf_len = len;
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(const void *tag_buf, u16 tag_len,
|
||||
struct debug_htt_stats_req *stats_req)
|
||||
{
|
||||
const struct ath12k_htt_tx_de_enqueue_packets_stats_tlv *htt_stats_buf = tag_buf;
|
||||
u8 *buf = stats_req->buf;
|
||||
u32 len = stats_req->buf_len;
|
||||
u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
if (tag_len < sizeof(*htt_stats_buf))
|
||||
return;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"HTT_TX_DE_ENQUEUE_PACKETS_STATS_TLV:\n");
|
||||
len += scnprintf(buf + len, buf_len - len, "enqueued_pkts = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->enqueued_pkts));
|
||||
len += scnprintf(buf + len, buf_len - len, "to_tqm = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->to_tqm));
|
||||
len += scnprintf(buf + len, buf_len - len, "to_tqm_bypass = %u\n\n",
|
||||
le32_to_cpu(htt_stats_buf->to_tqm_bypass));
|
||||
|
||||
stats_req->buf_len = len;
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(const void *tag_buf, u16 tag_len,
|
||||
struct debug_htt_stats_req *stats_req)
|
||||
{
|
||||
const struct ath12k_htt_tx_de_enqueue_discard_stats_tlv *htt_stats_buf = tag_buf;
|
||||
u8 *buf = stats_req->buf;
|
||||
u32 len = stats_req->buf_len;
|
||||
u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
if (tag_len < sizeof(*htt_stats_buf))
|
||||
return;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"HTT_TX_DE_ENQUEUE_DISCARD_STATS_TLV:\n");
|
||||
len += scnprintf(buf + len, buf_len - len, "discarded_pkts = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->discarded_pkts));
|
||||
len += scnprintf(buf + len, buf_len - len, "local_frames = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->local_frames));
|
||||
len += scnprintf(buf + len, buf_len - len, "is_ext_msdu = %u\n\n",
|
||||
le32_to_cpu(htt_stats_buf->is_ext_msdu));
|
||||
|
||||
stats_req->buf_len = len;
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_htt_print_tx_de_compl_stats_tlv(const void *tag_buf, u16 tag_len,
|
||||
struct debug_htt_stats_req *stats_req)
|
||||
{
|
||||
const struct ath12k_htt_tx_de_compl_stats_tlv *htt_stats_buf = tag_buf;
|
||||
u8 *buf = stats_req->buf;
|
||||
u32 len = stats_req->buf_len;
|
||||
u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
if (tag_len < sizeof(*htt_stats_buf))
|
||||
return;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_COMPL_STATS_TLV:\n");
|
||||
len += scnprintf(buf + len, buf_len - len, "tcl_dummy_frame = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->tcl_dummy_frame));
|
||||
len += scnprintf(buf + len, buf_len - len, "tqm_dummy_frame = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->tqm_dummy_frame));
|
||||
len += scnprintf(buf + len, buf_len - len, "tqm_notify_frame = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->tqm_notify_frame));
|
||||
len += scnprintf(buf + len, buf_len - len, "fw2wbm_enq = %u\n",
|
||||
le32_to_cpu(htt_stats_buf->fw2wbm_enq));
|
||||
len += scnprintf(buf + len, buf_len - len, "tqm_bypass_frame = %u\n\n",
|
||||
le32_to_cpu(htt_stats_buf->tqm_bypass_frame));
|
||||
|
||||
stats_req->buf_len = len;
|
||||
}
|
||||
|
||||
static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
|
||||
u16 tag, u16 len, const void *tag_buf,
|
||||
void *user_data)
|
||||
@@ -1198,6 +1528,30 @@ static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
|
||||
case HTT_STATS_TX_TQM_PDEV_TAG:
|
||||
ath12k_htt_print_tx_tqm_pdev_stats_tlv(tag_buf, len, stats_req);
|
||||
break;
|
||||
case HTT_STATS_TX_DE_CMN_TAG:
|
||||
ath12k_htt_print_tx_de_cmn_stats_tlv(tag_buf, len, stats_req);
|
||||
break;
|
||||
case HTT_STATS_TX_DE_EAPOL_PACKETS_TAG:
|
||||
ath12k_htt_print_tx_de_eapol_packets_stats_tlv(tag_buf, len, stats_req);
|
||||
break;
|
||||
case HTT_STATS_TX_DE_CLASSIFY_STATS_TAG:
|
||||
ath12k_htt_print_tx_de_classify_stats_tlv(tag_buf, len, stats_req);
|
||||
break;
|
||||
case HTT_STATS_TX_DE_CLASSIFY_FAILED_TAG:
|
||||
ath12k_htt_print_tx_de_classify_failed_stats_tlv(tag_buf, len, stats_req);
|
||||
break;
|
||||
case HTT_STATS_TX_DE_CLASSIFY_STATUS_TAG:
|
||||
ath12k_htt_print_tx_de_classify_status_stats_tlv(tag_buf, len, stats_req);
|
||||
break;
|
||||
case HTT_STATS_TX_DE_ENQUEUE_PACKETS_TAG:
|
||||
ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(tag_buf, len, stats_req);
|
||||
break;
|
||||
case HTT_STATS_TX_DE_ENQUEUE_DISCARD_TAG:
|
||||
ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(tag_buf, len, stats_req);
|
||||
break;
|
||||
case HTT_STATS_TX_DE_COMPL_STATS_TAG:
|
||||
ath12k_htt_print_tx_de_compl_stats_tlv(tag_buf, len, stats_req);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ enum ath12k_dbg_htt_ext_stats_type {
|
||||
ATH12K_DBG_HTT_EXT_STATS_PDEV_TX_SCHED = 4,
|
||||
ATH12K_DBG_HTT_EXT_STATS_PDEV_ERROR = 5,
|
||||
ATH12K_DBG_HTT_EXT_STATS_PDEV_TQM = 6,
|
||||
ATH12K_DBG_HTT_EXT_STATS_TX_DE_INFO = 8,
|
||||
|
||||
/* keep this last */
|
||||
ATH12K_DBG_HTT_NUM_EXT_STATS,
|
||||
@@ -143,6 +144,13 @@ enum ath12k_dbg_htt_tlv_tag {
|
||||
HTT_STATS_TX_TQM_LIST_MPDU_CNT_TAG = 13,
|
||||
HTT_STATS_TX_TQM_CMN_TAG = 14,
|
||||
HTT_STATS_TX_TQM_PDEV_TAG = 15,
|
||||
HTT_STATS_TX_DE_EAPOL_PACKETS_TAG = 17,
|
||||
HTT_STATS_TX_DE_CLASSIFY_FAILED_TAG = 18,
|
||||
HTT_STATS_TX_DE_CLASSIFY_STATS_TAG = 19,
|
||||
HTT_STATS_TX_DE_CLASSIFY_STATUS_TAG = 20,
|
||||
HTT_STATS_TX_DE_ENQUEUE_PACKETS_TAG = 21,
|
||||
HTT_STATS_TX_DE_ENQUEUE_DISCARD_TAG = 22,
|
||||
HTT_STATS_TX_DE_CMN_TAG = 23,
|
||||
HTT_STATS_TX_PDEV_SCHEDULER_TXQ_STATS_TAG = 36,
|
||||
HTT_STATS_TX_SCHED_CMN_TAG = 37,
|
||||
HTT_STATS_SCHED_TXQ_CMD_POSTED_TAG = 39,
|
||||
@@ -150,6 +158,7 @@ enum ath12k_dbg_htt_tlv_tag {
|
||||
HTT_STATS_SCHED_TXQ_CMD_REAPED_TAG = 44,
|
||||
HTT_STATS_HW_INTR_MISC_TAG = 54,
|
||||
HTT_STATS_HW_PDEV_ERRS_TAG = 56,
|
||||
HTT_STATS_TX_DE_COMPL_STATS_TAG = 65,
|
||||
HTT_STATS_WHAL_TX_TAG = 66,
|
||||
HTT_STATS_TX_PDEV_SIFS_HIST_TAG = 67,
|
||||
HTT_STATS_SCHED_TXQ_SCHED_ORDER_SU_TAG = 86,
|
||||
@@ -564,4 +573,121 @@ struct ath12k_htt_tx_tqm_pdev_stats_tlv {
|
||||
__le32 sched_nonudp_notify2;
|
||||
} __packed;
|
||||
|
||||
struct ath12k_htt_tx_de_cmn_stats_tlv {
|
||||
__le32 mac_id__word;
|
||||
__le32 tcl2fw_entry_count;
|
||||
__le32 not_to_fw;
|
||||
__le32 invalid_pdev_vdev_peer;
|
||||
__le32 tcl_res_invalid_addrx;
|
||||
__le32 wbm2fw_entry_count;
|
||||
__le32 invalid_pdev;
|
||||
__le32 tcl_res_addrx_timeout;
|
||||
__le32 invalid_vdev;
|
||||
__le32 invalid_tcl_exp_frame_desc;
|
||||
__le32 vdev_id_mismatch_cnt;
|
||||
} __packed;
|
||||
|
||||
struct ath12k_htt_tx_de_eapol_packets_stats_tlv {
|
||||
__le32 m1_packets;
|
||||
__le32 m2_packets;
|
||||
__le32 m3_packets;
|
||||
__le32 m4_packets;
|
||||
__le32 g1_packets;
|
||||
__le32 g2_packets;
|
||||
__le32 rc4_packets;
|
||||
__le32 eap_packets;
|
||||
__le32 eapol_start_packets;
|
||||
__le32 eapol_logoff_packets;
|
||||
__le32 eapol_encap_asf_packets;
|
||||
} __packed;
|
||||
|
||||
struct ath12k_htt_tx_de_classify_stats_tlv {
|
||||
__le32 arp_packets;
|
||||
__le32 igmp_packets;
|
||||
__le32 dhcp_packets;
|
||||
__le32 host_inspected;
|
||||
__le32 htt_included;
|
||||
__le32 htt_valid_mcs;
|
||||
__le32 htt_valid_nss;
|
||||
__le32 htt_valid_preamble_type;
|
||||
__le32 htt_valid_chainmask;
|
||||
__le32 htt_valid_guard_interval;
|
||||
__le32 htt_valid_retries;
|
||||
__le32 htt_valid_bw_info;
|
||||
__le32 htt_valid_power;
|
||||
__le32 htt_valid_key_flags;
|
||||
__le32 htt_valid_no_encryption;
|
||||
__le32 fse_entry_count;
|
||||
__le32 fse_priority_be;
|
||||
__le32 fse_priority_high;
|
||||
__le32 fse_priority_low;
|
||||
__le32 fse_traffic_ptrn_be;
|
||||
__le32 fse_traffic_ptrn_over_sub;
|
||||
__le32 fse_traffic_ptrn_bursty;
|
||||
__le32 fse_traffic_ptrn_interactive;
|
||||
__le32 fse_traffic_ptrn_periodic;
|
||||
__le32 fse_hwqueue_alloc;
|
||||
__le32 fse_hwqueue_created;
|
||||
__le32 fse_hwqueue_send_to_host;
|
||||
__le32 mcast_entry;
|
||||
__le32 bcast_entry;
|
||||
__le32 htt_update_peer_cache;
|
||||
__le32 htt_learning_frame;
|
||||
__le32 fse_invalid_peer;
|
||||
__le32 mec_notify;
|
||||
} __packed;
|
||||
|
||||
struct ath12k_htt_tx_de_classify_failed_stats_tlv {
|
||||
__le32 ap_bss_peer_not_found;
|
||||
__le32 ap_bcast_mcast_no_peer;
|
||||
__le32 sta_delete_in_progress;
|
||||
__le32 ibss_no_bss_peer;
|
||||
__le32 invalid_vdev_type;
|
||||
__le32 invalid_ast_peer_entry;
|
||||
__le32 peer_entry_invalid;
|
||||
__le32 ethertype_not_ip;
|
||||
__le32 eapol_lookup_failed;
|
||||
__le32 qpeer_not_allow_data;
|
||||
__le32 fse_tid_override;
|
||||
__le32 ipv6_jumbogram_zero_length;
|
||||
__le32 qos_to_non_qos_in_prog;
|
||||
__le32 ap_bcast_mcast_eapol;
|
||||
__le32 unicast_on_ap_bss_peer;
|
||||
__le32 ap_vdev_invalid;
|
||||
__le32 incomplete_llc;
|
||||
__le32 eapol_duplicate_m3;
|
||||
__le32 eapol_duplicate_m4;
|
||||
} __packed;
|
||||
|
||||
struct ath12k_htt_tx_de_classify_status_stats_tlv {
|
||||
__le32 eok;
|
||||
__le32 classify_done;
|
||||
__le32 lookup_failed;
|
||||
__le32 send_host_dhcp;
|
||||
__le32 send_host_mcast;
|
||||
__le32 send_host_unknown_dest;
|
||||
__le32 send_host;
|
||||
__le32 status_invalid;
|
||||
} __packed;
|
||||
|
||||
struct ath12k_htt_tx_de_enqueue_packets_stats_tlv {
|
||||
__le32 enqueued_pkts;
|
||||
__le32 to_tqm;
|
||||
__le32 to_tqm_bypass;
|
||||
} __packed;
|
||||
|
||||
struct ath12k_htt_tx_de_enqueue_discard_stats_tlv {
|
||||
__le32 discarded_pkts;
|
||||
__le32 local_frames;
|
||||
__le32 is_ext_msdu;
|
||||
} __packed;
|
||||
|
||||
struct ath12k_htt_tx_de_compl_stats_tlv {
|
||||
__le32 tcl_dummy_frame;
|
||||
__le32 tqm_dummy_frame;
|
||||
__le32 tqm_notify_frame;
|
||||
__le32 fw2wbm_enq;
|
||||
__le32 tqm_bypass_frame;
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2681,7 +2681,7 @@ try_again:
|
||||
if (push_reason !=
|
||||
HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++;
|
||||
ab->soc_stats.hal_reo_error[ring_id]++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -926,6 +926,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
|
||||
.iova_mask = 0,
|
||||
|
||||
.supports_aspm = false,
|
||||
},
|
||||
{
|
||||
.name = "wcn7850 hw2.0",
|
||||
@@ -1004,6 +1006,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
|
||||
.iova_mask = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1,
|
||||
|
||||
.supports_aspm = true,
|
||||
},
|
||||
{
|
||||
.name = "qcn9274 hw2.0",
|
||||
@@ -1078,6 +1082,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
|
||||
.iova_mask = 0,
|
||||
|
||||
.supports_aspm = false,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -189,6 +189,7 @@ struct ath12k_hw_params {
|
||||
bool tcl_ring_retry:1;
|
||||
bool reoq_lut_support:1;
|
||||
bool supports_shadow_regs:1;
|
||||
bool supports_aspm:1;
|
||||
|
||||
u32 num_tcl_banks;
|
||||
u32 max_tx_ring;
|
||||
|
||||
@@ -2196,9 +2196,8 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar,
|
||||
* request, then use MAX_AMPDU_LEN_FACTOR as 16 to calculate max_ampdu
|
||||
* length.
|
||||
*/
|
||||
ampdu_factor = (he_cap->he_cap_elem.mac_cap_info[3] &
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) >>
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK;
|
||||
ampdu_factor = u8_get_bits(he_cap->he_cap_elem.mac_cap_info[3],
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK);
|
||||
|
||||
if (ampdu_factor) {
|
||||
if (sta->deflink.vht_cap.vht_supported)
|
||||
|
||||
@@ -954,7 +954,8 @@ static void ath12k_pci_update_qrtr_node_id(struct ath12k_base *ab)
|
||||
|
||||
static void ath12k_pci_aspm_restore(struct ath12k_pci *ab_pci)
|
||||
{
|
||||
if (test_and_clear_bit(ATH12K_PCI_ASPM_RESTORE, &ab_pci->flags))
|
||||
if (ab_pci->ab->hw_params->supports_aspm &&
|
||||
test_and_clear_bit(ATH12K_PCI_ASPM_RESTORE, &ab_pci->flags))
|
||||
pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL,
|
||||
PCI_EXP_LNKCTL_ASPMC,
|
||||
ab_pci->link_ctl &
|
||||
|
||||
@@ -1538,6 +1538,7 @@ int ath12k_wmi_pdev_bss_chan_info_request(struct ath12k *ar,
|
||||
cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_PDEV_BSS_CHAN_INFO_REQUEST,
|
||||
sizeof(*cmd));
|
||||
cmd->req_type = cpu_to_le32(type);
|
||||
cmd->pdev_id = cpu_to_le32(ar->pdev->pdev_id);
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
|
||||
"WMI bss chan info req type %d\n", type);
|
||||
|
||||
@@ -3121,6 +3121,7 @@ struct wmi_pdev_bss_chan_info_req_cmd {
|
||||
__le32 tlv_header;
|
||||
/* ref wmi_bss_chan_info_req_type */
|
||||
__le32 req_type;
|
||||
__le32 pdev_id;
|
||||
} __packed;
|
||||
|
||||
struct wmi_ap_ps_peer_cmd {
|
||||
@@ -4085,7 +4086,6 @@ struct wmi_vdev_stopped_event {
|
||||
} __packed;
|
||||
|
||||
struct wmi_pdev_bss_chan_info_event {
|
||||
__le32 pdev_id;
|
||||
__le32 freq; /* Units in MHz */
|
||||
__le32 noise_floor; /* units are dBm */
|
||||
/* rx clear - how often the channel was unused */
|
||||
@@ -4103,6 +4103,7 @@ struct wmi_pdev_bss_chan_info_event {
|
||||
/*rx_cycle cnt for my bss in 64bits format */
|
||||
__le32 rx_bss_cycle_count_low;
|
||||
__le32 rx_bss_cycle_count_high;
|
||||
__le32 pdev_id;
|
||||
} __packed;
|
||||
|
||||
#define WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS 0
|
||||
|
||||
@@ -65,7 +65,7 @@ static int ath9k_pci_fixup(struct pci_dev *pdev, const u16 *cal_data,
|
||||
|
||||
dev_info(&pdev->dev, "fixup device configuration\n");
|
||||
|
||||
mem = pcim_iomap(pdev, 0, 0);
|
||||
mem = pci_iomap(pdev, 0, 0);
|
||||
if (!mem) {
|
||||
dev_err(&pdev->dev, "ioremap error\n");
|
||||
return -EINVAL;
|
||||
@@ -103,7 +103,7 @@ static int ath9k_pci_fixup(struct pci_dev *pdev, const u16 *cal_data,
|
||||
pci_write_config_word(pdev, PCI_COMMAND, cmd);
|
||||
|
||||
pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, bar0);
|
||||
pcim_iounmap(pdev, mem);
|
||||
pci_iounmap(pdev, mem);
|
||||
|
||||
pci_disable_device(pdev);
|
||||
|
||||
@@ -200,11 +200,9 @@ static int owl_probe(struct pci_dev *pdev,
|
||||
const char *eeprom_name;
|
||||
int err = 0;
|
||||
|
||||
if (pcim_enable_device(pdev))
|
||||
if (pci_enable_device(pdev))
|
||||
return -EIO;
|
||||
|
||||
pcim_pin_device(pdev);
|
||||
|
||||
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -32,11 +32,8 @@ static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
|
||||
|
||||
for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
|
||||
for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
|
||||
if (sort[j] > sort[j - 1]) {
|
||||
nfval = sort[j];
|
||||
sort[j] = sort[j - 1];
|
||||
sort[j - 1] = nfval;
|
||||
}
|
||||
if (sort[j] > sort[j - 1])
|
||||
swap(sort[j], sort[j - 1]);
|
||||
}
|
||||
}
|
||||
nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
|
||||
|
||||
@@ -1325,11 +1325,11 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw,
|
||||
struct ath_softc *sc = hw->priv;
|
||||
int i = 0;
|
||||
|
||||
data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all +
|
||||
data[i++] = ((u64)sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all +
|
||||
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all +
|
||||
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all +
|
||||
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all);
|
||||
data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all +
|
||||
data[i++] = ((u64)sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all +
|
||||
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all +
|
||||
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all +
|
||||
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all);
|
||||
@@ -1380,8 +1380,6 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||
|
||||
sc->debug.debugfs_phy = debugfs_create_dir("ath9k",
|
||||
sc->hw->wiphy->debugfsdir);
|
||||
if (IS_ERR(sc->debug.debugfs_phy))
|
||||
return -ENOMEM;
|
||||
|
||||
#ifdef CONFIG_ATH_DEBUG
|
||||
debugfs_create_file("debug", 0600, sc->debug.debugfs_phy,
|
||||
|
||||
@@ -486,8 +486,6 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
|
||||
|
||||
priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
|
||||
priv->hw->wiphy->debugfsdir);
|
||||
if (IS_ERR(priv->debug.debugfs_phy))
|
||||
return -ENOMEM;
|
||||
|
||||
ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy);
|
||||
|
||||
|
||||
@@ -2732,7 +2732,7 @@ static void ath9k_hw_gpio_cfg_soc(struct ath_hw *ah, u32 gpio, bool out,
|
||||
if (ah->caps.gpio_requested & BIT(gpio))
|
||||
return;
|
||||
|
||||
err = gpio_request_one(gpio, out ? GPIOF_OUT_INIT_LOW : GPIOF_IN, label);
|
||||
err = devm_gpio_request_one(ah->dev, gpio, out ? GPIOF_OUT_INIT_LOW : GPIOF_IN, label);
|
||||
if (err) {
|
||||
ath_err(ath9k_hw_common(ah), "request GPIO%d failed:%d\n",
|
||||
gpio, err);
|
||||
@@ -2801,10 +2801,8 @@ void ath9k_hw_gpio_free(struct ath_hw *ah, u32 gpio)
|
||||
|
||||
WARN_ON(gpio >= ah->caps.num_gpio_pins);
|
||||
|
||||
if (ah->caps.gpio_requested & BIT(gpio)) {
|
||||
gpio_free(gpio);
|
||||
if (ah->caps.gpio_requested & BIT(gpio))
|
||||
ah->caps.gpio_requested &= ~BIT(gpio);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_gpio_free);
|
||||
|
||||
|
||||
@@ -1066,7 +1066,7 @@ static const u32 lpphy_papd_mult_table[] = {
|
||||
0x00036963, 0x000339f2, 0x00030a89, 0x0002db28,
|
||||
};
|
||||
|
||||
static struct lpphy_tx_gain_table_entry lpphy_rev0_nopa_tx_gain_table[] = {
|
||||
static const struct lpphy_tx_gain_table_entry lpphy_rev0_nopa_tx_gain_table[] = {
|
||||
{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 152, },
|
||||
{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 147, },
|
||||
{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 143, },
|
||||
@@ -1197,7 +1197,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev0_nopa_tx_gain_table[] = {
|
||||
{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 71, },
|
||||
};
|
||||
|
||||
static struct lpphy_tx_gain_table_entry lpphy_rev0_2ghz_tx_gain_table[] = {
|
||||
static const struct lpphy_tx_gain_table_entry lpphy_rev0_2ghz_tx_gain_table[] = {
|
||||
{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 64, },
|
||||
{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 62, },
|
||||
{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 60, },
|
||||
@@ -1328,7 +1328,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev0_2ghz_tx_gain_table[] = {
|
||||
{ .gm = 4, .pga = 4, .pad = 2, .dac = 0, .bb_mult = 72, },
|
||||
};
|
||||
|
||||
static struct lpphy_tx_gain_table_entry lpphy_rev0_5ghz_tx_gain_table[] = {
|
||||
static const struct lpphy_tx_gain_table_entry lpphy_rev0_5ghz_tx_gain_table[] = {
|
||||
{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 99, },
|
||||
{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 96, },
|
||||
{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 93, },
|
||||
@@ -1459,7 +1459,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev0_5ghz_tx_gain_table[] = {
|
||||
{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 60, },
|
||||
};
|
||||
|
||||
static struct lpphy_tx_gain_table_entry lpphy_rev1_nopa_tx_gain_table[] = {
|
||||
static const struct lpphy_tx_gain_table_entry lpphy_rev1_nopa_tx_gain_table[] = {
|
||||
{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 152, },
|
||||
{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 147, },
|
||||
{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 143, },
|
||||
@@ -1599,7 +1599,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev1_nopa_tx_gain_table[] = {
|
||||
{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 71, },
|
||||
};
|
||||
|
||||
static struct lpphy_tx_gain_table_entry lpphy_rev1_2ghz_tx_gain_table[] = {
|
||||
static const struct lpphy_tx_gain_table_entry lpphy_rev1_2ghz_tx_gain_table[] = {
|
||||
{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 90, },
|
||||
{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 88, },
|
||||
{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 85, },
|
||||
@@ -1730,7 +1730,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev1_2ghz_tx_gain_table[] = {
|
||||
{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 60, },
|
||||
};
|
||||
|
||||
static struct lpphy_tx_gain_table_entry lpphy_rev1_5ghz_tx_gain_table[] = {
|
||||
static const struct lpphy_tx_gain_table_entry lpphy_rev1_5ghz_tx_gain_table[] = {
|
||||
{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 99, },
|
||||
{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 96, },
|
||||
{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 93, },
|
||||
@@ -1861,7 +1861,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev1_5ghz_tx_gain_table[] = {
|
||||
{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 60, },
|
||||
};
|
||||
|
||||
static struct lpphy_tx_gain_table_entry lpphy_rev2_nopa_tx_gain_table[] = {
|
||||
static const struct lpphy_tx_gain_table_entry lpphy_rev2_nopa_tx_gain_table[] = {
|
||||
{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 152, },
|
||||
{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 147, },
|
||||
{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 143, },
|
||||
@@ -1992,7 +1992,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev2_nopa_tx_gain_table[] = {
|
||||
{ .gm = 255, .pga = 111, .pad = 29, .dac = 0, .bb_mult = 64, },
|
||||
};
|
||||
|
||||
static struct lpphy_tx_gain_table_entry lpphy_rev2_2ghz_tx_gain_table[] = {
|
||||
static const struct lpphy_tx_gain_table_entry lpphy_rev2_2ghz_tx_gain_table[] = {
|
||||
{ .gm = 7, .pga = 99, .pad = 255, .dac = 0, .bb_mult = 64, },
|
||||
{ .gm = 7, .pga = 96, .pad = 255, .dac = 0, .bb_mult = 64, },
|
||||
{ .gm = 7, .pga = 93, .pad = 255, .dac = 0, .bb_mult = 64, },
|
||||
@@ -2123,7 +2123,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev2_2ghz_tx_gain_table[] = {
|
||||
{ .gm = 7, .pga = 13, .pad = 52, .dac = 0, .bb_mult = 64, },
|
||||
};
|
||||
|
||||
static struct lpphy_tx_gain_table_entry lpphy_rev2_5ghz_tx_gain_table[] = {
|
||||
static const struct lpphy_tx_gain_table_entry lpphy_rev2_5ghz_tx_gain_table[] = {
|
||||
{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 152, },
|
||||
{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 147, },
|
||||
{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 143, },
|
||||
@@ -2392,7 +2392,7 @@ void lpphy_write_gain_table(struct b43_wldev *dev, int offset,
|
||||
}
|
||||
|
||||
void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count,
|
||||
struct lpphy_tx_gain_table_entry *table)
|
||||
const struct lpphy_tx_gain_table_entry *table)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ struct lpphy_tx_gain_table_entry {
|
||||
void lpphy_write_gain_table(struct b43_wldev *dev, int offset,
|
||||
struct lpphy_tx_gain_table_entry data);
|
||||
void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count,
|
||||
struct lpphy_tx_gain_table_entry *table);
|
||||
const struct lpphy_tx_gain_table_entry *table);
|
||||
|
||||
void lpphy_rev0_1_table_init(struct b43_wldev *dev);
|
||||
void lpphy_rev2plus_table_init(struct b43_wldev *dev);
|
||||
|
||||
@@ -123,7 +123,7 @@ static s32 brcmf_btcoex_params_read(struct brcmf_if *ifp, u32 addr, u32 *data)
|
||||
{
|
||||
*data = addr;
|
||||
|
||||
return brcmf_fil_iovar_int_get(ifp, "btc_params", data);
|
||||
return brcmf_fil_iovar_int_query(ifp, "btc_params", data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -663,8 +663,8 @@ static int brcmf_cfg80211_request_sta_if(struct brcmf_if *ifp, u8 *macaddr)
|
||||
/* interface_create version 3+ */
|
||||
/* get supported version from firmware side */
|
||||
iface_create_ver = 0;
|
||||
err = brcmf_fil_bsscfg_int_get(ifp, "interface_create",
|
||||
&iface_create_ver);
|
||||
err = brcmf_fil_bsscfg_int_query(ifp, "interface_create",
|
||||
&iface_create_ver);
|
||||
if (err) {
|
||||
brcmf_err("fail to get supported version, err=%d\n", err);
|
||||
return -EOPNOTSUPP;
|
||||
@@ -756,8 +756,8 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
|
||||
/* interface_create version 3+ */
|
||||
/* get supported version from firmware side */
|
||||
iface_create_ver = 0;
|
||||
err = brcmf_fil_bsscfg_int_get(ifp, "interface_create",
|
||||
&iface_create_ver);
|
||||
err = brcmf_fil_bsscfg_int_query(ifp, "interface_create",
|
||||
&iface_create_ver);
|
||||
if (err) {
|
||||
brcmf_err("fail to get supported version, err=%d\n", err);
|
||||
return -EOPNOTSUPP;
|
||||
@@ -2101,7 +2101,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
|
||||
if (!sme->crypto.n_akm_suites)
|
||||
return 0;
|
||||
|
||||
err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val);
|
||||
err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
|
||||
"wpa_auth", &val);
|
||||
if (err) {
|
||||
bphy_err(drvr, "could not get wpa_auth (%d)\n", err);
|
||||
return err;
|
||||
@@ -2680,7 +2681,7 @@ brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
|
||||
struct brcmf_pub *drvr = cfg->pub;
|
||||
s32 qdbm = 0;
|
||||
s32 qdbm;
|
||||
s32 err;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
@@ -3067,7 +3068,7 @@ brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
|
||||
struct brcmf_scb_val_le scbval;
|
||||
struct brcmf_pktcnt_le pktcnt;
|
||||
s32 err;
|
||||
u32 rate = 0;
|
||||
u32 rate;
|
||||
u32 rssi;
|
||||
|
||||
/* Get the current tx rate */
|
||||
@@ -7046,8 +7047,8 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
|
||||
ch.bw = BRCMU_CHAN_BW_20;
|
||||
cfg->d11inf.encchspec(&ch);
|
||||
chaninfo = ch.chspec;
|
||||
err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
|
||||
&chaninfo);
|
||||
err = brcmf_fil_bsscfg_int_query(ifp, "per_chan_info",
|
||||
&chaninfo);
|
||||
if (!err) {
|
||||
if (chaninfo & WL_CHAN_RADAR)
|
||||
channel->flags |=
|
||||
@@ -7081,7 +7082,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
|
||||
|
||||
/* verify support for bw_cap command */
|
||||
val = WLC_BAND_5G;
|
||||
err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
|
||||
err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &val);
|
||||
|
||||
if (!err) {
|
||||
/* only set 2G bandwidth using bw_cap command */
|
||||
@@ -7157,11 +7158,11 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
|
||||
int err;
|
||||
|
||||
band = WLC_BAND_2G;
|
||||
err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
|
||||
err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &band);
|
||||
if (!err) {
|
||||
bw_cap[NL80211_BAND_2GHZ] = band;
|
||||
band = WLC_BAND_5G;
|
||||
err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
|
||||
err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &band);
|
||||
if (!err) {
|
||||
bw_cap[NL80211_BAND_5GHZ] = band;
|
||||
return;
|
||||
@@ -7170,7 +7171,6 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
|
||||
return;
|
||||
}
|
||||
brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
|
||||
mimo_bwcap = 0;
|
||||
err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
|
||||
if (err)
|
||||
/* assume 20MHz if firmware does not give a clue */
|
||||
@@ -7266,10 +7266,10 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
|
||||
struct brcmf_pub *drvr = cfg->pub;
|
||||
struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
|
||||
struct wiphy *wiphy = cfg_to_wiphy(cfg);
|
||||
u32 nmode = 0;
|
||||
u32 nmode;
|
||||
u32 vhtmode = 0;
|
||||
u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
|
||||
u32 rxchain = 0;
|
||||
u32 rxchain;
|
||||
u32 nchain;
|
||||
int err;
|
||||
s32 i;
|
||||
|
||||
@@ -691,7 +691,7 @@ static int brcmf_net_mon_open(struct net_device *ndev)
|
||||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
struct brcmf_pub *drvr = ifp->drvr;
|
||||
u32 monitor = 0;
|
||||
u32 monitor;
|
||||
int err;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
@@ -48,20 +48,20 @@
|
||||
/**
|
||||
* struct brcmf_ampdu_rx_reorder - AMPDU receive reorder info
|
||||
*
|
||||
* @pktslots: dynamic allocated array for ordering AMPDU packets.
|
||||
* @flow_id: AMPDU flow identifier.
|
||||
* @cur_idx: last AMPDU index from firmware.
|
||||
* @exp_idx: expected next AMPDU index.
|
||||
* @max_idx: maximum amount of packets per AMPDU.
|
||||
* @pend_pkts: number of packets currently in @pktslots.
|
||||
* @pktslots: array for ordering AMPDU packets.
|
||||
*/
|
||||
struct brcmf_ampdu_rx_reorder {
|
||||
struct sk_buff **pktslots;
|
||||
u8 flow_id;
|
||||
u8 cur_idx;
|
||||
u8 exp_idx;
|
||||
u8 max_idx;
|
||||
u8 pend_pkts;
|
||||
struct sk_buff *pktslots[];
|
||||
};
|
||||
|
||||
/* Forward decls for struct brcmf_pub (see below) */
|
||||
|
||||
@@ -184,7 +184,7 @@ static void brcmf_feat_wlc_version_overrides(struct brcmf_pub *drv)
|
||||
static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
|
||||
enum brcmf_feat_id id, char *name)
|
||||
{
|
||||
u32 data = 0;
|
||||
u32 data;
|
||||
int err;
|
||||
|
||||
/* we need to know firmware error */
|
||||
|
||||
@@ -96,15 +96,22 @@ static inline
|
||||
s32 brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data)
|
||||
{
|
||||
s32 err;
|
||||
__le32 data_le = cpu_to_le32(*data);
|
||||
|
||||
err = brcmf_fil_cmd_data_get(ifp, cmd, &data_le, sizeof(data_le));
|
||||
err = brcmf_fil_cmd_data_get(ifp, cmd, data, sizeof(*data));
|
||||
if (err == 0)
|
||||
*data = le32_to_cpu(data_le);
|
||||
*data = le32_to_cpu(*(__le32 *)data);
|
||||
brcmf_dbg(FIL, "ifidx=%d, cmd=%d, value=%d\n", ifp->ifidx, cmd, *data);
|
||||
|
||||
return err;
|
||||
}
|
||||
static inline
|
||||
s32 brcmf_fil_cmd_int_query(struct brcmf_if *ifp, u32 cmd, u32 *data)
|
||||
{
|
||||
__le32 *data_le = (__le32 *)data;
|
||||
|
||||
*data_le = cpu_to_le32(*data);
|
||||
return brcmf_fil_cmd_int_get(ifp, cmd, data);
|
||||
}
|
||||
|
||||
s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, const char *name,
|
||||
const void *data, u32 len);
|
||||
@@ -120,14 +127,21 @@ s32 brcmf_fil_iovar_int_set(struct brcmf_if *ifp, const char *name, u32 data)
|
||||
static inline
|
||||
s32 brcmf_fil_iovar_int_get(struct brcmf_if *ifp, const char *name, u32 *data)
|
||||
{
|
||||
__le32 data_le = cpu_to_le32(*data);
|
||||
s32 err;
|
||||
|
||||
err = brcmf_fil_iovar_data_get(ifp, name, &data_le, sizeof(data_le));
|
||||
err = brcmf_fil_iovar_data_get(ifp, name, data, sizeof(*data));
|
||||
if (err == 0)
|
||||
*data = le32_to_cpu(data_le);
|
||||
*data = le32_to_cpu(*(__le32 *)data);
|
||||
return err;
|
||||
}
|
||||
static inline
|
||||
s32 brcmf_fil_iovar_int_query(struct brcmf_if *ifp, const char *name, u32 *data)
|
||||
{
|
||||
__le32 *data_le = (__le32 *)data;
|
||||
|
||||
*data_le = cpu_to_le32(*data);
|
||||
return brcmf_fil_iovar_int_get(ifp, name, data);
|
||||
}
|
||||
|
||||
|
||||
s32 brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, const char *name,
|
||||
@@ -145,15 +159,21 @@ s32 brcmf_fil_bsscfg_int_set(struct brcmf_if *ifp, const char *name, u32 data)
|
||||
static inline
|
||||
s32 brcmf_fil_bsscfg_int_get(struct brcmf_if *ifp, const char *name, u32 *data)
|
||||
{
|
||||
__le32 data_le = cpu_to_le32(*data);
|
||||
s32 err;
|
||||
|
||||
err = brcmf_fil_bsscfg_data_get(ifp, name, &data_le,
|
||||
sizeof(data_le));
|
||||
err = brcmf_fil_bsscfg_data_get(ifp, name, data, sizeof(*data));
|
||||
if (err == 0)
|
||||
*data = le32_to_cpu(data_le);
|
||||
*data = le32_to_cpu(*(__le32 *)data);
|
||||
return err;
|
||||
}
|
||||
static inline
|
||||
s32 brcmf_fil_bsscfg_int_query(struct brcmf_if *ifp, const char *name, u32 *data)
|
||||
{
|
||||
__le32 *data_le = (__le32 *)data;
|
||||
|
||||
*data_le = cpu_to_le32(*data);
|
||||
return brcmf_fil_bsscfg_int_get(ifp, name, data);
|
||||
}
|
||||
|
||||
s32 brcmf_fil_xtlv_data_set(struct brcmf_if *ifp, const char *name, u16 id,
|
||||
void *data, u32 len);
|
||||
|
||||
@@ -1673,7 +1673,6 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt)
|
||||
struct sk_buff_head reorder_list;
|
||||
struct sk_buff *pnext;
|
||||
u8 flags;
|
||||
u32 buf_size;
|
||||
|
||||
reorder_data = ((struct brcmf_skb_reorder_data *)pkt->cb)->reorder;
|
||||
flow_id = reorder_data[BRCMF_RXREORDER_FLOWID_OFFSET];
|
||||
@@ -1708,15 +1707,13 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt)
|
||||
}
|
||||
/* from here on we need a flow reorder instance */
|
||||
if (rfi == NULL) {
|
||||
buf_size = sizeof(*rfi);
|
||||
max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET];
|
||||
|
||||
buf_size += (max_idx + 1) * sizeof(pkt);
|
||||
|
||||
/* allocate space for flow reorder info */
|
||||
brcmf_dbg(INFO, "flow-%d: start, maxidx %d\n",
|
||||
flow_id, max_idx);
|
||||
rfi = kzalloc(buf_size, GFP_ATOMIC);
|
||||
rfi = kzalloc(struct_size(rfi, pktslots, max_idx + 1),
|
||||
GFP_ATOMIC);
|
||||
if (rfi == NULL) {
|
||||
bphy_err(drvr, "failed to alloc buffer\n");
|
||||
brcmf_netif_rx(ifp, pkt);
|
||||
@@ -1724,7 +1721,6 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt)
|
||||
}
|
||||
|
||||
ifp->drvr->reorder_flows[flow_id] = rfi;
|
||||
rfi->pktslots = (struct sk_buff **)(rfi + 1);
|
||||
rfi->max_idx = max_idx;
|
||||
}
|
||||
if (flags & BRCMF_RXREORDER_NEW_HOLE) {
|
||||
|
||||
@@ -351,9 +351,7 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
|
||||
{
|
||||
struct ampdu_info *ampdu = wlc->ampdu;
|
||||
u32 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
|
||||
u32 txunfl_ratio;
|
||||
u8 max_mpdu;
|
||||
u32 current_ampdu_cnt = 0;
|
||||
u16 max_pld_size;
|
||||
u32 new_txunfl;
|
||||
struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid);
|
||||
@@ -389,26 +387,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
|
||||
if (fifo->accum_txfunfl < 10)
|
||||
return 0;
|
||||
|
||||
brcms_dbg_ht(wlc->hw->d11core, "ampdu_count %d tx_underflows %d\n",
|
||||
current_ampdu_cnt, fifo->accum_txfunfl);
|
||||
brcms_dbg_ht(wlc->hw->d11core, "tx_underflows %d\n", fifo->accum_txfunfl);
|
||||
|
||||
/*
|
||||
compute the current ratio of tx unfl per ampdu.
|
||||
When the current ampdu count becomes too
|
||||
big while the ratio remains small, we reset
|
||||
the current count in order to not
|
||||
introduce too big of a latency in detecting a
|
||||
large amount of tx underflows later.
|
||||
*/
|
||||
|
||||
txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
|
||||
|
||||
if (txunfl_ratio > ampdu->tx_max_funl) {
|
||||
if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT)
|
||||
fifo->accum_txfunfl = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
|
||||
AMPDU_NUM_MPDU_LEGACY);
|
||||
|
||||
|
||||
@@ -1611,10 +1611,9 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx)
|
||||
if (le32_to_cpu(hdr->idx) == idx) {
|
||||
pdata = wl->fw.fw_bin[i]->data +
|
||||
le32_to_cpu(hdr->offset);
|
||||
*pbuf = kvmalloc(len, GFP_KERNEL);
|
||||
*pbuf = kvmemdup(pdata, len, GFP_KERNEL);
|
||||
if (*pbuf == NULL)
|
||||
goto fail;
|
||||
memcpy(*pbuf, pdata, len);
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1622,7 +1621,6 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx)
|
||||
brcms_err(wl->wlc->hw->d11core,
|
||||
"ERROR: ucode buf tag:%d can not be found!\n", idx);
|
||||
*pbuf = NULL;
|
||||
fail:
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
|
||||
@@ -345,14 +345,19 @@ struct libipw_hdr_2addr {
|
||||
} __packed;
|
||||
|
||||
struct libipw_hdr_3addr {
|
||||
__le16 frame_ctl;
|
||||
__le16 duration_id;
|
||||
u8 addr1[ETH_ALEN];
|
||||
u8 addr2[ETH_ALEN];
|
||||
u8 addr3[ETH_ALEN];
|
||||
__le16 seq_ctl;
|
||||
/* New members MUST be added within the __struct_group() macro below. */
|
||||
__struct_group(libipw_hdr_3addr_hdr, hdr, __packed,
|
||||
__le16 frame_ctl;
|
||||
__le16 duration_id;
|
||||
u8 addr1[ETH_ALEN];
|
||||
u8 addr2[ETH_ALEN];
|
||||
u8 addr3[ETH_ALEN];
|
||||
__le16 seq_ctl;
|
||||
);
|
||||
u8 payload[];
|
||||
} __packed;
|
||||
static_assert(offsetof(struct libipw_hdr_3addr, payload) == sizeof(struct libipw_hdr_3addr_hdr),
|
||||
"struct member likely outside of __struct_group()");
|
||||
|
||||
struct libipw_hdr_4addr {
|
||||
__le16 frame_ctl;
|
||||
@@ -400,7 +405,7 @@ struct libipw_info_element {
|
||||
*/
|
||||
|
||||
struct libipw_auth {
|
||||
struct libipw_hdr_3addr header;
|
||||
struct libipw_hdr_3addr_hdr header;
|
||||
__le16 algorithm;
|
||||
__le16 transaction;
|
||||
__le16 status;
|
||||
@@ -417,7 +422,7 @@ struct libipw_channel_switch {
|
||||
} __packed;
|
||||
|
||||
struct libipw_action {
|
||||
struct libipw_hdr_3addr header;
|
||||
struct libipw_hdr_3addr_hdr header;
|
||||
u8 category;
|
||||
u8 action;
|
||||
union {
|
||||
@@ -430,7 +435,7 @@ struct libipw_action {
|
||||
} __packed;
|
||||
|
||||
struct libipw_disassoc {
|
||||
struct libipw_hdr_3addr header;
|
||||
struct libipw_hdr_3addr_hdr header;
|
||||
__le16 reason;
|
||||
} __packed;
|
||||
|
||||
@@ -438,13 +443,13 @@ struct libipw_disassoc {
|
||||
#define libipw_deauth libipw_disassoc
|
||||
|
||||
struct libipw_probe_request {
|
||||
struct libipw_hdr_3addr header;
|
||||
struct libipw_hdr_3addr_hdr header;
|
||||
/* SSID, supported rates */
|
||||
u8 variable[];
|
||||
} __packed;
|
||||
|
||||
struct libipw_probe_response {
|
||||
struct libipw_hdr_3addr header;
|
||||
struct libipw_hdr_3addr_hdr header;
|
||||
__le32 time_stamp[2];
|
||||
__le16 beacon_interval;
|
||||
__le16 capability;
|
||||
@@ -456,16 +461,8 @@ struct libipw_probe_response {
|
||||
/* Alias beacon for probe_response */
|
||||
#define libipw_beacon libipw_probe_response
|
||||
|
||||
struct libipw_assoc_request {
|
||||
struct libipw_hdr_3addr header;
|
||||
__le16 capability;
|
||||
__le16 listen_interval;
|
||||
/* SSID, supported rates, RSN */
|
||||
u8 variable[];
|
||||
} __packed;
|
||||
|
||||
struct libipw_reassoc_request {
|
||||
struct libipw_hdr_3addr header;
|
||||
struct libipw_hdr_3addr_hdr header;
|
||||
__le16 capability;
|
||||
__le16 listen_interval;
|
||||
u8 current_ap[ETH_ALEN];
|
||||
@@ -473,7 +470,7 @@ struct libipw_reassoc_request {
|
||||
} __packed;
|
||||
|
||||
struct libipw_assoc_response {
|
||||
struct libipw_hdr_3addr header;
|
||||
struct libipw_hdr_3addr_hdr header;
|
||||
__le16 capability;
|
||||
__le16 status;
|
||||
__le16 aid;
|
||||
@@ -588,13 +585,6 @@ struct libipw_channel_map {
|
||||
u8 map;
|
||||
} __packed;
|
||||
|
||||
struct libipw_ibss_dfs {
|
||||
struct libipw_info_element ie;
|
||||
u8 owner[ETH_ALEN];
|
||||
u8 recovery_interval;
|
||||
struct libipw_channel_map channel_map[];
|
||||
};
|
||||
|
||||
struct libipw_csa {
|
||||
u8 mode;
|
||||
u8 channel;
|
||||
|
||||
@@ -509,7 +509,7 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
|
||||
int i, idx, ret = 0;
|
||||
int group_key = 0;
|
||||
const char *alg, *module;
|
||||
struct lib80211_crypto_ops *ops;
|
||||
const struct lib80211_crypto_ops *ops;
|
||||
struct lib80211_crypt_data **crypt;
|
||||
|
||||
struct libipw_security sec = {
|
||||
|
||||
@@ -527,7 +527,7 @@ il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
struct ieee80211_hdr *header;
|
||||
struct ieee80211_rx_status rx_status = {};
|
||||
struct il_rx_pkt *pkt = rxb_addr(rxb);
|
||||
struct il3945_rx_frame_stats *rx_stats = IL_RX_STATS(pkt);
|
||||
struct il3945_rx_frame_stats_hdr *rx_stats = IL_RX_STATS(pkt);
|
||||
struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt);
|
||||
struct il3945_rx_frame_end *rx_end = IL_RX_END(pkt);
|
||||
u16 rx_stats_sig_avg __maybe_unused = le16_to_cpu(rx_stats->sig_avg);
|
||||
|
||||
@@ -157,8 +157,10 @@ struct il3945_ibss_seq {
|
||||
};
|
||||
|
||||
#define IL_RX_HDR(x) ((struct il3945_rx_frame_hdr *)(\
|
||||
x->u.rx_frame.stats.payload + \
|
||||
x->u.rx_frame.stats.phy_count))
|
||||
container_of(&x->u.rx_frame.stats, \
|
||||
struct il3945_rx_frame_stats, \
|
||||
hdr)->payload + \
|
||||
x->u.rx_frame.stats.phy_count))
|
||||
#define IL_RX_END(x) ((struct il3945_rx_frame_end *)(\
|
||||
IL_RX_HDR(x)->payload + \
|
||||
le16_to_cpu(IL_RX_HDR(x)->len)))
|
||||
|
||||
@@ -1769,7 +1769,7 @@ il4965_tx_skb(struct il_priv *il,
|
||||
/* Set up first empty entry in queue's array of Tx/cmd buffers */
|
||||
out_cmd = txq->cmd[q->write_ptr];
|
||||
out_meta = &txq->meta[q->write_ptr];
|
||||
tx_cmd = &out_cmd->cmd.tx;
|
||||
tx_cmd = container_of(&out_cmd->cmd.tx, struct il_tx_cmd, __hdr);
|
||||
memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
|
||||
memset(tx_cmd, 0, sizeof(struct il_tx_cmd));
|
||||
|
||||
|
||||
@@ -201,9 +201,6 @@ struct il_cmd_header {
|
||||
* 15 unsolicited RX or uCode-originated notification
|
||||
*/
|
||||
__le16 sequence;
|
||||
|
||||
/* command or response/notification data follows immediately */
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
@@ -1160,23 +1157,33 @@ struct il_wep_cmd {
|
||||
#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800)
|
||||
|
||||
struct il3945_rx_frame_stats {
|
||||
u8 phy_count;
|
||||
u8 id;
|
||||
u8 rssi;
|
||||
u8 agc;
|
||||
__le16 sig_avg;
|
||||
__le16 noise_diff;
|
||||
/* New members MUST be added within the __struct_group() macro below. */
|
||||
__struct_group(il3945_rx_frame_stats_hdr, hdr, __packed,
|
||||
u8 phy_count;
|
||||
u8 id;
|
||||
u8 rssi;
|
||||
u8 agc;
|
||||
__le16 sig_avg;
|
||||
__le16 noise_diff;
|
||||
);
|
||||
u8 payload[];
|
||||
} __packed;
|
||||
static_assert(offsetof(struct il3945_rx_frame_stats, payload) == sizeof(struct il3945_rx_frame_stats_hdr),
|
||||
"struct member likely outside of __struct_group()");
|
||||
|
||||
struct il3945_rx_frame_hdr {
|
||||
__le16 channel;
|
||||
__le16 phy_flags;
|
||||
u8 reserved1;
|
||||
u8 rate;
|
||||
__le16 len;
|
||||
/* New members MUST be added within the __struct_group() macro below. */
|
||||
__struct_group(il3945_rx_frame_hdr_hdr, hdr, __packed,
|
||||
__le16 channel;
|
||||
__le16 phy_flags;
|
||||
u8 reserved1;
|
||||
u8 rate;
|
||||
__le16 len;
|
||||
);
|
||||
u8 payload[];
|
||||
} __packed;
|
||||
static_assert(offsetof(struct il3945_rx_frame_hdr, payload) == sizeof(struct il3945_rx_frame_hdr_hdr),
|
||||
"struct member likely outside of __struct_group()");
|
||||
|
||||
struct il3945_rx_frame_end {
|
||||
__le32 status;
|
||||
@@ -1193,8 +1200,8 @@ struct il3945_rx_frame_end {
|
||||
* stats.phy_count
|
||||
*/
|
||||
struct il3945_rx_frame {
|
||||
struct il3945_rx_frame_stats stats;
|
||||
struct il3945_rx_frame_hdr hdr;
|
||||
struct il3945_rx_frame_stats_hdr stats;
|
||||
struct il3945_rx_frame_hdr_hdr hdr;
|
||||
struct il3945_rx_frame_end end;
|
||||
} __packed;
|
||||
|
||||
@@ -1352,67 +1359,69 @@ struct il_rx_mpdu_res_start {
|
||||
*/
|
||||
|
||||
struct il3945_tx_cmd {
|
||||
/*
|
||||
* MPDU byte count:
|
||||
* MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
|
||||
* + 8 byte IV for CCM or TKIP (not used for WEP)
|
||||
* + Data payload
|
||||
* + 8-byte MIC (not used for CCM/WEP)
|
||||
* NOTE: Does not include Tx command bytes, post-MAC pad bytes,
|
||||
* MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
|
||||
* Range: 14-2342 bytes.
|
||||
*/
|
||||
__le16 len;
|
||||
/* New members MUST be added within the __struct_group() macro below. */
|
||||
__struct_group(il3945_tx_cmd_hdr, __hdr, __packed,
|
||||
/*
|
||||
* MPDU byte count:
|
||||
* MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
|
||||
* + 8 byte IV for CCM or TKIP (not used for WEP)
|
||||
* + Data payload
|
||||
* + 8-byte MIC (not used for CCM/WEP)
|
||||
* NOTE: Does not include Tx command bytes, post-MAC pad bytes,
|
||||
* MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
|
||||
* Range: 14-2342 bytes.
|
||||
*/
|
||||
__le16 len;
|
||||
|
||||
/*
|
||||
* MPDU or MSDU byte count for next frame.
|
||||
* Used for fragmentation and bursting, but not 11n aggregation.
|
||||
* Same as "len", but for next frame. Set to 0 if not applicable.
|
||||
*/
|
||||
__le16 next_frame_len;
|
||||
/*
|
||||
* MPDU or MSDU byte count for next frame.
|
||||
* Used for fragmentation and bursting, but not 11n aggregation.
|
||||
* Same as "len", but for next frame. Set to 0 if not applicable.
|
||||
*/
|
||||
__le16 next_frame_len;
|
||||
|
||||
__le32 tx_flags; /* TX_CMD_FLG_* */
|
||||
__le32 tx_flags; /* TX_CMD_FLG_* */
|
||||
|
||||
u8 rate;
|
||||
u8 rate;
|
||||
|
||||
/* Index of recipient station in uCode's station table */
|
||||
u8 sta_id;
|
||||
u8 tid_tspec;
|
||||
u8 sec_ctl;
|
||||
u8 key[16];
|
||||
union {
|
||||
u8 byte[8];
|
||||
__le16 word[4];
|
||||
__le32 dw[2];
|
||||
} tkip_mic;
|
||||
__le32 next_frame_info;
|
||||
union {
|
||||
__le32 life_time;
|
||||
__le32 attempt;
|
||||
} stop_time;
|
||||
u8 supp_rates[2];
|
||||
u8 rts_retry_limit; /*byte 50 */
|
||||
u8 data_retry_limit; /*byte 51 */
|
||||
union {
|
||||
__le16 pm_frame_timeout;
|
||||
__le16 attempt_duration;
|
||||
} timeout;
|
||||
/* Index of recipient station in uCode's station table */
|
||||
u8 sta_id;
|
||||
u8 tid_tspec;
|
||||
u8 sec_ctl;
|
||||
u8 key[16];
|
||||
union {
|
||||
u8 byte[8];
|
||||
__le16 word[4];
|
||||
__le32 dw[2];
|
||||
} tkip_mic;
|
||||
__le32 next_frame_info;
|
||||
union {
|
||||
__le32 life_time;
|
||||
__le32 attempt;
|
||||
} stop_time;
|
||||
u8 supp_rates[2];
|
||||
u8 rts_retry_limit; /*byte 50 */
|
||||
u8 data_retry_limit; /*byte 51 */
|
||||
union {
|
||||
__le16 pm_frame_timeout;
|
||||
__le16 attempt_duration;
|
||||
} timeout;
|
||||
|
||||
/*
|
||||
* Duration of EDCA burst Tx Opportunity, in 32-usec units.
|
||||
* Set this if txop time is not specified by HCCA protocol (e.g. by AP).
|
||||
*/
|
||||
__le16 driver_txop;
|
||||
/*
|
||||
* Duration of EDCA burst Tx Opportunity, in 32-usec units.
|
||||
* Set this if txop time is not specified by HCCA protocol (e.g. by AP).
|
||||
*/
|
||||
__le16 driver_txop;
|
||||
);
|
||||
|
||||
/*
|
||||
* MAC header goes here, followed by 2 bytes padding if MAC header
|
||||
* length is 26 or 30 bytes, followed by payload data
|
||||
*/
|
||||
union {
|
||||
DECLARE_FLEX_ARRAY(u8, payload);
|
||||
DECLARE_FLEX_ARRAY(struct ieee80211_hdr, hdr);
|
||||
};
|
||||
struct ieee80211_hdr hdr[];
|
||||
} __packed;
|
||||
static_assert(offsetof(struct il3945_tx_cmd, hdr) == sizeof(struct il3945_tx_cmd_hdr),
|
||||
"struct member likely outside of __struct_group()");
|
||||
|
||||
/*
|
||||
* C_TX = 0x1c (response)
|
||||
@@ -1438,83 +1447,87 @@ struct il_dram_scratch {
|
||||
} __packed;
|
||||
|
||||
struct il_tx_cmd {
|
||||
/*
|
||||
* MPDU byte count:
|
||||
* MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
|
||||
* + 8 byte IV for CCM or TKIP (not used for WEP)
|
||||
* + Data payload
|
||||
* + 8-byte MIC (not used for CCM/WEP)
|
||||
* NOTE: Does not include Tx command bytes, post-MAC pad bytes,
|
||||
* MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
|
||||
* Range: 14-2342 bytes.
|
||||
*/
|
||||
__le16 len;
|
||||
/* New members MUST be added within the __struct_group() macro below. */
|
||||
__struct_group(il_tx_cmd_hdr, __hdr, __packed,
|
||||
/*
|
||||
* MPDU byte count:
|
||||
* MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
|
||||
* + 8 byte IV for CCM or TKIP (not used for WEP)
|
||||
* + Data payload
|
||||
* + 8-byte MIC (not used for CCM/WEP)
|
||||
* NOTE: Does not include Tx command bytes, post-MAC pad bytes,
|
||||
* MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
|
||||
* Range: 14-2342 bytes.
|
||||
*/
|
||||
__le16 len;
|
||||
|
||||
/*
|
||||
* MPDU or MSDU byte count for next frame.
|
||||
* Used for fragmentation and bursting, but not 11n aggregation.
|
||||
* Same as "len", but for next frame. Set to 0 if not applicable.
|
||||
*/
|
||||
__le16 next_frame_len;
|
||||
/*
|
||||
* MPDU or MSDU byte count for next frame.
|
||||
* Used for fragmentation and bursting, but not 11n aggregation.
|
||||
* Same as "len", but for next frame. Set to 0 if not applicable.
|
||||
*/
|
||||
__le16 next_frame_len;
|
||||
|
||||
__le32 tx_flags; /* TX_CMD_FLG_* */
|
||||
__le32 tx_flags; /* TX_CMD_FLG_* */
|
||||
|
||||
/* uCode may modify this field of the Tx command (in host DRAM!).
|
||||
* Driver must also set dram_lsb_ptr and dram_msb_ptr in this cmd. */
|
||||
struct il_dram_scratch scratch;
|
||||
/* uCode may modify this field of the Tx command (in host DRAM!).
|
||||
* Driver must also set dram_lsb_ptr and dram_msb_ptr in this cmd. */
|
||||
struct il_dram_scratch scratch;
|
||||
|
||||
/* Rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is cleared. */
|
||||
__le32 rate_n_flags; /* RATE_MCS_* */
|
||||
/* Rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is cleared. */
|
||||
__le32 rate_n_flags; /* RATE_MCS_* */
|
||||
|
||||
/* Index of destination station in uCode's station table */
|
||||
u8 sta_id;
|
||||
/* Index of destination station in uCode's station table */
|
||||
u8 sta_id;
|
||||
|
||||
/* Type of security encryption: CCM or TKIP */
|
||||
u8 sec_ctl; /* TX_CMD_SEC_* */
|
||||
/* Type of security encryption: CCM or TKIP */
|
||||
u8 sec_ctl; /* TX_CMD_SEC_* */
|
||||
|
||||
/*
|
||||
* Index into rate table (see C_TX_LINK_QUALITY_CMD) for initial
|
||||
* Tx attempt, if TX_CMD_FLG_STA_RATE_MSK is set. Normally "0" for
|
||||
* data frames, this field may be used to selectively reduce initial
|
||||
* rate (via non-0 value) for special frames (e.g. management), while
|
||||
* still supporting rate scaling for all frames.
|
||||
*/
|
||||
u8 initial_rate_idx;
|
||||
u8 reserved;
|
||||
u8 key[16];
|
||||
__le16 next_frame_flags;
|
||||
__le16 reserved2;
|
||||
union {
|
||||
__le32 life_time;
|
||||
__le32 attempt;
|
||||
} stop_time;
|
||||
/*
|
||||
* Index into rate table (see C_TX_LINK_QUALITY_CMD) for initial
|
||||
* Tx attempt, if TX_CMD_FLG_STA_RATE_MSK is set. Normally "0" for
|
||||
* data frames, this field may be used to selectively reduce initial
|
||||
* rate (via non-0 value) for special frames (e.g. management), while
|
||||
* still supporting rate scaling for all frames.
|
||||
*/
|
||||
u8 initial_rate_idx;
|
||||
u8 reserved;
|
||||
u8 key[16];
|
||||
__le16 next_frame_flags;
|
||||
__le16 reserved2;
|
||||
union {
|
||||
__le32 life_time;
|
||||
__le32 attempt;
|
||||
} stop_time;
|
||||
|
||||
/* Host DRAM physical address pointer to "scratch" in this command.
|
||||
* Must be dword aligned. "0" in dram_lsb_ptr disables usage. */
|
||||
__le32 dram_lsb_ptr;
|
||||
u8 dram_msb_ptr;
|
||||
/* Host DRAM physical address pointer to "scratch" in this command.
|
||||
* Must be dword aligned. "0" in dram_lsb_ptr disables usage. */
|
||||
__le32 dram_lsb_ptr;
|
||||
u8 dram_msb_ptr;
|
||||
|
||||
u8 rts_retry_limit; /*byte 50 */
|
||||
u8 data_retry_limit; /*byte 51 */
|
||||
u8 tid_tspec;
|
||||
union {
|
||||
__le16 pm_frame_timeout;
|
||||
__le16 attempt_duration;
|
||||
} timeout;
|
||||
u8 rts_retry_limit; /*byte 50 */
|
||||
u8 data_retry_limit; /*byte 51 */
|
||||
u8 tid_tspec;
|
||||
union {
|
||||
__le16 pm_frame_timeout;
|
||||
__le16 attempt_duration;
|
||||
} timeout;
|
||||
|
||||
/*
|
||||
* Duration of EDCA burst Tx Opportunity, in 32-usec units.
|
||||
* Set this if txop time is not specified by HCCA protocol (e.g. by AP).
|
||||
*/
|
||||
__le16 driver_txop;
|
||||
/*
|
||||
* Duration of EDCA burst Tx Opportunity, in 32-usec units.
|
||||
* Set this if txop time is not specified by HCCA protocol (e.g. by AP).
|
||||
*/
|
||||
__le16 driver_txop;
|
||||
);
|
||||
|
||||
/*
|
||||
* MAC header goes here, followed by 2 bytes padding if MAC header
|
||||
* length is 26 or 30 bytes, followed by payload data
|
||||
*/
|
||||
u8 payload[0];
|
||||
struct ieee80211_hdr hdr[];
|
||||
} __packed;
|
||||
static_assert(offsetof(struct il_tx_cmd, hdr) == sizeof(struct il_tx_cmd_hdr),
|
||||
"struct member likely outside of __struct_group()");
|
||||
|
||||
/* TX command response is sent after *3945* transmission attempts.
|
||||
*
|
||||
@@ -2502,7 +2515,7 @@ struct il3945_scan_cmd {
|
||||
|
||||
/* For active scans (set to all-0s for passive scans).
|
||||
* Does not include payload. Must specify Tx rate; no rate scaling. */
|
||||
struct il3945_tx_cmd tx_cmd;
|
||||
struct il3945_tx_cmd_hdr tx_cmd;
|
||||
|
||||
/* For directed active scans (set to all-0s otherwise) */
|
||||
struct il_ssid_ie direct_scan[PROBE_OPTION_MAX_3945];
|
||||
@@ -2546,7 +2559,7 @@ struct il_scan_cmd {
|
||||
|
||||
/* For active scans (set to all-0s for passive scans).
|
||||
* Does not include payload. Must specify Tx rate; no rate scaling. */
|
||||
struct il_tx_cmd tx_cmd;
|
||||
struct il_tx_cmd_hdr tx_cmd;
|
||||
|
||||
/* For directed active scans (set to all-0s otherwise) */
|
||||
struct il_ssid_ie direct_scan[PROBE_OPTION_MAX];
|
||||
@@ -2662,7 +2675,7 @@ struct il4965_beacon_notif {
|
||||
*/
|
||||
|
||||
struct il3945_tx_beacon_cmd {
|
||||
struct il3945_tx_cmd tx;
|
||||
struct il3945_tx_cmd_hdr tx;
|
||||
__le16 tim_idx;
|
||||
u8 tim_size;
|
||||
u8 reserved1;
|
||||
@@ -2670,7 +2683,7 @@ struct il3945_tx_beacon_cmd {
|
||||
} __packed;
|
||||
|
||||
struct il_tx_beacon_cmd {
|
||||
struct il_tx_cmd tx;
|
||||
struct il_tx_cmd_hdr tx;
|
||||
__le16 tim_idx;
|
||||
u8 tim_size;
|
||||
u8 reserved1;
|
||||
|
||||
@@ -553,7 +553,7 @@ struct il_device_cmd {
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
u32 val32;
|
||||
struct il_tx_cmd tx;
|
||||
struct il_tx_cmd_hdr tx;
|
||||
u8 payload[DEF_CMD_PAYLOAD_SIZE];
|
||||
} __packed cmd;
|
||||
} __packed;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_BZ_UCODE_API_MAX 92
|
||||
#define IWL_BZ_UCODE_API_MAX 93
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_BZ_UCODE_API_MIN 90
|
||||
@@ -148,6 +148,17 @@ const struct iwl_cfg_trans_params iwl_bz_trans_cfg = {
|
||||
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_gl_trans_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_BZ,
|
||||
.base_params = &iwl_bz_base_params,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.umac_prph_offset = 0x300000,
|
||||
.xtal_latency = 12000,
|
||||
.low_latency_xtal = true,
|
||||
};
|
||||
|
||||
const char iwl_bz_name[] = "Intel(R) TBD Bz device";
|
||||
const char iwl_fm_name[] = "Intel(R) Wi-Fi 7 BE201 320MHz";
|
||||
const char iwl_gl_name[] = "Intel(R) Wi-Fi 7 BE200 320MHz";
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_SC_UCODE_API_MAX 92
|
||||
#define IWL_SC_UCODE_API_MAX 93
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_SC_UCODE_API_MIN 90
|
||||
|
||||
@@ -1325,8 +1325,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
iwlwifi_mod_params.amsdu_size);
|
||||
}
|
||||
|
||||
trans_cfg.cmd_q_wdg_timeout = IWL_WATCHDOG_DISABLED;
|
||||
|
||||
trans_cfg.command_groups = iwl_dvm_groups;
|
||||
trans_cfg.command_groups_size = ARRAY_SIZE(iwl_dvm_groups);
|
||||
|
||||
|
||||
@@ -357,6 +357,11 @@ int iwl_acpi_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc)
|
||||
}
|
||||
|
||||
mcc_val = wifi_pkg->package.elements[1].integer.value;
|
||||
if (mcc_val != BIOS_MCC_CHINA) {
|
||||
ret = -EINVAL;
|
||||
IWL_DEBUG_RADIO(fwrt, "ACPI WRDD is supported only for CN\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
mcc[0] = (mcc_val >> 8) & 0xff;
|
||||
mcc[1] = mcc_val & 0xff;
|
||||
|
||||
@@ -95,7 +95,7 @@ enum iwl_bt_ci_compliance {
|
||||
}; /* BT_COEX_CI_COMPLIENCE_E_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_bt_coex_profile_notif - notification about BT coex
|
||||
* struct iwl_bt_coex_prof_old_notif - notification about BT coex
|
||||
* @mbox_msg: message from BT to WiFi
|
||||
* @msg_idx: the index of the message
|
||||
* @bt_ci_compliance: enum %iwl_bt_ci_compliance
|
||||
@@ -110,7 +110,7 @@ enum iwl_bt_ci_compliance {
|
||||
* @wifi_loss_mid_high_rssi: The predicted lost WiFi rate (% of air time that
|
||||
* BT is utilizing) when the RSSI is mid/high (>= -65 dBm)
|
||||
*/
|
||||
struct iwl_bt_coex_profile_notif {
|
||||
struct iwl_bt_coex_prof_old_notif {
|
||||
__le32 mbox_msg[4];
|
||||
__le32 msg_idx;
|
||||
__le32 bt_ci_compliance;
|
||||
@@ -126,4 +126,29 @@ struct iwl_bt_coex_profile_notif {
|
||||
* BT_COEX_PROFILE_NTFY_API_S_VER_5
|
||||
*/
|
||||
|
||||
/**
|
||||
* enum iwl_bt_coex_subcmd_ids - coex configuration command IDs
|
||||
*/
|
||||
enum iwl_bt_coex_subcmd_ids {
|
||||
/**
|
||||
*@PROFILE_NOTIF: &struct iwl_bt_coex_profile_notif
|
||||
*/
|
||||
PROFILE_NOTIF = 0xFF,
|
||||
};
|
||||
|
||||
#define COEX_NUM_BAND 3
|
||||
#define COEX_NUM_CHAINS 2
|
||||
|
||||
/**
|
||||
* struct iwl_bt_coex_profile_notif - notification about BT coex
|
||||
* @wifi_loss_low_rssi: The predicted lost WiFi rate (% of air time that BT is
|
||||
* utilizing) when the RSSI is low (<= -65 dBm)
|
||||
* @wifi_loss_mid_high_rssi: The predicted lost WiFi rate (% of air time that
|
||||
* BT is utilizing) when the RSSI is mid/high (>= -65 dBm)
|
||||
*/
|
||||
struct iwl_bt_coex_profile_notif {
|
||||
u8 wifi_loss_low_rssi[COEX_NUM_BAND][COEX_NUM_CHAINS];
|
||||
u8 wifi_loss_mid_high_rssi[COEX_NUM_BAND][COEX_NUM_CHAINS];
|
||||
} __packed; /* BT_COEX_BT_PROFILE_NTF_API_S_VER_1 */
|
||||
|
||||
#endif /* __iwl_fw_api_coex_h__ */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2022 Intel Corporation
|
||||
* Copyright (C) 2018-2022, 2024 Intel Corporation
|
||||
*/
|
||||
#ifndef __iwl_fw_api_commands_h__
|
||||
#define __iwl_fw_api_commands_h__
|
||||
@@ -25,6 +25,8 @@
|
||||
* @NAN_GROUP: NAN group, uses command IDs from &enum iwl_nan_subcmd_ids
|
||||
* @LOCATION_GROUP: location group, uses command IDs from
|
||||
* &enum iwl_location_subcmd_ids
|
||||
* @BT_COEX_GROUP: bt coex group, uses command IDs from
|
||||
* &enum iwl_bt_coex_subcmd_ids
|
||||
* @PROT_OFFLOAD_GROUP: protocol offload group, uses command IDs from
|
||||
* &enum iwl_prot_offload_subcmd_ids
|
||||
* @REGULATORY_AND_NVM_GROUP: regulatory/NVM group, uses command IDs from
|
||||
@@ -43,6 +45,7 @@ enum iwl_mvm_command_groups {
|
||||
SCAN_GROUP = 0x6,
|
||||
NAN_GROUP = 0x7,
|
||||
LOCATION_GROUP = 0x8,
|
||||
BT_COEX_GROUP = 0x9,
|
||||
PROT_OFFLOAD_GROUP = 0xb,
|
||||
REGULATORY_AND_NVM_GROUP = 0xc,
|
||||
DEBUG_GROUP = 0xf,
|
||||
@@ -144,8 +147,8 @@ enum iwl_legacy_cmds {
|
||||
/**
|
||||
* @TX_CMD: uses &struct iwl_tx_cmd or &struct iwl_tx_cmd_gen2 or
|
||||
* &struct iwl_tx_cmd_gen3,
|
||||
* response in &struct iwl_mvm_tx_resp or
|
||||
* &struct iwl_mvm_tx_resp_v3
|
||||
* response in &struct iwl_tx_resp or
|
||||
* &struct iwl_tx_resp_v3
|
||||
*/
|
||||
TX_CMD = 0x1c,
|
||||
|
||||
@@ -398,7 +401,7 @@ enum iwl_legacy_cmds {
|
||||
REDUCE_TX_POWER_CMD = 0x9f,
|
||||
|
||||
/**
|
||||
* @MISSED_BEACONS_NOTIFICATION: &struct iwl_missed_beacons_notif
|
||||
* @MISSED_BEACONS_NOTIFICATION: &struct iwl_missed_beacons_notif_v4
|
||||
*/
|
||||
MISSED_BEACONS_NOTIFICATION = 0xa2,
|
||||
|
||||
@@ -467,7 +470,7 @@ enum iwl_legacy_cmds {
|
||||
MARKER_CMD = 0xcb,
|
||||
|
||||
/**
|
||||
* @BT_PROFILE_NOTIFICATION: &struct iwl_bt_coex_profile_notif
|
||||
* @BT_PROFILE_NOTIFICATION: &struct iwl_bt_coex_prof_old_notif
|
||||
*/
|
||||
BT_PROFILE_NOTIFICATION = 0xce,
|
||||
|
||||
|
||||
@@ -476,6 +476,8 @@ enum iwl_fw_ini_region_device_memory_subtype {
|
||||
* @IWL_FW_INI_TIME_POINT_PRESET_OVERRIDE_START: start handling override preset
|
||||
* request
|
||||
* @IWL_FW_INI_TIME_SCAN_FAILURE: failed scan channel list
|
||||
* @IWL_FW_INI_TIME_ESR_LINK_UP: EMLSR is active (several links are activated)
|
||||
* @IWL_FW_INI_TIME_ESR_LINK_DOWN: EMLSR is inactive (only one active link left)
|
||||
* @IWL_FW_INI_TIME_POINT_NUM: number of time points
|
||||
*/
|
||||
enum iwl_fw_ini_time_point {
|
||||
@@ -509,6 +511,8 @@ enum iwl_fw_ini_time_point {
|
||||
IWL_FW_INI_TIME_POINT_PRESET_OVERRIDE_EXT_REQ,
|
||||
IWL_FW_INI_TIME_POINT_PRESET_OVERRIDE_START,
|
||||
IWL_FW_INI_TIME_SCAN_FAILURE,
|
||||
IWL_FW_INI_TIME_ESR_LINK_UP,
|
||||
IWL_FW_INI_TIME_ESR_LINK_DOWN,
|
||||
IWL_FW_INI_TIME_POINT_NUM,
|
||||
}; /* FW_TLV_DEBUG_TIME_POINT_API_E */
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ enum iwl_mac_conf_subcmd_ids {
|
||||
*/
|
||||
LINK_CONFIG_CMD = 0x9,
|
||||
/**
|
||||
* @STA_CONFIG_CMD: &struct iwl_mvm_sta_cfg_cmd
|
||||
* @STA_CONFIG_CMD: &struct iwl_sta_cfg_cmd
|
||||
*/
|
||||
STA_CONFIG_CMD = 0xA,
|
||||
/**
|
||||
@@ -50,7 +50,7 @@ enum iwl_mac_conf_subcmd_ids {
|
||||
*/
|
||||
AUX_STA_CMD = 0xB,
|
||||
/**
|
||||
* @STA_REMOVE_CMD: &struct iwl_mvm_remove_sta_cmd
|
||||
* @STA_REMOVE_CMD: &struct iwl_remove_sta_cmd
|
||||
*/
|
||||
STA_REMOVE_CMD = 0xC,
|
||||
/**
|
||||
@@ -61,6 +61,14 @@ enum iwl_mac_conf_subcmd_ids {
|
||||
* @ROC_CMD: &struct iwl_roc_req
|
||||
*/
|
||||
ROC_CMD = 0xE,
|
||||
/**
|
||||
* @MISSED_BEACONS_NOTIF: &struct iwl_missed_beacons_notif
|
||||
*/
|
||||
MISSED_BEACONS_NOTIF = 0xF6,
|
||||
/**
|
||||
* @EMLSR_TRANS_FAIL_NOTIF: &struct iwl_esr_trans_fail_notif
|
||||
*/
|
||||
EMLSR_TRANS_FAIL_NOTIF = 0xF7,
|
||||
/**
|
||||
* @ROC_NOTIF: &struct iwl_roc_notif
|
||||
*/
|
||||
@@ -446,6 +454,9 @@ enum iwl_link_ctx_flags {
|
||||
* @listen_lmac: indicates whether the link should be allocated on the Listen
|
||||
* Lmac or on the Main Lmac. Cannot be changed on an active Link.
|
||||
* Relevant only for eSR.
|
||||
* @block_tx: tell the firmware that this link can't Tx. This should be used
|
||||
* only when a link is de-activated because of CSA with mode = 1.
|
||||
* Available since version 5.
|
||||
* @reserved1: in version 2, listen_lmac became reserved
|
||||
* @cck_rates: basic rates available for CCK
|
||||
* @ofdm_rates: basic rates available for OFDM
|
||||
@@ -472,7 +483,9 @@ enum iwl_link_ctx_flags {
|
||||
* @bssid_index: index of the associated VAP
|
||||
* @bss_color: 11ax AP ID that is used in the HE SIG-A to mark inter BSS frame
|
||||
* @spec_link_id: link_id as the AP knows it
|
||||
* @reserved2: alignment
|
||||
* @ul_mu_data_disable: OM Control UL MU Data Disable RX Support (bit 44) in
|
||||
* HE MAC Capabilities information field as defined in figure 9-897 in
|
||||
* IEEE802.11REVme-D5.0
|
||||
* @ibss_bssid_addr: bssid for ibss
|
||||
* @reserved_for_ibss_bssid_addr: reserved
|
||||
* @reserved3: reserved for future use
|
||||
@@ -488,7 +501,10 @@ struct iwl_link_config_cmd {
|
||||
__le32 active;
|
||||
union {
|
||||
__le32 listen_lmac;
|
||||
__le32 reserved1;
|
||||
struct {
|
||||
u8 block_tx;
|
||||
u8 reserved1[3];
|
||||
};
|
||||
};
|
||||
__le32 cck_rates;
|
||||
__le32 ofdm_rates;
|
||||
@@ -515,17 +531,17 @@ struct iwl_link_config_cmd {
|
||||
u8 bssid_index;
|
||||
u8 bss_color;
|
||||
u8 spec_link_id;
|
||||
u8 reserved2;
|
||||
u8 ul_mu_data_disable;
|
||||
u8 ibss_bssid_addr[6];
|
||||
__le16 reserved_for_ibss_bssid_addr;
|
||||
__le32 reserved3[8];
|
||||
} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3 */
|
||||
} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, _VER_5 */
|
||||
|
||||
/* Currently FW supports link ids in the range 0-3 and can have
|
||||
* at most two active links for each vif.
|
||||
*/
|
||||
#define IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM 2
|
||||
#define IWL_MVM_FW_MAX_LINK_ID 3
|
||||
#define IWL_FW_MAX_ACTIVE_LINKS_NUM 2
|
||||
#define IWL_FW_MAX_LINK_ID 3
|
||||
|
||||
/**
|
||||
* enum iwl_fw_sta_type - FW station types
|
||||
@@ -547,7 +563,7 @@ enum iwl_fw_sta_type {
|
||||
}; /* STATION_TYPE_E_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_sta_cfg_cmd - cmd structure to add a peer sta to the uCode's
|
||||
* struct iwl_sta_cfg_cmd - cmd structure to add a peer sta to the uCode's
|
||||
* station table
|
||||
* ( STA_CONFIG_CMD = 0xA )
|
||||
*
|
||||
@@ -579,7 +595,7 @@ enum iwl_fw_sta_type {
|
||||
* capa
|
||||
* @htc_flags: which features are supported in HTC
|
||||
*/
|
||||
struct iwl_mvm_sta_cfg_cmd {
|
||||
struct iwl_sta_cfg_cmd {
|
||||
__le32 sta_id;
|
||||
__le32 link_id;
|
||||
u8 peer_mld_address[ETH_ALEN];
|
||||
@@ -620,13 +636,13 @@ struct iwl_mvm_aux_sta_cmd {
|
||||
} __packed; /* AUX_STA_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_remove_sta_cmd - a cmd structure to remove a sta added by
|
||||
* struct iwl_remove_sta_cmd - a cmd structure to remove a sta added by
|
||||
* STA_CONFIG_CMD or AUX_STA_CONFIG_CMD
|
||||
* ( STA_REMOVE_CMD = 0xC )
|
||||
*
|
||||
* @sta_id: index of station to remove
|
||||
*/
|
||||
struct iwl_mvm_remove_sta_cmd {
|
||||
struct iwl_remove_sta_cmd {
|
||||
__le32 sta_id;
|
||||
} __packed; /* REMOVE_STA_API_S_VER_1 */
|
||||
|
||||
@@ -663,4 +679,51 @@ struct iwl_mvm_esr_mode_notif {
|
||||
__le32 action;
|
||||
} __packed; /* ESR_MODE_RECOMMENDATION_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_missed_beacons_notif - sent when by the firmware upon beacon loss
|
||||
* ( MISSED_BEACONS_NOTIF = 0xF6 )
|
||||
* @link_id: fw link ID
|
||||
* @consec_missed_beacons_since_last_rx: number of consecutive missed
|
||||
* beacons since last RX.
|
||||
* @consec_missed_beacons: number of consecutive missed beacons
|
||||
* @other_link_id: used in EMLSR only. The fw link ID for
|
||||
* &consec_missed_beacons_other_link. IWL_MVM_FW_LINK_ID_INVALID (0xff) if
|
||||
* invalid.
|
||||
* @consec_missed_beacons_other_link: number of consecutive missed beacons on
|
||||
* &other_link_id.
|
||||
*/
|
||||
struct iwl_missed_beacons_notif {
|
||||
__le32 link_id;
|
||||
__le32 consec_missed_beacons_since_last_rx;
|
||||
__le32 consec_missed_beacons;
|
||||
__le32 other_link_id;
|
||||
__le32 consec_missed_beacons_other_link;
|
||||
} __packed; /* MISSED_BEACON_NTFY_API_S_VER_5 */
|
||||
|
||||
/*
|
||||
* enum iwl_esr_trans_fail_code: to be used to parse the notif below
|
||||
*
|
||||
* @ESR_TRANS_FAILED_TX_STATUS_ERROR: failed to TX EML OMN frame
|
||||
* @ESR_TRANSITION_FAILED_TX_TIMEOUT: timeout on the EML OMN frame
|
||||
* @ESR_TRANSITION_FAILED_BEACONS_NOT_HEARD: can't get a beacon on the new link
|
||||
*/
|
||||
enum iwl_esr_trans_fail_code {
|
||||
ESR_TRANS_FAILED_TX_STATUS_ERROR,
|
||||
ESR_TRANSITION_FAILED_TX_TIMEOUT,
|
||||
ESR_TRANSITION_FAILED_BEACONS_NOT_HEARD,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_esr_trans_fail_notif - FW reports a failure in EMLSR transition
|
||||
*
|
||||
* @link_id: the link_id that still works after the failure
|
||||
* @activation: true if the link was activated, false otherwise
|
||||
* @err_code: see &enum iwl_esr_trans_fail_code
|
||||
*/
|
||||
struct iwl_esr_trans_fail_notif {
|
||||
__le32 link_id;
|
||||
__le32 activation;
|
||||
__le32 err_code;
|
||||
} __packed; /* ESR_TRANSITION_FAILED_NTFY_API_S_VER_1 */
|
||||
|
||||
#endif /* __iwl_fw_api_mac_cfg_h__ */
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#define NUM_MAC_INDEX (NUM_MAC_INDEX_DRIVER + 1)
|
||||
#define NUM_MAC_INDEX_CDB (NUM_MAC_INDEX_DRIVER + 2)
|
||||
|
||||
#define IWL_MVM_STATION_COUNT_MAX 16
|
||||
#define IWL_STATION_COUNT_MAX 16
|
||||
#define IWL_MVM_INVALID_STA 0xFF
|
||||
|
||||
enum iwl_ac {
|
||||
@@ -378,7 +378,7 @@ struct iwl_missed_beacons_notif_ver_3 {
|
||||
} __packed; /* MISSED_BEACON_NTFY_API_S_VER_3 */
|
||||
|
||||
/**
|
||||
* struct iwl_missed_beacons_notif - information on missed beacons
|
||||
* struct iwl_missed_beacons_notif_v4 - information on missed beacons
|
||||
* ( MISSED_BEACONS_NOTIFICATION = 0xa2 )
|
||||
* @link_id: fw link ID
|
||||
* @consec_missed_beacons_since_last_rx: number of consecutive missed
|
||||
@@ -387,7 +387,7 @@ struct iwl_missed_beacons_notif_ver_3 {
|
||||
* @num_expected_beacons: number of expected beacons
|
||||
* @num_recvd_beacons: number of received beacons
|
||||
*/
|
||||
struct iwl_missed_beacons_notif {
|
||||
struct iwl_missed_beacons_notif_v4 {
|
||||
__le32 link_id;
|
||||
__le32 consec_missed_beacons_since_last_rx;
|
||||
__le32 consec_missed_beacons;
|
||||
|
||||
@@ -285,18 +285,12 @@ enum iwl_dev_tx_power_cmd_mode {
|
||||
* @set_mode: see &enum iwl_dev_tx_power_cmd_mode
|
||||
* @mac_context_id: id of the mac ctx for which we are reducing TX power.
|
||||
* @pwr_restriction: TX power restriction in 1/8 dBms.
|
||||
* @dev_24: device TX power restriction in 1/8 dBms
|
||||
* @dev_52_low: device TX power restriction upper band - low
|
||||
* @dev_52_high: device TX power restriction upper band - high
|
||||
*/
|
||||
struct iwl_dev_tx_power_common {
|
||||
__le32 set_mode;
|
||||
__le32 mac_context_id;
|
||||
__le16 pwr_restriction;
|
||||
__le16 dev_24;
|
||||
__le16 dev_52_low;
|
||||
__le16 dev_52_high;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_dev_tx_power_cmd_v3 - TX power reduction command version 3
|
||||
@@ -412,8 +406,20 @@ struct iwl_dev_tx_power_cmd_v8 {
|
||||
__le32 tpc_vlp_backoff_level;
|
||||
} __packed; /* TX_REDUCED_POWER_API_S_VER_8 */
|
||||
|
||||
/*
|
||||
* @dev_24: device TX power restriction in 1/8 dBms
|
||||
* @dev_52_low: device TX power restriction upper band - low
|
||||
* @dev_52_high: device TX power restriction upper band - high
|
||||
*/
|
||||
struct iwl_dev_tx_power_cmd_per_band {
|
||||
__le16 dev_24;
|
||||
__le16 dev_52_low;
|
||||
__le16 dev_52_high;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_dev_tx_power_cmd - TX power reduction command (multiversion)
|
||||
* struct iwl_dev_tx_power_cmd_v3_v8 - TX power reduction command (multiversion)
|
||||
* @per_band: per band restrictions
|
||||
* @common: common part of the command
|
||||
* @v3: version 3 part of the command
|
||||
* @v4: version 4 part of the command
|
||||
@@ -422,8 +428,9 @@ struct iwl_dev_tx_power_cmd_v8 {
|
||||
* @v7: version 7 part of the command
|
||||
* @v8: version 8 part of the command
|
||||
*/
|
||||
struct iwl_dev_tx_power_cmd {
|
||||
struct iwl_dev_tx_power_cmd_v3_v8 {
|
||||
struct iwl_dev_tx_power_common common;
|
||||
struct iwl_dev_tx_power_cmd_per_band per_band;
|
||||
union {
|
||||
struct iwl_dev_tx_power_cmd_v3 v3;
|
||||
struct iwl_dev_tx_power_cmd_v4 v4;
|
||||
@@ -434,6 +441,60 @@ struct iwl_dev_tx_power_cmd {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_dev_tx_power_cmd_v9 - TX power reduction cmd
|
||||
* @reserved: reserved (padding)
|
||||
* @per_chain: per chain restrictions
|
||||
* @per_chain_restriction_changed: is per_chain_restriction has changed
|
||||
* from last command. used if set_mode is
|
||||
* IWL_TX_POWER_MODE_SET_SAR_TIMER.
|
||||
* note: if not changed, the command is used for keep alive only.
|
||||
* @reserved1: reserved (padding)
|
||||
* @timer_period: timer in milliseconds. if expires FW will change to default
|
||||
* BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER
|
||||
*/
|
||||
struct iwl_dev_tx_power_cmd_v9 {
|
||||
__le16 reserved;
|
||||
__le16 per_chain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V1];
|
||||
u8 per_chain_restriction_changed;
|
||||
u8 reserved1[3];
|
||||
__le32 timer_period;
|
||||
} __packed; /* TX_REDUCED_POWER_API_S_VER_9 */
|
||||
|
||||
/**
|
||||
* struct iwl_dev_tx_power_cmd_v10 - TX power reduction cmd
|
||||
* @per_chain: per chain restrictions
|
||||
* @per_chain_restriction_changed: is per_chain_restriction has changed
|
||||
* from last command. used if set_mode is
|
||||
* IWL_TX_POWER_MODE_SET_SAR_TIMER.
|
||||
* note: if not changed, the command is used for keep alive only.
|
||||
* @reserved: reserved (padding)
|
||||
* @timer_period: timer in milliseconds. if expires FW will change to default
|
||||
* BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER
|
||||
* @flags: reduce power flags.
|
||||
*/
|
||||
struct iwl_dev_tx_power_cmd_v10 {
|
||||
__le16 per_chain[IWL_NUM_CHAIN_TABLES_V2][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2];
|
||||
u8 per_chain_restriction_changed;
|
||||
u8 reserved;
|
||||
__le32 timer_period;
|
||||
__le32 flags;
|
||||
} __packed; /* TX_REDUCED_POWER_API_S_VER_10 */
|
||||
|
||||
/*
|
||||
* struct iwl_dev_tx_power_cmd - TX power reduction command (multiversion)
|
||||
* @common: common part of the command
|
||||
* @v9: version 9 part of the command
|
||||
* @v10: version 10 part of the command
|
||||
*/
|
||||
struct iwl_dev_tx_power_cmd {
|
||||
struct iwl_dev_tx_power_common common;
|
||||
union {
|
||||
struct iwl_dev_tx_power_cmd_v9 v9;
|
||||
struct iwl_dev_tx_power_cmd_v10 v10;
|
||||
};
|
||||
} __packed; /* TX_REDUCED_POWER_API_S_VER_9_VER10 */
|
||||
|
||||
#define IWL_NUM_GEO_PROFILES 3
|
||||
#define IWL_NUM_GEO_PROFILES_V3 8
|
||||
#define IWL_NUM_BANDS_PER_CHAIN_V1 2
|
||||
|
||||
@@ -731,39 +731,46 @@ enum iwl_umac_scan_general_params_flags2 {
|
||||
* struct iwl_scan_channel_cfg_umac
|
||||
* @flags: bitmap - 0-19: directed scan to i'th ssid.
|
||||
* @channel_num: channel number 1-13 etc.
|
||||
* @band: band of channel: 0 for 2GHz, 1 for 5GHz
|
||||
* @iter_count: repetition count for the channel.
|
||||
* @iter_interval: interval between two scan iterations on one channel.
|
||||
* @v1: command version 1
|
||||
* @v1.iter_count: repetition count for the channel.
|
||||
* @v1.iter_interval: interval between two scan iterations on one channel.
|
||||
* @v2: command versions 2-4
|
||||
* @v2.band: band of channel: 0 for 2GHz, 1 for 5GHz
|
||||
* @v2.iter_count: repetition count for the channel.
|
||||
* @v2.iter_interval: interval between two scan iterations on one channel.
|
||||
* @v5: command versions 5 and up
|
||||
* @v5.iter_count: repetition count for the channel.
|
||||
* @v5.iter_interval: interval between two scan iterations on one channel.
|
||||
* @v5.psd_20: highest PSD value for all APs known so far
|
||||
* on this channel.
|
||||
*/
|
||||
struct iwl_scan_channel_cfg_umac {
|
||||
#define IWL_CHAN_CFG_FLAGS_BAND_POS 30
|
||||
__le32 flags;
|
||||
u8 channel_num;
|
||||
|
||||
/* All versions are of the same size, so use a union without adjusting
|
||||
* the command size later
|
||||
*/
|
||||
union {
|
||||
struct {
|
||||
u8 channel_num;
|
||||
u8 iter_count;
|
||||
__le16 iter_interval;
|
||||
} v1; /* SCAN_CHANNEL_CONFIG_API_S_VER_1 */
|
||||
} __packed v1; /* SCAN_CHANNEL_CONFIG_API_S_VER_1 */
|
||||
struct {
|
||||
u8 channel_num;
|
||||
u8 band;
|
||||
u8 iter_count;
|
||||
u8 iter_interval;
|
||||
} v2; /* SCAN_CHANNEL_CONFIG_API_S_VER_2
|
||||
* SCAN_CHANNEL_CONFIG_API_S_VER_3
|
||||
* SCAN_CHANNEL_CONFIG_API_S_VER_4
|
||||
*/
|
||||
} __packed v2; /* SCAN_CHANNEL_CONFIG_API_S_VER_2
|
||||
* SCAN_CHANNEL_CONFIG_API_S_VER_3
|
||||
* SCAN_CHANNEL_CONFIG_API_S_VER_4
|
||||
*/
|
||||
struct {
|
||||
u8 channel_num;
|
||||
u8 psd_20;
|
||||
u8 iter_count;
|
||||
u8 iter_interval;
|
||||
} v5; /* SCAN_CHANNEL_CONFIG_API_S_VER_5 */
|
||||
};
|
||||
} __packed v5; /* SCAN_CHANNEL_CONFIG_API_S_VER_5 */
|
||||
} __packed;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
@@ -1132,6 +1139,19 @@ struct iwl_umac_scan_abort {
|
||||
__le32 flags;
|
||||
} __packed; /* SCAN_ABORT_CMD_UMAC_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_umac_scan_abort_status
|
||||
*
|
||||
* @IWL_UMAC_SCAN_ABORT_STATUS_SUCCESS: scan was successfully aborted
|
||||
* @IWL_UMAC_SCAN_ABORT_STATUS_IN_PROGRESS: scan abort is in progress
|
||||
* @IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND: nothing to abort
|
||||
*/
|
||||
enum iwl_umac_scan_abort_status {
|
||||
IWL_UMAC_SCAN_ABORT_STATUS_SUCCESS = 0,
|
||||
IWL_UMAC_SCAN_ABORT_STATUS_IN_PROGRESS,
|
||||
IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_umac_scan_complete
|
||||
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018, 2020 - 2021, 2023 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018, 2020 - 2021, 2023 - 2024 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
@@ -327,14 +327,14 @@ struct mvm_statistics_load {
|
||||
__le32 air_time[MAC_INDEX_AUX];
|
||||
__le32 byte_count[MAC_INDEX_AUX];
|
||||
__le32 pkt_count[MAC_INDEX_AUX];
|
||||
u8 avg_energy[IWL_MVM_STATION_COUNT_MAX];
|
||||
u8 avg_energy[IWL_STATION_COUNT_MAX];
|
||||
} __packed; /* STATISTICS_RX_MAC_STATION_S_VER_3 */
|
||||
|
||||
struct mvm_statistics_load_v1 {
|
||||
__le32 air_time[NUM_MAC_INDEX];
|
||||
__le32 byte_count[NUM_MAC_INDEX];
|
||||
__le32 pkt_count[NUM_MAC_INDEX];
|
||||
u8 avg_energy[IWL_MVM_STATION_COUNT_MAX];
|
||||
u8 avg_energy[IWL_STATION_COUNT_MAX];
|
||||
} __packed; /* STATISTICS_RX_MAC_STATION_S_VER_1 */
|
||||
|
||||
struct mvm_statistics_rx {
|
||||
@@ -594,7 +594,7 @@ struct iwl_stats_ntfy_per_sta {
|
||||
} __packed; /* STATISTICS_NTFY_PER_STA_API_S_VER_1 */
|
||||
|
||||
#define IWL_STATS_MAX_PHY_OPERATIONAL 3
|
||||
#define IWL_STATS_MAX_FW_LINKS (IWL_MVM_FW_MAX_LINK_ID + 1)
|
||||
#define IWL_STATS_MAX_FW_LINKS (IWL_FW_MAX_LINK_ID + 1)
|
||||
|
||||
/**
|
||||
* struct iwl_system_statistics_notif_oper
|
||||
@@ -608,7 +608,7 @@ struct iwl_system_statistics_notif_oper {
|
||||
__le32 time_stamp;
|
||||
struct iwl_stats_ntfy_per_link per_link[IWL_STATS_MAX_FW_LINKS];
|
||||
struct iwl_stats_ntfy_per_phy per_phy[IWL_STATS_MAX_PHY_OPERATIONAL];
|
||||
struct iwl_stats_ntfy_per_sta per_sta[IWL_MVM_STATION_COUNT_MAX];
|
||||
struct iwl_stats_ntfy_per_sta per_sta[IWL_STATION_COUNT_MAX];
|
||||
} __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_API_S_VER_3 */
|
||||
|
||||
/**
|
||||
@@ -651,7 +651,7 @@ struct iwl_statistics_operational_ntfy {
|
||||
__le32 flags;
|
||||
struct iwl_stats_ntfy_per_mac per_mac[MAC_INDEX_AUX];
|
||||
struct iwl_stats_ntfy_per_phy per_phy[IWL_STATS_MAX_PHY_OPERATIONAL];
|
||||
struct iwl_stats_ntfy_per_sta per_sta[IWL_MVM_STATION_COUNT_MAX];
|
||||
struct iwl_stats_ntfy_per_sta per_sta[IWL_STATION_COUNT_MAX];
|
||||
__le64 rx_time;
|
||||
__le64 tx_time;
|
||||
__le64 on_time_rf;
|
||||
@@ -699,7 +699,7 @@ struct iwl_statistics_operational_ntfy_ver_14 {
|
||||
__le64 tx_time;
|
||||
__le64 on_time_rf;
|
||||
__le64 on_time_scan;
|
||||
__le32 average_energy[IWL_MVM_STATION_COUNT_MAX];
|
||||
__le32 average_energy[IWL_STATION_COUNT_MAX];
|
||||
__le32 reserved;
|
||||
} __packed; /* STATISTICS_OPERATIONAL_NTFY_API_S_VER_14 */
|
||||
|
||||
|
||||
@@ -486,7 +486,7 @@ struct agg_tx_status {
|
||||
#define IWL_MVM_TX_RES_GET_RA(_ra_tid) ((_ra_tid) >> 4)
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_tx_resp_v3 - notifies that fw is TXing a packet
|
||||
* struct iwl_tx_resp_v3 - notifies that fw is TXing a packet
|
||||
* ( REPLY_TX = 0x1c )
|
||||
* @frame_count: 1 no aggregation, >1 aggregation
|
||||
* @bt_kill_count: num of times blocked by bluetooth (unused for agg)
|
||||
@@ -517,7 +517,7 @@ struct agg_tx_status {
|
||||
* After the array of statuses comes the SSN of the SCD. Look at
|
||||
* %iwl_mvm_get_scd_ssn for more details.
|
||||
*/
|
||||
struct iwl_mvm_tx_resp_v3 {
|
||||
struct iwl_tx_resp_v3 {
|
||||
u8 frame_count;
|
||||
u8 bt_kill_count;
|
||||
u8 failure_rts;
|
||||
@@ -543,7 +543,7 @@ struct iwl_mvm_tx_resp_v3 {
|
||||
} __packed; /* TX_RSP_API_S_VER_3 */
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_tx_resp - notifies that fw is TXing a packet
|
||||
* struct iwl_tx_resp - notifies that fw is TXing a packet
|
||||
* ( REPLY_TX = 0x1c )
|
||||
* @frame_count: 1 no aggregation, >1 aggregation
|
||||
* @bt_kill_count: num of times blocked by bluetooth (unused for agg)
|
||||
@@ -575,7 +575,7 @@ struct iwl_mvm_tx_resp_v3 {
|
||||
* After the array of statuses comes the SSN of the SCD. Look at
|
||||
* %iwl_mvm_get_scd_ssn for more details.
|
||||
*/
|
||||
struct iwl_mvm_tx_resp {
|
||||
struct iwl_tx_resp {
|
||||
u8 frame_count;
|
||||
u8 bt_kill_count;
|
||||
u8 failure_rts;
|
||||
@@ -823,7 +823,7 @@ struct iwl_mac_beacon_cmd {
|
||||
*/
|
||||
|
||||
struct iwl_beacon_notif {
|
||||
struct iwl_mvm_tx_resp beacon_notify_hdr;
|
||||
struct iwl_tx_resp beacon_notify_hdr;
|
||||
__le64 tsf;
|
||||
__le32 ibss_mgr_status;
|
||||
} __packed;
|
||||
@@ -836,7 +836,7 @@ struct iwl_beacon_notif {
|
||||
* @gp2: last beacon time in gp2
|
||||
*/
|
||||
struct iwl_extended_beacon_notif_v5 {
|
||||
struct iwl_mvm_tx_resp beacon_notify_hdr;
|
||||
struct iwl_tx_resp beacon_notify_hdr;
|
||||
__le64 tsf;
|
||||
__le32 ibss_mgr_status;
|
||||
__le32 gp2;
|
||||
|
||||
@@ -634,3 +634,19 @@ int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
|
||||
GET_BIOS_TABLE(dsm, fwrt, func, value);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_bios_get_dsm);
|
||||
|
||||
bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc)
|
||||
{
|
||||
/* Some kind of regulatory mess means we need to currently disallow
|
||||
* puncturing in the US and Canada unless enabled in BIOS.
|
||||
*/
|
||||
switch (mcc) {
|
||||
case IWL_MCC_US:
|
||||
return puncturing & IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK;
|
||||
case IWL_MCC_CANADA:
|
||||
return puncturing & IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_puncturing_is_allowed_in_bios);
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#define IWL_WTAS_ENABLE_IEC_MSK 0x4
|
||||
#define IWL_WTAS_USA_UHB_MSK BIT(16)
|
||||
|
||||
#define BIOS_MCC_CHINA 0x434e
|
||||
|
||||
/*
|
||||
* The profile for revision 2 is a superset of revision 1, which is in
|
||||
* turn a superset of revision 0. So we can store all revisions
|
||||
@@ -217,4 +219,6 @@ static inline u32 iwl_bios_get_ppag_flags(const u32 ppag_modes,
|
||||
return ppag_modes & (ppag_ver < 3 ? IWL_PPAG_ETSI_CHINA_MASK :
|
||||
IWL_PPAG_REV3_MASK);
|
||||
}
|
||||
|
||||
bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc);
|
||||
#endif /* __fw_regulatory_h__ */
|
||||
|
||||
@@ -638,7 +638,7 @@ int iwl_uefi_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (data->mcc != UEFI_MCC_CHINA) {
|
||||
if (data->mcc != BIOS_MCC_CHINA) {
|
||||
ret = -EINVAL;
|
||||
IWL_DEBUG_RADIO(fwrt, "UEFI WRDD is supported only for CN\n");
|
||||
goto out;
|
||||
@@ -729,3 +729,32 @@ out:
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
struct uefi_cnv_var_puncturing_data *data;
|
||||
/* default value is not enabled if there is any issue in reading
|
||||
* uefi variable or revision is not supported
|
||||
*/
|
||||
int puncturing = 0;
|
||||
|
||||
data = iwl_uefi_get_verified_variable(fwrt->trans,
|
||||
IWL_UEFI_PUNCTURING_NAME,
|
||||
"UefiCnvWlanPuncturing",
|
||||
sizeof(*data), NULL);
|
||||
if (IS_ERR(data))
|
||||
return puncturing;
|
||||
|
||||
if (data->revision != IWL_UEFI_PUNCTURING_REVISION) {
|
||||
IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI PUNCTURING rev:%d\n",
|
||||
data->revision);
|
||||
} else {
|
||||
puncturing = data->puncturing & IWL_UEFI_PUNCTURING_REV0_MASK;
|
||||
IWL_DEBUG_RADIO(fwrt, "Loaded puncturing bits from UEFI: %d\n",
|
||||
puncturing);
|
||||
}
|
||||
|
||||
kfree(data);
|
||||
return puncturing;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_uefi_get_puncturing);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define IWL_UEFI_ECKV_NAME L"UefiCnvWlanECKV"
|
||||
#define IWL_UEFI_DSM_NAME L"UefiCnvWlanGeneralCfg"
|
||||
#define IWL_UEFI_WBEM_NAME L"UefiCnvWlanWBEM"
|
||||
#define IWL_UEFI_PUNCTURING_NAME L"UefiCnvWlanPuncturing"
|
||||
|
||||
|
||||
#define IWL_SGOM_MAP_SIZE 339
|
||||
@@ -38,6 +39,7 @@
|
||||
#define IWL_UEFI_ECKV_REVISION 0
|
||||
#define IWL_UEFI_WBEM_REVISION 0
|
||||
#define IWL_UEFI_DSM_REVISION 4
|
||||
#define IWL_UEFI_PUNCTURING_REVISION 0
|
||||
|
||||
struct pnvm_sku_package {
|
||||
u8 rev;
|
||||
@@ -149,8 +151,6 @@ struct uefi_cnv_var_splc {
|
||||
u32 default_pwr_limit;
|
||||
} __packed;
|
||||
|
||||
#define UEFI_MCC_CHINA 0x434e
|
||||
|
||||
/* struct uefi_cnv_var_wrdd - WRDD table as defined in UEFI
|
||||
* @revision: the revision of the table
|
||||
* @mcc: country identifier as defined in ISO/IEC 3166-1 Alpha 2 code
|
||||
@@ -194,6 +194,25 @@ struct uefi_cnv_wlan_wbem_data {
|
||||
u32 wbem_320mhz_per_mcc;
|
||||
} __packed;
|
||||
|
||||
enum iwl_uefi_cnv_puncturing_flags {
|
||||
IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK = BIT(0),
|
||||
IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK = BIT(1),
|
||||
};
|
||||
|
||||
#define IWL_UEFI_PUNCTURING_REV0_MASK (IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK | \
|
||||
IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK)
|
||||
/**
|
||||
* struct uefi_cnv_var_puncturing_data - controlling channel
|
||||
* puncturing for few countries.
|
||||
* @revision: the revision of the table
|
||||
* @puncturing: enablement of channel puncturing per mcc
|
||||
* see &enum iwl_uefi_cnv_puncturing_flags.
|
||||
*/
|
||||
struct uefi_cnv_var_puncturing_data {
|
||||
u8 revision;
|
||||
u32 puncturing;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* This is known to be broken on v4.19 and to work on v5.4. Until we
|
||||
* figure out why this is the case and how to make it work, simply
|
||||
@@ -224,6 +243,7 @@ int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
|
||||
void iwl_uefi_get_sgom_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt);
|
||||
int iwl_uefi_get_uats_table(struct iwl_trans *trans,
|
||||
struct iwl_fw_runtime *fwrt);
|
||||
int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt);
|
||||
#else /* CONFIG_EFI */
|
||||
static inline void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)
|
||||
{
|
||||
@@ -320,5 +340,11 @@ int iwl_uefi_get_uats_table(struct iwl_trans *trans,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_EFI */
|
||||
#endif /* __iwl_fw_uefi__ */
|
||||
|
||||
@@ -504,6 +504,7 @@ extern const struct iwl_cfg_trans_params iwl_so_long_latency_trans_cfg;
|
||||
extern const struct iwl_cfg_trans_params iwl_so_long_latency_imr_trans_cfg;
|
||||
extern const struct iwl_cfg_trans_params iwl_ma_trans_cfg;
|
||||
extern const struct iwl_cfg_trans_params iwl_bz_trans_cfg;
|
||||
extern const struct iwl_cfg_trans_params iwl_gl_trans_cfg;
|
||||
extern const struct iwl_cfg_trans_params iwl_sc_trans_cfg;
|
||||
extern const char iwl9162_name[];
|
||||
extern const char iwl9260_name[];
|
||||
|
||||
@@ -1205,7 +1205,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
if (le32_to_cpup((const __le32 *)tlv_data) >
|
||||
IWL_MVM_STATION_COUNT_MAX) {
|
||||
IWL_STATION_COUNT_MAX) {
|
||||
IWL_ERR(drv,
|
||||
"%d is an invalid number of station\n",
|
||||
le32_to_cpup((const __le32 *)tlv_data));
|
||||
@@ -1479,7 +1479,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||
fw->ucode_capa.standard_phy_calibration_size =
|
||||
IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
|
||||
fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS;
|
||||
fw->ucode_capa.num_stations = IWL_MVM_STATION_COUNT_MAX;
|
||||
fw->ucode_capa.num_stations = IWL_STATION_COUNT_MAX;
|
||||
fw->ucode_capa.num_beacons = 1;
|
||||
/* dump all fw memory areas by default */
|
||||
fw->dbg.dump_mask = 0xffffffff;
|
||||
|
||||
@@ -386,7 +386,6 @@ struct iwl_dump_sanitize_ops {
|
||||
* @cmd_queue: the index of the command queue.
|
||||
* Must be set before start_fw.
|
||||
* @cmd_fifo: the fifo for host commands
|
||||
* @cmd_q_wdg_timeout: the timeout of the watchdog timer for the command queue.
|
||||
* @no_reclaim_cmds: Some devices erroneously don't set the
|
||||
* SEQ_RX_FRAME bit on some notifications, this is the
|
||||
* list of such notifications to filter. Max length is
|
||||
@@ -412,7 +411,6 @@ struct iwl_trans_config {
|
||||
|
||||
u8 cmd_queue;
|
||||
u8 cmd_fifo;
|
||||
unsigned int cmd_q_wdg_timeout;
|
||||
const u8 *no_reclaim_cmds;
|
||||
unsigned int n_no_reclaim_cmds;
|
||||
|
||||
|
||||
@@ -283,6 +283,16 @@ struct iwl_mei_colloc_info {
|
||||
u8 bssid[ETH_ALEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_mei_sap_version - SAP version
|
||||
* @IWL_MEI_SAP_VERSION_3: SAP version 3
|
||||
* @IWL_MEI_SAP_VERSION_4: SAP version 4
|
||||
*/
|
||||
enum iwl_mei_sap_version {
|
||||
IWL_MEI_SAP_VERSION_3 = 3,
|
||||
IWL_MEI_SAP_VERSION_4 = 4,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct iwl_mei_ops - driver's operations called by iwlmei
|
||||
* Operations will not be called more than once concurrently.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2023 Intel Corporation
|
||||
* Copyright (C) 2021-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
@@ -58,7 +58,6 @@ bool iwl_mei_is_connected(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iwl_mei_is_connected);
|
||||
|
||||
#define SAP_VERSION 3
|
||||
#define SAP_CONTROL_BLOCK_ID 0x21504153 /* SAP! in ASCII */
|
||||
|
||||
struct iwl_sap_q_ctrl_blk {
|
||||
@@ -110,16 +109,19 @@ struct iwl_sap_shared_mem_ctrl_blk {
|
||||
|
||||
#define SAP_H2M_DATA_Q_SZ 48256
|
||||
#define SAP_M2H_DATA_Q_SZ 24128
|
||||
#define SAP_H2M_NOTIF_Q_SZ 2240
|
||||
#define SAP_H2M_NOTIF_Q_SZ_VER3 2240
|
||||
#define SAP_H2M_NOTIF_Q_SZ_VER4 32768
|
||||
#define SAP_M2H_NOTIF_Q_SZ 62720
|
||||
|
||||
#define _IWL_MEI_SAP_SHARED_MEM_SZ \
|
||||
#define _IWL_MEI_SAP_SHARED_MEM_SZ_VER3 \
|
||||
(sizeof(struct iwl_sap_shared_mem_ctrl_blk) + \
|
||||
SAP_H2M_DATA_Q_SZ + SAP_H2M_NOTIF_Q_SZ + \
|
||||
SAP_H2M_DATA_Q_SZ + SAP_H2M_NOTIF_Q_SZ_VER3 + \
|
||||
SAP_M2H_DATA_Q_SZ + SAP_M2H_NOTIF_Q_SZ + 4)
|
||||
|
||||
#define IWL_MEI_SAP_SHARED_MEM_SZ \
|
||||
(roundup(_IWL_MEI_SAP_SHARED_MEM_SZ, PAGE_SIZE))
|
||||
#define _IWL_MEI_SAP_SHARED_MEM_SZ_VER4 \
|
||||
(sizeof(struct iwl_sap_shared_mem_ctrl_blk) + \
|
||||
SAP_H2M_DATA_Q_SZ + SAP_H2M_NOTIF_Q_SZ_VER4 + \
|
||||
SAP_M2H_DATA_Q_SZ + SAP_M2H_NOTIF_Q_SZ + 4)
|
||||
|
||||
struct iwl_mei_shared_mem_ptrs {
|
||||
struct iwl_sap_shared_mem_ctrl_blk *ctrl;
|
||||
@@ -206,6 +208,7 @@ struct iwl_mei {
|
||||
* @mac_address: interface MAC address.
|
||||
* @nvm_address: NVM MAC address.
|
||||
* @priv: A pointer to iwlwifi.
|
||||
* @sap_version: The SAP version to use. enum iwl_mei_sap_version.
|
||||
*
|
||||
* This used to cache the configurations coming from iwlwifi's way. The data
|
||||
* is cached here so that we can buffer the configuration even if we don't have
|
||||
@@ -220,6 +223,7 @@ struct iwl_mei_cache {
|
||||
u16 mcc;
|
||||
u8 mac_address[6];
|
||||
u8 nvm_address[6];
|
||||
enum iwl_mei_sap_version sap_version;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
@@ -238,14 +242,17 @@ static void iwl_mei_free_shared_mem(struct mei_cl_device *cldev)
|
||||
|
||||
#define HBM_DMA_BUF_ID_WLAN 1
|
||||
|
||||
static int iwl_mei_alloc_shared_mem(struct mei_cl_device *cldev)
|
||||
static int iwl_mei_alloc_mem_for_version(struct mei_cl_device *cldev,
|
||||
enum iwl_mei_sap_version version)
|
||||
{
|
||||
struct iwl_mei *mei = mei_cldev_get_drvdata(cldev);
|
||||
struct iwl_mei_shared_mem_ptrs *mem = &mei->shared_mem;
|
||||
u32 mem_size = roundup(version == IWL_MEI_SAP_VERSION_4 ?
|
||||
_IWL_MEI_SAP_SHARED_MEM_SZ_VER4 :
|
||||
_IWL_MEI_SAP_SHARED_MEM_SZ_VER3, PAGE_SIZE);
|
||||
|
||||
mem->ctrl = mei_cldev_dma_map(cldev, HBM_DMA_BUF_ID_WLAN,
|
||||
IWL_MEI_SAP_SHARED_MEM_SZ);
|
||||
|
||||
iwl_mei_cache.sap_version = version;
|
||||
mem->ctrl = mei_cldev_dma_map(cldev, HBM_DMA_BUF_ID_WLAN, mem_size);
|
||||
if (IS_ERR(mem->ctrl)) {
|
||||
int ret = PTR_ERR(mem->ctrl);
|
||||
|
||||
@@ -254,11 +261,30 @@ static int iwl_mei_alloc_shared_mem(struct mei_cl_device *cldev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(mem->ctrl, 0, IWL_MEI_SAP_SHARED_MEM_SZ);
|
||||
memset(mem->ctrl, 0, mem_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_mei_alloc_shared_mem(struct mei_cl_device *cldev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* SAP version 4 uses a larger Host to MEI notif queue.
|
||||
* Since it is unknown at this stage which SAP version is used by the
|
||||
* CSME firmware on this platform, try to allocate the version 4 first.
|
||||
* If the CSME firmware uses version 3, this allocation is expected to
|
||||
* fail because the CSME firmware allocated less memory for our driver.
|
||||
*/
|
||||
ret = iwl_mei_alloc_mem_for_version(cldev, IWL_MEI_SAP_VERSION_4);
|
||||
if (ret)
|
||||
ret = iwl_mei_alloc_mem_for_version(cldev,
|
||||
IWL_MEI_SAP_VERSION_3);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_mei_init_shared_mem(struct iwl_mei *mei)
|
||||
{
|
||||
struct iwl_mei_shared_mem_ptrs *mem = &mei->shared_mem;
|
||||
@@ -277,7 +303,9 @@ static void iwl_mei_init_shared_mem(struct iwl_mei *mei)
|
||||
h2m->q_ctrl_blk[SAP_QUEUE_IDX_DATA].size =
|
||||
cpu_to_le32(SAP_H2M_DATA_Q_SZ);
|
||||
h2m->q_ctrl_blk[SAP_QUEUE_IDX_NOTIF].size =
|
||||
cpu_to_le32(SAP_H2M_NOTIF_Q_SZ);
|
||||
iwl_mei_cache.sap_version == IWL_MEI_SAP_VERSION_3 ?
|
||||
cpu_to_le32(SAP_H2M_NOTIF_Q_SZ_VER3) :
|
||||
cpu_to_le32(SAP_H2M_NOTIF_Q_SZ_VER4);
|
||||
m2h->q_ctrl_blk[SAP_QUEUE_IDX_DATA].size =
|
||||
cpu_to_le32(SAP_M2H_DATA_Q_SZ);
|
||||
m2h->q_ctrl_blk[SAP_QUEUE_IDX_NOTIF].size =
|
||||
@@ -647,7 +675,7 @@ iwl_mei_handle_rx_start_ok(struct mei_cl_device *cldev,
|
||||
return;
|
||||
}
|
||||
|
||||
if (rsp->supported_version != SAP_VERSION) {
|
||||
if (rsp->supported_version != iwl_mei_cache.sap_version) {
|
||||
dev_err(&cldev->dev,
|
||||
"didn't get the expected version: got %d\n",
|
||||
rsp->supported_version);
|
||||
@@ -1281,7 +1309,7 @@ static int iwl_mei_send_start(struct mei_cl_device *cldev)
|
||||
.hdr.type = cpu_to_le32(SAP_ME_MSG_START),
|
||||
.hdr.seq_num = cpu_to_le32(atomic_inc_return(&mei->seq_no)),
|
||||
.hdr.len = cpu_to_le32(sizeof(msg)),
|
||||
.supported_versions[0] = SAP_VERSION,
|
||||
.supported_versions[0] = iwl_mei_cache.sap_version,
|
||||
.init_data_seq_num = cpu_to_le16(0x100),
|
||||
.init_notif_seq_num = cpu_to_le16(0x800),
|
||||
};
|
||||
|
||||
@@ -208,7 +208,7 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
|
||||
}
|
||||
|
||||
struct iwl_bt_iterator_data {
|
||||
struct iwl_bt_coex_profile_notif *notif;
|
||||
struct iwl_bt_coex_prof_old_notif *notif;
|
||||
struct iwl_mvm *mvm;
|
||||
struct ieee80211_chanctx_conf *primary;
|
||||
struct ieee80211_chanctx_conf *secondary;
|
||||
@@ -266,10 +266,26 @@ iwl_mvm_bt_coex_calculate_esr_mode(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
bool have_wifi_loss_rate =
|
||||
iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
|
||||
BT_PROFILE_NOTIFICATION, 0) > 4;
|
||||
BT_PROFILE_NOTIFICATION, 0) > 4 ||
|
||||
iwl_fw_lookup_notif_ver(mvm->fw, BT_COEX_GROUP,
|
||||
PROFILE_NOTIF, 0) >= 1;
|
||||
u8 wifi_loss_mid_high_rssi;
|
||||
u8 wifi_loss_low_rssi;
|
||||
u8 wifi_loss_rate;
|
||||
|
||||
if (mvm->last_bt_notif.wifi_loss_low_rssi == BT_OFF)
|
||||
if (iwl_fw_lookup_notif_ver(mvm->fw, BT_COEX_GROUP,
|
||||
PROFILE_NOTIF, 0) >= 1) {
|
||||
/* For now, we consider 2.4 GHz band / ANT_A only */
|
||||
wifi_loss_mid_high_rssi =
|
||||
mvm->last_bt_wifi_loss.wifi_loss_mid_high_rssi[PHY_BAND_24][0];
|
||||
wifi_loss_low_rssi =
|
||||
mvm->last_bt_wifi_loss.wifi_loss_low_rssi[PHY_BAND_24][0];
|
||||
} else {
|
||||
wifi_loss_mid_high_rssi = mvm->last_bt_notif.wifi_loss_mid_high_rssi;
|
||||
wifi_loss_low_rssi = mvm->last_bt_notif.wifi_loss_low_rssi;
|
||||
}
|
||||
|
||||
if (wifi_loss_low_rssi == BT_OFF)
|
||||
return true;
|
||||
|
||||
if (primary)
|
||||
@@ -286,20 +302,20 @@ iwl_mvm_bt_coex_calculate_esr_mode(struct iwl_mvm *mvm,
|
||||
* we will get an update on this and exit eSR.
|
||||
*/
|
||||
if (!link_rssi)
|
||||
wifi_loss_rate = mvm->last_bt_notif.wifi_loss_mid_high_rssi;
|
||||
wifi_loss_rate = wifi_loss_mid_high_rssi;
|
||||
|
||||
else if (mvmvif->esr_active)
|
||||
/* RSSI needs to get really low to disable eSR... */
|
||||
wifi_loss_rate =
|
||||
link_rssi <= -IWL_MVM_BT_COEX_DISABLE_ESR_THRESH ?
|
||||
mvm->last_bt_notif.wifi_loss_low_rssi :
|
||||
mvm->last_bt_notif.wifi_loss_mid_high_rssi;
|
||||
wifi_loss_low_rssi :
|
||||
wifi_loss_mid_high_rssi;
|
||||
else
|
||||
/* ...And really high before we enable it back */
|
||||
wifi_loss_rate =
|
||||
link_rssi <= -IWL_MVM_BT_COEX_ENABLE_ESR_THRESH ?
|
||||
mvm->last_bt_notif.wifi_loss_low_rssi :
|
||||
mvm->last_bt_notif.wifi_loss_mid_high_rssi;
|
||||
wifi_loss_low_rssi :
|
||||
wifi_loss_mid_high_rssi;
|
||||
|
||||
return wifi_loss_rate <= IWL_MVM_BT_COEX_WIFI_LOSS_THRESH;
|
||||
}
|
||||
@@ -509,6 +525,35 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
|
||||
iwl_mvm_bt_notif_per_link(mvm, vif, data, link_id);
|
||||
}
|
||||
|
||||
/* must be called under rcu_read_lock */
|
||||
static void iwl_mvm_bt_coex_notif_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm *mvm = _data;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_STATION)
|
||||
return;
|
||||
|
||||
for (int link_id = 0;
|
||||
link_id < IEEE80211_MLD_MAX_NUM_LINKS;
|
||||
link_id++) {
|
||||
struct ieee80211_bss_conf *link_conf =
|
||||
rcu_dereference_check(vif->link_conf[link_id],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
struct ieee80211_chanctx_conf *chanctx_conf =
|
||||
rcu_dereference_check(link_conf->chanctx_conf,
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
|
||||
if ((!chanctx_conf ||
|
||||
chanctx_conf->def.chan->band != NL80211_BAND_2GHZ))
|
||||
continue;
|
||||
|
||||
iwl_mvm_bt_coex_update_link_esr(mvm, vif, link_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_bt_iterator_data data = {
|
||||
@@ -591,11 +636,11 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
|
||||
}
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
void iwl_mvm_rx_bt_coex_old_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
|
||||
struct iwl_bt_coex_prof_old_notif *notif = (void *)pkt->data;
|
||||
|
||||
IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
|
||||
IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
|
||||
@@ -612,6 +657,22 @@ void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
|
||||
iwl_mvm_bt_coex_notif_handle(mvm);
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
const struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
const struct iwl_bt_coex_profile_notif *notif = (const void *)pkt->data;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
mvm->last_bt_wifi_loss = *notif;
|
||||
|
||||
ieee80211_iterate_active_interfaces(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_bt_coex_notif_iterator,
|
||||
mvm);
|
||||
}
|
||||
|
||||
void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
enum ieee80211_rssi_event_data rssi_event)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#define IWL_MVM_BT_COEX_WIFI_LOSS_THRESH 0
|
||||
#define IWL_MVM_TRIGGER_LINK_SEL_TIME_SEC 30
|
||||
#define IWL_MVM_TPT_COUNT_WINDOW_SEC 5
|
||||
#define IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS 5
|
||||
#define IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH 11
|
||||
|
||||
#define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
|
||||
#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
|
||||
@@ -109,7 +111,7 @@
|
||||
#define IWL_MVM_FTM_INITIATOR_SECURE_LTF false
|
||||
#define IWL_MVM_FTM_RESP_NDP_SUPPORT true
|
||||
#define IWL_MVM_FTM_RESP_LMR_FEEDBACK_SUPPORT true
|
||||
#define IWL_MVM_FTM_NON_TB_MIN_TIME_BETWEEN_MSR 5
|
||||
#define IWL_MVM_FTM_NON_TB_MIN_TIME_BETWEEN_MSR 7
|
||||
#define IWL_MVM_FTM_NON_TB_MAX_TIME_BETWEEN_MSR 1000
|
||||
#define IWL_MVM_D3_DEBUG false
|
||||
#define IWL_MVM_USE_TWT true
|
||||
@@ -125,7 +127,6 @@
|
||||
#define IWL_MVM_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT 60 /* in seconds */
|
||||
#define IWL_MVM_MIN_BEACON_INTERVAL_TU 16
|
||||
#define IWL_MVM_AUTO_EML_ENABLE true
|
||||
#define IWL_MVM_MISSED_BEACONS_EXIT_ESR_THRESH 7
|
||||
|
||||
#define IWL_MVM_HIGH_RSSI_THRESH_20MHZ -67
|
||||
#define IWL_MVM_LOW_RSSI_THRESH_20MHZ -71
|
||||
|
||||
@@ -772,6 +772,7 @@ iwl_mvm_ftm_set_secured_ranging(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct iwl_mvm_ftm_iter_data target;
|
||||
|
||||
target.bssid = bssid;
|
||||
target.cipher = cipher;
|
||||
ieee80211_iter_keys(mvm->hw, vif, iter, &target);
|
||||
} else {
|
||||
memcpy(tk, entry->tk, sizeof(entry->tk));
|
||||
|
||||
@@ -863,7 +863,10 @@ static int iwl_mvm_config_ltr(struct iwl_mvm *mvm)
|
||||
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
|
||||
{
|
||||
u32 cmd_id = REDUCE_TX_POWER_CMD;
|
||||
struct iwl_dev_tx_power_cmd cmd = {
|
||||
struct iwl_dev_tx_power_cmd_v3_v8 cmd = {
|
||||
.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS),
|
||||
};
|
||||
struct iwl_dev_tx_power_cmd cmd_v9_v10 = {
|
||||
.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS),
|
||||
};
|
||||
__le16 *per_chain;
|
||||
@@ -871,8 +874,19 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
|
||||
u16 len = 0;
|
||||
u32 n_subbands;
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 3);
|
||||
void *cmd_data = &cmd;
|
||||
|
||||
if (cmd_ver >= 7) {
|
||||
if (cmd_ver == 10) {
|
||||
len = sizeof(cmd_v9_v10.v10);
|
||||
n_subbands = IWL_NUM_SUB_BANDS_V2;
|
||||
per_chain = &cmd_v9_v10.v10.per_chain[0][0][0];
|
||||
cmd_v9_v10.v10.flags =
|
||||
cpu_to_le32(mvm->fwrt.reduced_power_flags);
|
||||
} else if (cmd_ver == 9) {
|
||||
len = sizeof(cmd_v9_v10.v9);
|
||||
n_subbands = IWL_NUM_SUB_BANDS_V1;
|
||||
per_chain = &cmd_v9_v10.v9.per_chain[0][0];
|
||||
} else if (cmd_ver >= 7) {
|
||||
len = sizeof(cmd.v7);
|
||||
n_subbands = IWL_NUM_SUB_BANDS_V2;
|
||||
per_chain = cmd.v7.per_chain[0][0];
|
||||
@@ -899,9 +913,14 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
|
||||
per_chain = cmd.v3.per_chain[0][0];
|
||||
}
|
||||
|
||||
/* all structs have the same common part, add it */
|
||||
/* all structs have the same common part, add its length */
|
||||
len += sizeof(cmd.common);
|
||||
|
||||
if (cmd_ver < 9)
|
||||
len += sizeof(cmd.per_band);
|
||||
else
|
||||
cmd_data = &cmd_v9_v10;
|
||||
|
||||
ret = iwl_sar_fill_profile(&mvm->fwrt, per_chain,
|
||||
IWL_NUM_CHAIN_TABLES,
|
||||
n_subbands, prof_a, prof_b);
|
||||
@@ -913,7 +932,7 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
|
||||
iwl_mei_set_power_limit(per_chain);
|
||||
|
||||
IWL_DEBUG_RADIO(mvm, "Sending REDUCE_TX_POWER_CMD per chain\n");
|
||||
return iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, len, &cmd);
|
||||
return iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, len, cmd_data);
|
||||
}
|
||||
|
||||
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
|
||||
@@ -1464,7 +1483,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
RCU_INIT_POINTER(mvm->fw_id_to_link_sta[i], NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < IWL_MVM_FW_MAX_LINK_ID + 1; i++)
|
||||
for (i = 0; i < IWL_FW_MAX_LINK_ID + 1; i++)
|
||||
RCU_INIT_POINTER(mvm->link_id_to_link_conf[i], NULL);
|
||||
|
||||
mvm->tdls_cs.peer.sta_id = IWL_MVM_INVALID_STA;
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
HOW(EXIT_COEX) \
|
||||
HOW(EXIT_BANDWIDTH) \
|
||||
HOW(EXIT_CSA) \
|
||||
HOW(EXIT_LINK_USAGE)
|
||||
HOW(EXIT_LINK_USAGE) \
|
||||
HOW(EXIT_FAIL_ENTRY)
|
||||
|
||||
static const char *const iwl_mvm_esr_states_names[] = {
|
||||
#define NAME_ENTRY(x) [ilog2(IWL_MVM_ESR_##x)] = #x,
|
||||
@@ -233,10 +234,15 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
WARN_ON_ONCE(active == link_info->active);
|
||||
|
||||
/* When deactivating a link session protection should
|
||||
* be stopped
|
||||
* be stopped. Also let the firmware know if we can't Tx.
|
||||
*/
|
||||
if (!active && vif->type == NL80211_IFTYPE_STATION)
|
||||
if (!active && vif->type == NL80211_IFTYPE_STATION) {
|
||||
iwl_mvm_stop_session_protection(mvm, vif);
|
||||
if (link_info->csa_block_tx) {
|
||||
cmd.block_tx = 1;
|
||||
link_info->csa_block_tx = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd.link_id = cpu_to_le32(link_info->fw_link_id);
|
||||
@@ -258,7 +264,7 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
if (vif->type == NL80211_IFTYPE_ADHOC && link_conf->bssid)
|
||||
memcpy(cmd.ibss_bssid_addr, link_conf->bssid, ETH_ALEN);
|
||||
|
||||
iwl_mvm_set_fw_basic_rates(mvm, vif, link_conf,
|
||||
iwl_mvm_set_fw_basic_rates(mvm, vif, link_info,
|
||||
&cmd.cck_rates, &cmd.ofdm_rates);
|
||||
|
||||
cmd.cck_short_preamble = cpu_to_le32(link_conf->use_short_preamble);
|
||||
@@ -293,6 +299,17 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
(link_conf->uora_ocw_range >> 3) & 0x7;
|
||||
}
|
||||
|
||||
/* ap_sta may be NULL if we're disconnecting */
|
||||
if (changes & LINK_CONTEXT_MODIFY_HE_PARAMS && mvmvif->ap_sta) {
|
||||
struct ieee80211_link_sta *link_sta =
|
||||
link_sta_dereference_check(mvmvif->ap_sta, link_id);
|
||||
|
||||
if (!WARN_ON(!link_sta) && link_sta->he_cap.has_he &&
|
||||
link_sta->he_cap.he_cap_elem.mac_cap_info[5] &
|
||||
IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX)
|
||||
cmd.ul_mu_data_disable = 1;
|
||||
}
|
||||
|
||||
/* TODO how to set ndp_fdbk_buff_th_exp? */
|
||||
|
||||
if (iwl_mvm_set_fw_mu_edca_params(mvm, mvmvif->link[link_id],
|
||||
|
||||
@@ -413,19 +413,18 @@ static void iwl_mvm_ack_rates(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
void iwl_mvm_set_fw_basic_rates(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf,
|
||||
struct iwl_mvm_vif_link_info *link_info,
|
||||
__le32 *cck_rates, __le32 *ofdm_rates)
|
||||
{
|
||||
struct ieee80211_chanctx_conf *chanctx;
|
||||
struct iwl_mvm_phy_ctxt *phy_ctxt;
|
||||
u8 cck_ack_rates = 0, ofdm_ack_rates = 0;
|
||||
enum nl80211_band band = NL80211_BAND_2GHZ;
|
||||
|
||||
rcu_read_lock();
|
||||
chanctx = rcu_dereference(link_conf->chanctx_conf);
|
||||
iwl_mvm_ack_rates(mvm, vif, chanctx ? chanctx->def.chan->band
|
||||
: NL80211_BAND_2GHZ,
|
||||
&cck_ack_rates, &ofdm_ack_rates);
|
||||
phy_ctxt = link_info->phy_ctxt;
|
||||
if (phy_ctxt && phy_ctxt->channel)
|
||||
band = phy_ctxt->channel->band;
|
||||
|
||||
rcu_read_unlock();
|
||||
iwl_mvm_ack_rates(mvm, vif, band, &cck_ack_rates, &ofdm_ack_rates);
|
||||
|
||||
*cck_rates = cpu_to_le32((u32)cck_ack_rates);
|
||||
*ofdm_rates = cpu_to_le32((u32)ofdm_ack_rates);
|
||||
@@ -563,7 +562,7 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
|
||||
else
|
||||
eth_broadcast_addr(cmd->bssid_addr);
|
||||
|
||||
iwl_mvm_set_fw_basic_rates(mvm, vif, &vif->bss_conf, &cmd->cck_rates,
|
||||
iwl_mvm_set_fw_basic_rates(mvm, vif, &mvmvif->deflink, &cmd->cck_rates,
|
||||
&cmd->ofdm_rates);
|
||||
|
||||
cmd->cck_short_preamble =
|
||||
@@ -1528,7 +1527,7 @@ void iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
|
||||
mvm->ap_last_beacon_gp2 = le32_to_cpu(beacon->gp2);
|
||||
|
||||
if (!iwl_mvm_is_short_beacon_notif_supported(mvm)) {
|
||||
struct iwl_mvm_tx_resp *beacon_notify_hdr =
|
||||
struct iwl_tx_resp *beacon_notify_hdr =
|
||||
&beacon_v5->beacon_notify_hdr;
|
||||
|
||||
if (unlikely(pkt_len < sizeof(*beacon_v5)))
|
||||
@@ -1586,11 +1585,11 @@ void iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
|
||||
}
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
static void
|
||||
iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
const struct iwl_missed_beacons_notif *mb,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_missed_beacons_notif *mb = (void *)pkt->data;
|
||||
struct iwl_fw_dbg_trigger_missed_bcon *bcon_trig;
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger;
|
||||
u32 stop_trig_missed_bcon, stop_trig_missed_bcon_since_rx;
|
||||
@@ -1604,6 +1603,16 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
u8 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
|
||||
MISSED_BEACONS_NOTIFICATION,
|
||||
0);
|
||||
u8 new_notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, MAC_CONF_GROUP,
|
||||
MISSED_BEACONS_NOTIF, 0);
|
||||
|
||||
/* If the firmware uses the new notification (from MAC_CONF_GROUP),
|
||||
* refer to that notification's version.
|
||||
* Note that the new notification from MAC_CONF_GROUP starts from
|
||||
* version 5.
|
||||
*/
|
||||
if (new_notif_ver)
|
||||
notif_ver = new_notif_ver;
|
||||
|
||||
/* before version four the ID in the notification refers to mac ID */
|
||||
if (notif_ver < 4) {
|
||||
@@ -1620,13 +1629,11 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(mvm,
|
||||
"missed bcn %s_id=%u, consecutive=%u (%u, %u, %u)\n",
|
||||
"missed bcn %s_id=%u, consecutive=%u (%u)\n",
|
||||
notif_ver < 4 ? "mac" : "link",
|
||||
id,
|
||||
le32_to_cpu(mb->consec_missed_beacons),
|
||||
le32_to_cpu(mb->consec_missed_beacons_since_last_rx),
|
||||
le32_to_cpu(mb->num_recvd_beacons),
|
||||
le32_to_cpu(mb->num_expected_beacons));
|
||||
le32_to_cpu(mb->consec_missed_beacons_since_last_rx));
|
||||
|
||||
if (!vif)
|
||||
return;
|
||||
@@ -1656,10 +1663,27 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
"missed_beacons:%d, missed_beacons_since_rx:%d\n",
|
||||
rx_missed_bcon, rx_missed_bcon_since_rx);
|
||||
}
|
||||
} else if (rx_missed_bcon >= IWL_MVM_MISSED_BEACONS_EXIT_ESR_THRESH &&
|
||||
link_id >= 0 && hweight16(vif->active_links) > 1) {
|
||||
iwl_mvm_exit_esr(mvm, vif, IWL_MVM_ESR_EXIT_MISSED_BEACON,
|
||||
iwl_mvm_get_other_link(vif, link_id));
|
||||
} else if (link_id >= 0 && hweight16(vif->active_links) > 1) {
|
||||
u32 scnd_lnk_bcn_lost = 0;
|
||||
|
||||
if (notif_ver >= 5 &&
|
||||
!IWL_FW_CHECK(mvm,
|
||||
le32_to_cpu(mb->other_link_id) == IWL_MVM_FW_LINK_ID_INVALID,
|
||||
"No data for other link id but we are in EMLSR active_links: 0x%x\n",
|
||||
vif->active_links))
|
||||
scnd_lnk_bcn_lost =
|
||||
le32_to_cpu(mb->consec_missed_beacons_other_link);
|
||||
|
||||
/* Exit EMLSR if we lost more than
|
||||
* IWL_MVM_MISSED_BEACONS_EXIT_ESR_THRESH beacons on boths links
|
||||
* OR more than IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH on any link.
|
||||
*/
|
||||
if ((rx_missed_bcon >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS &&
|
||||
scnd_lnk_bcn_lost >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS) ||
|
||||
rx_missed_bcon >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH)
|
||||
iwl_mvm_exit_esr(mvm, vif,
|
||||
IWL_MVM_ESR_EXIT_MISSED_BEACON,
|
||||
iwl_mvm_get_primary_link(vif));
|
||||
} else if (rx_missed_bcon_since_rx > IWL_MVM_MISSED_BEACONS_THRESHOLD) {
|
||||
if (!iwl_mvm_has_new_tx_api(mvm))
|
||||
ieee80211_beacon_loss(vif);
|
||||
@@ -1687,6 +1711,31 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
iwl_fw_dbg_collect_trig(&mvm->fwrt, trigger, NULL);
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
|
||||
iwl_mvm_handle_missed_beacons_notif(mvm, (const void *)pkt->data, pkt);
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_missed_beacons_notif_legacy(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
const struct iwl_missed_beacons_notif_v4 *mb_v4 =
|
||||
(const void *)pkt->data;
|
||||
struct iwl_missed_beacons_notif mb = {
|
||||
.link_id = mb_v4->link_id,
|
||||
.consec_missed_beacons = mb_v4->consec_missed_beacons,
|
||||
.consec_missed_beacons_since_last_rx =
|
||||
mb_v4->consec_missed_beacons_since_last_rx,
|
||||
.other_link_id = cpu_to_le32(IWL_MVM_FW_LINK_ID_INVALID),
|
||||
};
|
||||
|
||||
iwl_mvm_handle_missed_beacons_notif(mvm, &mb, pkt);
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
|
||||
@@ -165,12 +165,8 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
|
||||
mvm->lar_regdom_set = true;
|
||||
mvm->mcc_src = src_id;
|
||||
|
||||
/* Some kind of regulatory mess means we need to currently disallow
|
||||
* puncturing in the US and Canada. Do that here, at least until we
|
||||
* figure out the new chanctx APIs for puncturing.
|
||||
*/
|
||||
if (resp->mcc == cpu_to_le16(IWL_MCC_US) ||
|
||||
resp->mcc == cpu_to_le16(IWL_MCC_CANADA))
|
||||
if (!iwl_puncturing_is_allowed_in_bios(mvm->bios_enable_puncturing,
|
||||
le16_to_cpu(resp->mcc)))
|
||||
ieee80211_hw_set(mvm->hw, DISALLOW_PUNCTURING);
|
||||
else
|
||||
__clear_bit(IEEE80211_HW_DISALLOW_PUNCTURING, mvm->hw->flags);
|
||||
@@ -639,10 +635,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
NL80211_FEATURE_LOW_PRIORITY_SCAN |
|
||||
NL80211_FEATURE_P2P_GO_OPPPS |
|
||||
NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
|
||||
NL80211_FEATURE_DYNAMIC_SMPS |
|
||||
NL80211_FEATURE_STATIC_SMPS |
|
||||
NL80211_FEATURE_SUPPORTS_WMM_ADMISSION;
|
||||
|
||||
/* when firmware supports RLC/SMPS offload, do not set these
|
||||
* driver features, since it's no longer supported by driver.
|
||||
*/
|
||||
if (!iwl_mvm_has_rlc_offload(mvm))
|
||||
hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS |
|
||||
NL80211_FEATURE_DYNAMIC_SMPS;
|
||||
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT))
|
||||
hw->wiphy->features |= NL80211_FEATURE_TX_POWER_INSERTION;
|
||||
@@ -838,20 +839,10 @@ void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
|
||||
if (ieee80211_is_mgmt(hdr->frame_control))
|
||||
sta = NULL;
|
||||
|
||||
/* If there is no sta, and it's not offchannel - send through AP */
|
||||
/* this shouldn't even happen: just drop */
|
||||
if (!sta && info->control.vif->type == NL80211_IFTYPE_STATION &&
|
||||
!offchannel) {
|
||||
struct iwl_mvm_vif *mvmvif =
|
||||
iwl_mvm_vif_from_mac80211(info->control.vif);
|
||||
u8 ap_sta_id = READ_ONCE(mvmvif->deflink.ap_sta_id);
|
||||
|
||||
if (ap_sta_id < mvm->fw->ucode_capa.num_stations) {
|
||||
/* mac80211 holds rcu read lock */
|
||||
sta = rcu_dereference(mvm->fw_id_to_mac_id[ap_sta_id]);
|
||||
if (IS_ERR_OR_NULL(sta))
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
!offchannel)
|
||||
goto drop;
|
||||
|
||||
if (tmp_sta && !sta && link_id != IEEE80211_LINK_UNSPECIFIED &&
|
||||
!ieee80211_is_probe_resp(hdr->frame_control)) {
|
||||
@@ -1480,19 +1471,33 @@ int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
{
|
||||
u32 cmd_id = REDUCE_TX_POWER_CMD;
|
||||
int len;
|
||||
struct iwl_dev_tx_power_cmd cmd = {
|
||||
struct iwl_dev_tx_power_cmd_v3_v8 cmd = {
|
||||
.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC),
|
||||
.common.mac_context_id =
|
||||
cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id),
|
||||
.common.pwr_restriction = cpu_to_le16(8 * tx_power),
|
||||
};
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id,
|
||||
IWL_FW_CMD_VER_UNKNOWN);
|
||||
struct iwl_dev_tx_power_cmd cmd_v9_v10;
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 3);
|
||||
u16 u_tx_power = tx_power == IWL_DEFAULT_MAX_TX_POWER ?
|
||||
IWL_DEV_MAX_TX_POWER : 8 * tx_power;
|
||||
void *cmd_data = &cmd;
|
||||
|
||||
if (tx_power == IWL_DEFAULT_MAX_TX_POWER)
|
||||
cmd.common.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER);
|
||||
cmd.common.pwr_restriction = cpu_to_le16(u_tx_power);
|
||||
|
||||
if (cmd_ver == 8)
|
||||
if (cmd_ver > 8) {
|
||||
/* Those fields sit on the same place for v9 and v10 */
|
||||
cmd_v9_v10.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC);
|
||||
cmd_v9_v10.common.mac_context_id =
|
||||
cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id);
|
||||
cmd_v9_v10.common.pwr_restriction = cpu_to_le16(u_tx_power);
|
||||
cmd_data = &cmd_v9_v10;
|
||||
}
|
||||
|
||||
if (cmd_ver == 10)
|
||||
len = sizeof(cmd_v9_v10.v10);
|
||||
else if (cmd_ver == 9)
|
||||
len = sizeof(cmd_v9_v10.v9);
|
||||
else if (cmd_ver == 8)
|
||||
len = sizeof(cmd.v8);
|
||||
else if (cmd_ver == 7)
|
||||
len = sizeof(cmd.v7);
|
||||
@@ -1507,10 +1512,14 @@ int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
else
|
||||
len = sizeof(cmd.v3);
|
||||
|
||||
/* all structs have the same common part, add it */
|
||||
/* all structs have the same common part, add its length */
|
||||
len += sizeof(cmd.common);
|
||||
|
||||
return iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, len, &cmd);
|
||||
if (cmd_ver < 9)
|
||||
len += sizeof(cmd.per_band);
|
||||
|
||||
return iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, len, cmd_data);
|
||||
|
||||
}
|
||||
|
||||
static void iwl_mvm_post_csa_tx(void *data, struct ieee80211_sta *sta)
|
||||
|
||||
@@ -144,7 +144,7 @@ static void iwl_mvm_mld_update_sta_key(struct ieee80211_hw *hw,
|
||||
if (sta != data->sta || key->link_id >= 0)
|
||||
return;
|
||||
|
||||
err = iwl_mvm_send_cmd_pdu(mvm, cmd_id, CMD_ASYNC, sizeof(cmd), &cmd);
|
||||
err = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cmd), &cmd);
|
||||
|
||||
if (err)
|
||||
data->err = err;
|
||||
@@ -162,8 +162,8 @@ int iwl_mvm_mld_update_sta_keys(struct iwl_mvm *mvm,
|
||||
.new_sta_mask = new_sta_mask,
|
||||
};
|
||||
|
||||
ieee80211_iter_keys_rcu(mvm->hw, vif, iwl_mvm_mld_update_sta_key,
|
||||
&data);
|
||||
ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_mld_update_sta_key,
|
||||
&data);
|
||||
return data.err;
|
||||
}
|
||||
|
||||
@@ -402,7 +402,7 @@ void iwl_mvm_sec_key_remove_ap(struct iwl_mvm *mvm,
|
||||
if (!sec_key_ver)
|
||||
return;
|
||||
|
||||
ieee80211_iter_keys_rcu(mvm->hw, vif,
|
||||
iwl_mvm_sec_key_remove_ap_iter,
|
||||
(void *)(uintptr_t)link_id);
|
||||
ieee80211_iter_keys(mvm->hw, vif,
|
||||
iwl_mvm_sec_key_remove_ap_iter,
|
||||
(void *)(uintptr_t)link_id);
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ static void iwl_mvm_restart_mpdu_count(struct iwl_mvm *mvm,
|
||||
spin_unlock_bh(&mvmsta->mpdu_counters[q].lock);
|
||||
}
|
||||
|
||||
IWL_DEBUG_STATS(mvm, "MPDU counters are cleared\n");
|
||||
IWL_DEBUG_INFO(mvm, "MPDU counters are cleared\n");
|
||||
}
|
||||
|
||||
static int iwl_mvm_esr_mode_active(struct iwl_mvm *mvm,
|
||||
@@ -269,6 +269,9 @@ static int iwl_mvm_esr_mode_active(struct iwl_mvm *mvm,
|
||||
*/
|
||||
iwl_mvm_restart_mpdu_count(mvm, mvmvif);
|
||||
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_ESR_LINK_UP,
|
||||
NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -456,6 +459,9 @@ static int iwl_mvm_esr_mode_inactive(struct iwl_mvm *mvm,
|
||||
/* Start a new counting window */
|
||||
iwl_mvm_restart_mpdu_count(mvm, mvmvif);
|
||||
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_ESR_LINK_DOWN,
|
||||
NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1335,6 +1341,22 @@ iwl_mvm_mld_mac_pre_channel_switch(struct ieee80211_hw *hw,
|
||||
else
|
||||
selected = primary;
|
||||
|
||||
/*
|
||||
* remembers to tell the firmware that this link can't tx
|
||||
* Note that this logic seems to be unrelated to esr, but it
|
||||
* really is needed only when esr is active. When we have a
|
||||
* single link, the firmware will handle all this on its own.
|
||||
* In multi-link scenarios, we can learn about the CSA from
|
||||
* another link and this logic is too complex for the firmware
|
||||
* to track.
|
||||
* Since we want to de-activate the link that got a CSA, we
|
||||
* need to tell the firmware not to send any frame on that link
|
||||
* as the firmware may not be aware that link is under a CSA
|
||||
* with mode=1 (no Tx allowed).
|
||||
*/
|
||||
if (chsw->block_tx && mvmvif->link[chsw->link_id])
|
||||
mvmvif->link[chsw->link_id]->csa_block_tx = true;
|
||||
|
||||
iwl_mvm_exit_esr(mvm, vif, IWL_MVM_ESR_EXIT_CSA, selected);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ u32 iwl_mvm_sta_fw_id_mask(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
}
|
||||
|
||||
static int iwl_mvm_mld_send_sta_cmd(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_sta_cfg_cmd *cmd)
|
||||
struct iwl_sta_cfg_cmd *cmd)
|
||||
{
|
||||
int ret = iwl_mvm_send_cmd_pdu(mvm,
|
||||
WIDE_ID(MAC_CONF_GROUP, STA_CONFIG_CMD),
|
||||
@@ -63,7 +63,7 @@ static int iwl_mvm_mld_add_int_sta_to_fw(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_int_sta *sta,
|
||||
const u8 *addr, int link_id)
|
||||
{
|
||||
struct iwl_mvm_sta_cfg_cmd cmd;
|
||||
struct iwl_sta_cfg_cmd cmd;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
@@ -94,7 +94,7 @@ static int iwl_mvm_mld_add_int_sta_to_fw(struct iwl_mvm *mvm,
|
||||
*/
|
||||
static int iwl_mvm_mld_rm_sta_from_fw(struct iwl_mvm *mvm, u32 sta_id)
|
||||
{
|
||||
struct iwl_mvm_remove_sta_cmd rm_sta_cmd = {
|
||||
struct iwl_remove_sta_cmd rm_sta_cmd = {
|
||||
.sta_id = cpu_to_le32(sta_id),
|
||||
};
|
||||
int ret;
|
||||
@@ -216,7 +216,7 @@ int iwl_mvm_mld_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
const u8 *baddr = _baddr;
|
||||
unsigned int wdg_timeout =
|
||||
iwl_mvm_get_wd_timeout(mvm, vif, false, false);
|
||||
iwl_mvm_get_wd_timeout(mvm, vif);
|
||||
u16 *queue;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
@@ -254,7 +254,7 @@ int iwl_mvm_mld_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct iwl_mvm_int_sta *msta = &mvm_link->mcast_sta;
|
||||
static const u8 _maddr[] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
const u8 *maddr = _maddr;
|
||||
unsigned int timeout = iwl_mvm_get_wd_timeout(mvm, vif, false, false);
|
||||
unsigned int timeout = iwl_mvm_get_wd_timeout(mvm, vif);
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
@@ -438,7 +438,7 @@ static int iwl_mvm_mld_cfg_sta(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
struct iwl_mvm_vif *mvm_vif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_vif_link_info *link_info =
|
||||
mvm_vif->link[link_conf->link_id];
|
||||
struct iwl_mvm_sta_cfg_cmd cmd = {
|
||||
struct iwl_sta_cfg_cmd cmd = {
|
||||
.sta_id = cpu_to_le32(mvm_link_sta->sta_id),
|
||||
.station_type = cpu_to_le32(mvm_sta->sta_type),
|
||||
};
|
||||
|
||||
@@ -299,6 +299,7 @@ struct iwl_probe_resp_data {
|
||||
* @active: indicates the link is active in FW (for sanity checking)
|
||||
* @cab_queue: content-after-beacon (multicast) queue
|
||||
* @listen_lmac: indicates this link is allocated to the listen LMAC
|
||||
* @csa_block_tx: we got CSA with mode=1
|
||||
* @mcast_sta: multicast station
|
||||
* @phy_ctxt: phy context allocated to this link, if any
|
||||
* @bf_data: beacon filtering data
|
||||
@@ -324,6 +325,7 @@ struct iwl_mvm_vif_link_info {
|
||||
bool he_ru_2mhz_block;
|
||||
bool active;
|
||||
bool listen_lmac;
|
||||
bool csa_block_tx;
|
||||
|
||||
u16 cab_queue;
|
||||
/* Assigned while mac80211 has the link in a channel context,
|
||||
@@ -368,6 +370,7 @@ struct iwl_mvm_vif_link_info {
|
||||
* preventing the enablement of EMLSR
|
||||
* @IWL_MVM_ESR_EXIT_CSA: CSA happened, so exit EMLSR
|
||||
* @IWL_MVM_ESR_EXIT_LINK_USAGE: Exit EMLSR due to low tpt on secondary link
|
||||
* @IWL_MVM_ESR_EXIT_FAIL_ENTRY: Exit EMLSR due to entry failure
|
||||
*/
|
||||
enum iwl_mvm_esr_state {
|
||||
IWL_MVM_ESR_BLOCKED_PREVENTION = 0x1,
|
||||
@@ -382,6 +385,7 @@ enum iwl_mvm_esr_state {
|
||||
IWL_MVM_ESR_EXIT_BANDWIDTH = 0x80000,
|
||||
IWL_MVM_ESR_EXIT_CSA = 0x100000,
|
||||
IWL_MVM_ESR_EXIT_LINK_USAGE = 0x200000,
|
||||
IWL_MVM_ESR_EXIT_FAIL_ENTRY = 0x400000,
|
||||
};
|
||||
|
||||
#define IWL_MVM_BLOCK_ESR_REASONS 0xffff
|
||||
@@ -770,7 +774,6 @@ struct iwl_mvm_tcm {
|
||||
* @num_stored: number of mpdus stored in the buffer
|
||||
* @queue: queue of this reorder buffer
|
||||
* @last_amsdu: track last ASMDU SN for duplication detection
|
||||
* @last_sub_index: track ASMDU sub frame index for duplication detection
|
||||
* @valid: reordering is valid for this queue
|
||||
* @lock: protect reorder buffer internal state
|
||||
*/
|
||||
@@ -779,7 +782,6 @@ struct iwl_mvm_reorder_buffer {
|
||||
u16 num_stored;
|
||||
int queue;
|
||||
u16 last_amsdu;
|
||||
u8 last_sub_index;
|
||||
bool valid;
|
||||
spinlock_t lock;
|
||||
} ____cacheline_aligned_in_smp;
|
||||
@@ -1074,8 +1076,8 @@ struct iwl_mvm {
|
||||
|
||||
/* data related to data path */
|
||||
struct iwl_rx_phy_info last_phy_info;
|
||||
struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT_MAX];
|
||||
struct ieee80211_link_sta __rcu *fw_id_to_link_sta[IWL_MVM_STATION_COUNT_MAX];
|
||||
struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_STATION_COUNT_MAX];
|
||||
struct ieee80211_link_sta __rcu *fw_id_to_link_sta[IWL_STATION_COUNT_MAX];
|
||||
u8 rx_ba_sessions;
|
||||
|
||||
/* configured by mac80211 */
|
||||
@@ -1164,7 +1166,7 @@ struct iwl_mvm {
|
||||
|
||||
struct ieee80211_vif __rcu *vif_id_to_mac[NUM_MAC_INDEX_DRIVER];
|
||||
|
||||
struct ieee80211_bss_conf __rcu *link_id_to_link_conf[IWL_MVM_FW_MAX_LINK_ID + 1];
|
||||
struct ieee80211_bss_conf __rcu *link_id_to_link_conf[IWL_FW_MAX_LINK_ID + 1];
|
||||
|
||||
/* -1 for always, 0 for never, >0 for that many times */
|
||||
s8 fw_restart;
|
||||
@@ -1200,8 +1202,11 @@ struct iwl_mvm {
|
||||
|
||||
wait_queue_head_t rx_sync_waitq;
|
||||
|
||||
/* BT-Coex */
|
||||
struct iwl_bt_coex_profile_notif last_bt_notif;
|
||||
/* BT-Coex - only one of those will be used */
|
||||
union {
|
||||
struct iwl_bt_coex_prof_old_notif last_bt_notif;
|
||||
struct iwl_bt_coex_profile_notif last_bt_wifi_loss;
|
||||
};
|
||||
struct iwl_bt_coex_ci_cmd last_bt_ci_cmd;
|
||||
|
||||
u8 bt_tx_prio;
|
||||
@@ -1365,6 +1370,7 @@ struct iwl_mvm {
|
||||
struct iwl_mvm_acs_survey *acs_survey;
|
||||
|
||||
bool statistics_clear;
|
||||
u32 bios_enable_puncturing;
|
||||
};
|
||||
|
||||
/* Extract MVM priv from op_mode and _hw */
|
||||
@@ -1700,9 +1706,9 @@ static inline struct agg_tx_status *
|
||||
iwl_mvm_get_agg_status(struct iwl_mvm *mvm, void *tx_resp)
|
||||
{
|
||||
if (iwl_mvm_has_new_tx_api(mvm))
|
||||
return &((struct iwl_mvm_tx_resp *)tx_resp)->status;
|
||||
return &((struct iwl_tx_resp *)tx_resp)->status;
|
||||
else
|
||||
return ((struct iwl_mvm_tx_resp_v3 *)tx_resp)->status;
|
||||
return ((struct iwl_tx_resp_v3 *)tx_resp)->status;
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_is_tt_in_fw(struct iwl_mvm *mvm)
|
||||
@@ -1745,7 +1751,7 @@ static inline int iwl_mvm_max_active_links(struct iwl_mvm *mvm,
|
||||
if (iwl_mvm_is_esr_supported(trans) ||
|
||||
(CSR_HW_RFID_TYPE(trans->hw_rf_id) == IWL_CFG_RF_TYPE_FM &&
|
||||
CSR_HW_RFID_IS_CDB(trans->hw_rf_id)))
|
||||
return IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM;
|
||||
return IWL_FW_MAX_ACTIVE_LINKS_NUM;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1764,6 +1770,13 @@ static inline u8 iwl_mvm_mac_ac_to_tx_fifo(struct iwl_mvm *mvm,
|
||||
return iwl_mvm_ac_to_tx_fifo[ac];
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_has_rlc_offload(struct iwl_mvm *mvm)
|
||||
{
|
||||
return iwl_fw_lookup_cmd_ver(mvm->fw,
|
||||
WIDE_ID(DATA_PATH_GROUP, RLC_CONFIG_CMD),
|
||||
0) >= 3;
|
||||
}
|
||||
|
||||
struct iwl_rate_info {
|
||||
u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
|
||||
u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
|
||||
@@ -2003,7 +2016,7 @@ int iwl_mvm_phy_send_rlc(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
|
||||
void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif);
|
||||
void iwl_mvm_set_fw_basic_rates(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf,
|
||||
struct iwl_mvm_vif_link_info *link_info,
|
||||
__le32 *cck_rates, __le32 *ofdm_rates);
|
||||
void iwl_mvm_set_fw_protection_flags(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
@@ -2062,6 +2075,8 @@ void iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_missed_beacons_notif_legacy(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_mu_mimo_grp_notif(struct iwl_mvm *mvm,
|
||||
@@ -2322,6 +2337,8 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
|
||||
|
||||
/* BT Coex */
|
||||
int iwl_mvm_send_bt_init_conf(struct iwl_mvm *mvm);
|
||||
void iwl_mvm_rx_bt_coex_old_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
@@ -2570,8 +2587,7 @@ u8 iwl_mvm_tcm_load_percentage(u32 airtime, u32 elapsed);
|
||||
|
||||
void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error);
|
||||
unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool tdls, bool cmd_q);
|
||||
struct ieee80211_vif *vif);
|
||||
void iwl_mvm_connection_loss(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
const char *errmsg);
|
||||
void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
|
||||
|
||||
@@ -611,6 +611,7 @@ void iwl_mvm_rx_chub_update_mcc(struct iwl_mvm *mvm,
|
||||
char mcc[3];
|
||||
struct ieee80211_regdomain *regd;
|
||||
int wgds_tbl_idx;
|
||||
bool changed = false;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
@@ -630,10 +631,15 @@ void iwl_mvm_rx_chub_update_mcc(struct iwl_mvm *mvm,
|
||||
IWL_DEBUG_LAR(mvm,
|
||||
"RX: received chub update mcc cmd (mcc '%s' src %d)\n",
|
||||
mcc, src);
|
||||
regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, mcc, src, NULL);
|
||||
regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, mcc, src, &changed);
|
||||
if (IS_ERR_OR_NULL(regd))
|
||||
return;
|
||||
|
||||
if (!changed) {
|
||||
IWL_DEBUG_LAR(mvm, "RX: No change in the regulatory data\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
wgds_tbl_idx = iwl_mvm_get_sar_geo_profile(mvm);
|
||||
if (wgds_tbl_idx < 1)
|
||||
IWL_DEBUG_INFO(mvm,
|
||||
@@ -644,5 +650,7 @@ void iwl_mvm_rx_chub_update_mcc(struct iwl_mvm *mvm,
|
||||
wgds_tbl_idx);
|
||||
|
||||
regulatory_set_wiphy_regd(mvm->hw->wiphy, regd);
|
||||
|
||||
out:
|
||||
kfree(regd);
|
||||
}
|
||||
|
||||
@@ -159,6 +159,43 @@ static void iwl_mvm_rx_esr_mode_notif(struct iwl_mvm *mvm,
|
||||
iwl_mvm_get_primary_link(vif));
|
||||
}
|
||||
|
||||
static void iwl_mvm_rx_esr_trans_fail_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_esr_trans_fail_notif *notif = (void *)pkt->data;
|
||||
struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm);
|
||||
u8 fw_link_id = le32_to_cpu(notif->link_id);
|
||||
struct ieee80211_bss_conf *bss_conf;
|
||||
|
||||
if (IS_ERR_OR_NULL(vif))
|
||||
return;
|
||||
|
||||
IWL_DEBUG_INFO(mvm, "Failed to %s eSR on link %d, reason %d\n",
|
||||
le32_to_cpu(notif->activation) ? "enter" : "exit",
|
||||
le32_to_cpu(notif->link_id),
|
||||
le32_to_cpu(notif->err_code));
|
||||
|
||||
/* we couldn't go back to single link, disconnect */
|
||||
if (!le32_to_cpu(notif->activation)) {
|
||||
iwl_mvm_connection_loss(mvm, vif, "emlsr exit failed");
|
||||
return;
|
||||
}
|
||||
|
||||
bss_conf = iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, fw_link_id, false);
|
||||
if (IWL_FW_CHECK(mvm, !bss_conf,
|
||||
"FW reported failure to activate EMLSR on a non-existing link: %d\n",
|
||||
fw_link_id))
|
||||
return;
|
||||
|
||||
/*
|
||||
* We failed to activate the second link and enter EMLSR, we need to go
|
||||
* back to single link.
|
||||
*/
|
||||
iwl_mvm_exit_esr(mvm, vif, IWL_MVM_ESR_EXIT_FAIL_ENTRY,
|
||||
bss_conf->link_id);
|
||||
}
|
||||
|
||||
static void iwl_mvm_rx_monitor_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
@@ -261,6 +298,12 @@ static void iwl_mvm_rx_thermal_dual_chain_req(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_thermal_dual_chain_request *req = (void *)pkt->data;
|
||||
|
||||
/* firmware is expected to handle that in RLC offload mode */
|
||||
if (IWL_FW_CHECK(mvm, iwl_mvm_has_rlc_offload(mvm),
|
||||
"Got THERMAL_DUAL_CHAIN_REQUEST (0x%x) in RLC offload mode\n",
|
||||
req->event))
|
||||
return;
|
||||
|
||||
/*
|
||||
* We could pass it to the iterator data, but also need to remember
|
||||
* it for new interfaces that are added while in this state.
|
||||
@@ -325,7 +368,7 @@ struct iwl_rx_handlers {
|
||||
*/
|
||||
static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
||||
RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, RX_HANDLER_SYNC,
|
||||
struct iwl_mvm_tx_resp),
|
||||
struct iwl_tx_resp),
|
||||
RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, RX_HANDLER_SYNC,
|
||||
struct iwl_mvm_ba_notif),
|
||||
|
||||
@@ -333,9 +376,12 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
||||
iwl_mvm_tlc_update_notif, RX_HANDLER_SYNC,
|
||||
struct iwl_tlc_update_notif),
|
||||
|
||||
RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif,
|
||||
RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_old_notif,
|
||||
RX_HANDLER_ASYNC_LOCKED_WIPHY,
|
||||
struct iwl_bt_coex_profile_notif),
|
||||
struct iwl_bt_coex_prof_old_notif),
|
||||
RX_HANDLER_GRP(BT_COEX_GROUP, PROFILE_NOTIF, iwl_mvm_rx_bt_coex_notif,
|
||||
RX_HANDLER_ASYNC_LOCKED_WIPHY,
|
||||
struct iwl_bt_coex_profile_notif),
|
||||
RX_HANDLER_NO_SIZE(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif,
|
||||
RX_HANDLER_ASYNC_LOCKED),
|
||||
RX_HANDLER_NO_SIZE(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics,
|
||||
@@ -385,10 +431,15 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
||||
iwl_mvm_rx_umac_scan_iter_complete_notif, RX_HANDLER_SYNC,
|
||||
struct iwl_umac_scan_iter_complete_notif),
|
||||
|
||||
RX_HANDLER(MISSED_BEACONS_NOTIFICATION, iwl_mvm_rx_missed_beacons_notif,
|
||||
RX_HANDLER(MISSED_BEACONS_NOTIFICATION,
|
||||
iwl_mvm_rx_missed_beacons_notif_legacy,
|
||||
RX_HANDLER_ASYNC_LOCKED_WIPHY,
|
||||
struct iwl_missed_beacons_notif),
|
||||
struct iwl_missed_beacons_notif_v4),
|
||||
|
||||
RX_HANDLER_GRP(MAC_CONF_GROUP, MISSED_BEACONS_NOTIF,
|
||||
iwl_mvm_rx_missed_beacons_notif,
|
||||
RX_HANDLER_ASYNC_LOCKED_WIPHY,
|
||||
struct iwl_missed_beacons_notif),
|
||||
RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, RX_HANDLER_SYNC,
|
||||
struct iwl_error_resp),
|
||||
RX_HANDLER(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION,
|
||||
@@ -472,6 +523,10 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
||||
RX_HANDLER_GRP(SCAN_GROUP, CHANNEL_SURVEY_NOTIF,
|
||||
iwl_mvm_rx_channel_survey_notif, RX_HANDLER_ASYNC_LOCKED,
|
||||
struct iwl_umac_scan_channel_survey_notif),
|
||||
RX_HANDLER_GRP(MAC_CONF_GROUP, EMLSR_TRANS_FAIL_NOTIF,
|
||||
iwl_mvm_rx_esr_trans_fail_notif,
|
||||
RX_HANDLER_ASYNC_LOCKED_WIPHY,
|
||||
struct iwl_esr_trans_fail_notif),
|
||||
};
|
||||
#undef RX_HANDLER
|
||||
#undef RX_HANDLER_GRP
|
||||
@@ -602,6 +657,7 @@ static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = {
|
||||
HCMD_NAME(STA_REMOVE_CMD),
|
||||
HCMD_NAME(STA_DISABLE_TX_CMD),
|
||||
HCMD_NAME(ROC_CMD),
|
||||
HCMD_NAME(EMLSR_TRANS_FAIL_NOTIF),
|
||||
HCMD_NAME(ROC_NOTIF),
|
||||
HCMD_NAME(CHANNEL_SWITCH_ERROR_NOTIF),
|
||||
HCMD_NAME(MISSED_VAP_NOTIF),
|
||||
@@ -713,6 +769,13 @@ static const struct iwl_hcmd_names iwl_mvm_regulatory_and_nvm_names[] = {
|
||||
HCMD_NAME(TAS_CONFIG),
|
||||
};
|
||||
|
||||
/* Please keep this array *SORTED* by hex value.
|
||||
* Access is done through binary search
|
||||
*/
|
||||
static const struct iwl_hcmd_names iwl_mvm_bt_coex_names[] = {
|
||||
HCMD_NAME(PROFILE_NOTIF),
|
||||
};
|
||||
|
||||
static const struct iwl_hcmd_arr iwl_mvm_groups[] = {
|
||||
[LEGACY_GROUP] = HCMD_ARR(iwl_mvm_legacy_names),
|
||||
[LONG_GROUP] = HCMD_ARR(iwl_mvm_legacy_names),
|
||||
@@ -722,6 +785,7 @@ static const struct iwl_hcmd_arr iwl_mvm_groups[] = {
|
||||
[DATA_PATH_GROUP] = HCMD_ARR(iwl_mvm_data_path_names),
|
||||
[SCAN_GROUP] = HCMD_ARR(iwl_mvm_scan_names),
|
||||
[LOCATION_GROUP] = HCMD_ARR(iwl_mvm_location_names),
|
||||
[BT_COEX_GROUP] = HCMD_ARR(iwl_mvm_bt_coex_names),
|
||||
[PROT_OFFLOAD_GROUP] = HCMD_ARR(iwl_mvm_prot_offload_names),
|
||||
[REGULATORY_AND_NVM_GROUP] =
|
||||
HCMD_ARR(iwl_mvm_regulatory_and_nvm_names),
|
||||
@@ -1223,12 +1287,12 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
struct iwl_mvm_csme_conn_info *csme_conn_info __maybe_unused;
|
||||
|
||||
/*
|
||||
* We use IWL_MVM_STATION_COUNT_MAX to check the validity of the station
|
||||
* We use IWL_STATION_COUNT_MAX to check the validity of the station
|
||||
* index all over the driver - check that its value corresponds to the
|
||||
* array size.
|
||||
*/
|
||||
BUILD_BUG_ON(ARRAY_SIZE(mvm->fw_id_to_mac_id) !=
|
||||
IWL_MVM_STATION_COUNT_MAX);
|
||||
IWL_STATION_COUNT_MAX);
|
||||
|
||||
/********************************
|
||||
* 1. Allocating and configuring HW data
|
||||
@@ -1287,6 +1351,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
}
|
||||
|
||||
mvm->fw_restart = iwlwifi_mod_params.fw_restart ? -1 : 0;
|
||||
mvm->bios_enable_puncturing = iwl_uefi_get_puncturing(&mvm->fwrt);
|
||||
|
||||
if (iwl_mvm_has_new_tx_api(mvm)) {
|
||||
/*
|
||||
@@ -1386,10 +1451,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
trans_cfg.cb_data_offs = offsetof(struct ieee80211_tx_info,
|
||||
driver_data[2]);
|
||||
|
||||
/* Set a short watchdog for the command queue */
|
||||
trans_cfg.cmd_q_wdg_timeout =
|
||||
iwl_mvm_get_wd_timeout(mvm, NULL, false, true);
|
||||
|
||||
snprintf(mvm->hw->wiphy->fw_version,
|
||||
sizeof(mvm->hw->wiphy->fw_version),
|
||||
"%.31s", fw->fw_version);
|
||||
|
||||
@@ -159,7 +159,11 @@ int iwl_mvm_phy_send_rlc(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
|
||||
.phy_id = cpu_to_le32(ctxt->id),
|
||||
};
|
||||
|
||||
if (ctxt->rlc_disabled)
|
||||
/* From version 3, RLC is offloaded to firmware, so the driver no
|
||||
* longer needs to send cmd.rlc, note that we are not using any
|
||||
* other fields in the command - don't send it.
|
||||
*/
|
||||
if (iwl_mvm_has_rlc_offload(mvm) || ctxt->rlc_disabled)
|
||||
return 0;
|
||||
|
||||
if (iwl_fw_lookup_cmd_ver(mvm->fw, WIDE_ID(DATA_PATH_GROUP,
|
||||
|
||||
@@ -738,8 +738,8 @@ static void iwl_mvm_stats_energy_iter(void *_data,
|
||||
u8 *energy = _data;
|
||||
u32 sta_id = mvmsta->deflink.sta_id;
|
||||
|
||||
if (WARN_ONCE(sta_id >= IWL_MVM_STATION_COUNT_MAX, "sta_id %d >= %d",
|
||||
sta_id, IWL_MVM_STATION_COUNT_MAX))
|
||||
if (WARN_ONCE(sta_id >= IWL_STATION_COUNT_MAX, "sta_id %d >= %d",
|
||||
sta_id, IWL_STATION_COUNT_MAX))
|
||||
return;
|
||||
|
||||
if (energy[sta_id])
|
||||
@@ -991,7 +991,7 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
|
||||
spin_lock_bh(&mvmsta->mpdu_counters[q].lock);
|
||||
|
||||
/* The link IDs that doesn't exist will contain 0 */
|
||||
for (int link = 0; link < IWL_MVM_FW_MAX_LINK_ID; link++) {
|
||||
for (int link = 0; link < IWL_FW_MAX_LINK_ID; link++) {
|
||||
total_tx += mvmsta->mpdu_counters[q].per_link[link].tx;
|
||||
total_rx += mvmsta->mpdu_counters[q].per_link[link].rx;
|
||||
}
|
||||
@@ -1009,8 +1009,8 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
|
||||
spin_unlock_bh(&mvmsta->mpdu_counters[q].lock);
|
||||
}
|
||||
|
||||
IWL_DEBUG_STATS(mvm, "total Tx MPDUs: %ld. total Rx MPDUs: %ld\n",
|
||||
total_tx, total_rx);
|
||||
IWL_DEBUG_INFO(mvm, "total Tx MPDUs: %ld. total Rx MPDUs: %ld\n",
|
||||
total_tx, total_rx);
|
||||
|
||||
/* If we don't have enough MPDUs - exit EMLSR */
|
||||
if (total_tx < IWL_MVM_ENTER_ESR_TPT_THRESH &&
|
||||
@@ -1020,6 +1020,9 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
|
||||
return;
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(mvm, "Secondary Link %d: Tx MPDUs: %ld. Rx MPDUs: %ld\n",
|
||||
sec_link, sec_link_tx, sec_link_rx);
|
||||
|
||||
/* Calculate the percentage of the secondary link TX/RX */
|
||||
sec_link_tx_perc = total_tx ? sec_link_tx * 100 / total_tx : 0;
|
||||
sec_link_rx_perc = total_rx ? sec_link_rx * 100 / total_rx : 0;
|
||||
@@ -1039,7 +1042,7 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
|
||||
void iwl_mvm_handle_rx_system_oper_stats(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
u8 average_energy[IWL_MVM_STATION_COUNT_MAX];
|
||||
u8 average_energy[IWL_STATION_COUNT_MAX];
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_system_statistics_notif_oper *stats;
|
||||
int i;
|
||||
@@ -1098,7 +1101,7 @@ static void
|
||||
iwl_mvm_handle_rx_statistics_tlv(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
u8 average_energy[IWL_MVM_STATION_COUNT_MAX];
|
||||
u8 average_energy[IWL_STATION_COUNT_MAX];
|
||||
__le32 air_time[MAC_INDEX_AUX];
|
||||
__le32 rx_bytes[MAC_INDEX_AUX];
|
||||
__le32 flags = 0;
|
||||
|
||||
@@ -729,8 +729,6 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
|
||||
bool last_subframe =
|
||||
desc->amsdu_info & IWL_RX_MPDU_AMSDU_LAST_SUBFRAME;
|
||||
u8 tid = ieee80211_get_tid(hdr);
|
||||
u8 sub_frame_idx = desc->amsdu_info &
|
||||
IWL_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK;
|
||||
struct iwl_mvm_reorder_buf_entry *entries;
|
||||
u32 sta_mask;
|
||||
int index;
|
||||
@@ -843,10 +841,8 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
|
||||
__skb_queue_tail(&entries[index].frames, skb);
|
||||
buffer->num_stored++;
|
||||
|
||||
if (amsdu) {
|
||||
if (amsdu)
|
||||
buffer->last_amsdu = sn;
|
||||
buffer->last_sub_index = sub_frame_idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* We cannot trust NSSN for AMSDU sub-frames that are not the last.
|
||||
@@ -2542,7 +2538,7 @@ void iwl_mvm_rx_bar_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (WARN(tid != baid_data->tid || sta_id > IWL_MVM_STATION_COUNT_MAX ||
|
||||
if (WARN(tid != baid_data->tid || sta_id > IWL_STATION_COUNT_MAX ||
|
||||
!(baid_data->sta_mask & BIT(sta_id)),
|
||||
"baid 0x%x is mapped to sta_mask:0x%x tid:%d, but BAR release received for sta:%d tid:%d\n",
|
||||
baid, baid_data->sta_mask, baid_data->tid, sta_id,
|
||||
|
||||
@@ -1594,7 +1594,7 @@ iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm,
|
||||
|
||||
for (i = 0; i < n_channels; i++) {
|
||||
channel_cfg[i].flags = cpu_to_le32(flags);
|
||||
channel_cfg[i].v1.channel_num = channels[i]->hw_value;
|
||||
channel_cfg[i].channel_num = channels[i]->hw_value;
|
||||
if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
|
||||
enum nl80211_band band = channels[i]->band;
|
||||
|
||||
@@ -1626,13 +1626,13 @@ iwl_mvm_umac_scan_cfg_channels_v4(struct iwl_mvm *mvm,
|
||||
&cp->channel_config[i];
|
||||
|
||||
cfg->flags = cpu_to_le32(flags);
|
||||
cfg->v2.channel_num = channels[i]->hw_value;
|
||||
cfg->channel_num = channels[i]->hw_value;
|
||||
cfg->v2.band = iwl_mvm_phy_band_from_nl80211(band);
|
||||
cfg->v2.iter_count = 1;
|
||||
cfg->v2.iter_interval = 0;
|
||||
|
||||
iwl_mvm_scan_ch_add_n_aps_override(vif_type,
|
||||
cfg->v2.channel_num,
|
||||
cfg->channel_num,
|
||||
cfg->v2.band, bitmap,
|
||||
bitmap_n_entries);
|
||||
}
|
||||
@@ -1656,7 +1656,7 @@ iwl_mvm_umac_scan_cfg_channels_v7(struct iwl_mvm *mvm,
|
||||
u8 iwl_band = iwl_mvm_phy_band_from_nl80211(band);
|
||||
|
||||
cfg->flags = cpu_to_le32(flags | n_aps_flag);
|
||||
cfg->v2.channel_num = channels[i]->hw_value;
|
||||
cfg->channel_num = channels[i]->hw_value;
|
||||
if (cfg80211_channel_is_psc(channels[i]))
|
||||
cfg->flags = 0;
|
||||
|
||||
@@ -1789,7 +1789,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
|
||||
!params->n_6ghz_params && params->n_ssids)
|
||||
continue;
|
||||
|
||||
cfg->v1.channel_num = params->channels[i]->hw_value;
|
||||
cfg->channel_num = params->channels[i]->hw_value;
|
||||
if (version < 17)
|
||||
cfg->v2.band = PHY_BAND_6;
|
||||
else
|
||||
@@ -2477,7 +2477,7 @@ iwl_mvm_scan_umac_fill_ch_p_v7(struct iwl_mvm *mvm,
|
||||
if (!cfg80211_channel_is_psc(channel))
|
||||
continue;
|
||||
|
||||
cfg->v5.channel_num = channel->hw_value;
|
||||
cfg->channel_num = channel->hw_value;
|
||||
cfg->v5.iter_count = 1;
|
||||
cfg->v5.iter_interval = 0;
|
||||
|
||||
@@ -3313,13 +3313,23 @@ void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
|
||||
mvm->scan_start);
|
||||
}
|
||||
|
||||
static int iwl_mvm_umac_scan_abort(struct iwl_mvm *mvm, int type)
|
||||
static int iwl_mvm_umac_scan_abort(struct iwl_mvm *mvm, int type, bool *wait)
|
||||
{
|
||||
struct iwl_umac_scan_abort cmd = {};
|
||||
struct iwl_umac_scan_abort abort_cmd = {};
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = WIDE_ID(IWL_ALWAYS_LONG_GROUP, SCAN_ABORT_UMAC),
|
||||
.len = { sizeof(abort_cmd), },
|
||||
.data = { &abort_cmd, },
|
||||
.flags = CMD_SEND_IN_RFKILL,
|
||||
};
|
||||
|
||||
int uid, ret;
|
||||
u32 status = IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
*wait = true;
|
||||
|
||||
/* We should always get a valid index here, because we already
|
||||
* checked that this type of scan was running in the generic
|
||||
* code.
|
||||
@@ -3328,17 +3338,28 @@ static int iwl_mvm_umac_scan_abort(struct iwl_mvm *mvm, int type)
|
||||
if (WARN_ON_ONCE(uid < 0))
|
||||
return uid;
|
||||
|
||||
cmd.uid = cpu_to_le32(uid);
|
||||
abort_cmd.uid = cpu_to_le32(uid);
|
||||
|
||||
IWL_DEBUG_SCAN(mvm, "Sending scan abort, uid %u\n", uid);
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm,
|
||||
WIDE_ID(IWL_ALWAYS_LONG_GROUP, SCAN_ABORT_UMAC),
|
||||
CMD_SEND_IN_RFKILL, sizeof(cmd), &cmd);
|
||||
ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
|
||||
|
||||
IWL_DEBUG_SCAN(mvm, "Scan abort: ret=%d, status=%u\n", ret, status);
|
||||
if (!ret)
|
||||
mvm->scan_uid_status[uid] = type << IWL_MVM_SCAN_STOPPING_SHIFT;
|
||||
|
||||
IWL_DEBUG_SCAN(mvm, "Scan abort: ret=%d\n", ret);
|
||||
/* Handle the case that the FW is no longer familiar with the scan that
|
||||
* is to be stopped. In such a case, it is expected that the scan
|
||||
* complete notification was already received but not yet processed.
|
||||
* In such a case, there is no need to wait for a scan complete
|
||||
* notification and the flow should continue similar to the case that
|
||||
* the scan was really aborted.
|
||||
*/
|
||||
if (status == IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND) {
|
||||
mvm->scan_uid_status[uid] = type << IWL_MVM_SCAN_STOPPING_SHIFT;
|
||||
*wait = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3348,6 +3369,7 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
|
||||
static const u16 scan_done_notif[] = { SCAN_COMPLETE_UMAC,
|
||||
SCAN_OFFLOAD_COMPLETE, };
|
||||
int ret;
|
||||
bool wait = true;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
@@ -3359,7 +3381,7 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
|
||||
IWL_DEBUG_SCAN(mvm, "Preparing to stop scan, type %x\n", type);
|
||||
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN))
|
||||
ret = iwl_mvm_umac_scan_abort(mvm, type);
|
||||
ret = iwl_mvm_umac_scan_abort(mvm, type, &wait);
|
||||
else
|
||||
ret = iwl_mvm_lmac_scan_abort(mvm);
|
||||
|
||||
@@ -3367,6 +3389,10 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
|
||||
IWL_DEBUG_SCAN(mvm, "couldn't stop scan type %d\n", type);
|
||||
iwl_remove_notification(&mvm->notif_wait, &wait_scan_done);
|
||||
return ret;
|
||||
} else if (!wait) {
|
||||
IWL_DEBUG_SCAN(mvm, "no need to wait for scan type %d\n", type);
|
||||
iwl_remove_notification(&mvm->notif_wait, &wait_scan_done);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return iwl_wait_notification(&mvm->notif_wait, &wait_scan_done,
|
||||
|
||||
@@ -29,7 +29,7 @@ int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm, enum nl80211_iftype iftype)
|
||||
int sta_id;
|
||||
u32 reserved_ids = 0;
|
||||
|
||||
BUILD_BUG_ON(IWL_MVM_STATION_COUNT_MAX > 32);
|
||||
BUILD_BUG_ON(IWL_STATION_COUNT_MAX > 32);
|
||||
WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status));
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
@@ -900,7 +900,7 @@ static int iwl_mvm_sta_alloc_queue_tvqm(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_txq *mvmtxq =
|
||||
iwl_mvm_txq_from_tid(sta, tid);
|
||||
unsigned int wdg_timeout =
|
||||
iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false);
|
||||
iwl_mvm_get_wd_timeout(mvm, mvmsta->vif);
|
||||
int queue = -1;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
@@ -1080,7 +1080,7 @@ static void iwl_mvm_unshare_queue(struct iwl_mvm *mvm, int queue)
|
||||
return;
|
||||
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
wdg_timeout = iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false);
|
||||
wdg_timeout = iwl_mvm_get_wd_timeout(mvm, mvmsta->vif);
|
||||
|
||||
ssn = IEEE80211_SEQ_TO_SN(mvmsta->tid_data[tid].seq_number);
|
||||
|
||||
@@ -1330,7 +1330,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
|
||||
.frame_limit = IWL_FRAME_LIMIT,
|
||||
};
|
||||
unsigned int wdg_timeout =
|
||||
iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false);
|
||||
iwl_mvm_get_wd_timeout(mvm, mvmsta->vif);
|
||||
int queue = -1;
|
||||
u16 queue_tmp;
|
||||
unsigned long disable_agg_tids = 0;
|
||||
@@ -1622,7 +1622,7 @@ void iwl_mvm_realloc_queues_after_restart(struct iwl_mvm *mvm,
|
||||
{
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
unsigned int wdg =
|
||||
iwl_mvm_get_wd_timeout(mvm, mvm_sta->vif, false, false);
|
||||
iwl_mvm_get_wd_timeout(mvm, mvm_sta->vif);
|
||||
int i;
|
||||
struct iwl_trans_txq_scd_cfg cfg = {
|
||||
.sta_id = mvm_sta->deflink.sta_id,
|
||||
@@ -2359,7 +2359,7 @@ int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
int queue;
|
||||
int ret;
|
||||
unsigned int wdg_timeout =
|
||||
iwl_mvm_get_wd_timeout(mvm, vif, false, false);
|
||||
iwl_mvm_get_wd_timeout(mvm, vif);
|
||||
struct iwl_trans_txq_scd_cfg cfg = {
|
||||
.fifo = IWL_MVM_TX_FIFO_VO,
|
||||
.sta_id = mvmvif->deflink.bcast_sta.sta_id,
|
||||
@@ -2568,7 +2568,7 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
.aggregate = false,
|
||||
.frame_limit = IWL_FRAME_LIMIT,
|
||||
};
|
||||
unsigned int timeout = iwl_mvm_get_wd_timeout(mvm, vif, false, false);
|
||||
unsigned int timeout = iwl_mvm_get_wd_timeout(mvm, vif);
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
@@ -3207,7 +3207,7 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
|
||||
unsigned int wdg_timeout =
|
||||
iwl_mvm_get_wd_timeout(mvm, vif, sta->tdls, false);
|
||||
iwl_mvm_get_wd_timeout(mvm, vif);
|
||||
int queue, ret;
|
||||
bool alloc_queue = true;
|
||||
enum iwl_mvm_queue_status queue_status;
|
||||
@@ -4326,7 +4326,7 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
u16 queue;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
unsigned int wdg_timeout =
|
||||
iwl_mvm_get_wd_timeout(mvm, vif, false, false);
|
||||
iwl_mvm_get_wd_timeout(mvm, vif);
|
||||
bool mld = iwl_mvm_has_mld_api(mvm->fw);
|
||||
u32 type = mld ? STATION_TYPE_PEER : IWL_STA_LINK;
|
||||
|
||||
@@ -4455,10 +4455,10 @@ void iwl_mvm_count_mpdu(struct iwl_mvm_sta *mvm_sta, u8 fw_sta_id, u32 count,
|
||||
sizeof(queue_counter->per_link));
|
||||
queue_counter->window_start = jiffies;
|
||||
|
||||
IWL_DEBUG_STATS(mvm, "MPDU counters are cleared\n");
|
||||
IWL_DEBUG_INFO(mvm, "MPDU counters are cleared\n");
|
||||
}
|
||||
|
||||
for (int i = 0; i < IWL_MVM_FW_MAX_LINK_ID; i++)
|
||||
for (int i = 0; i < IWL_FW_MAX_LINK_ID; i++)
|
||||
total_mpdus += tx ? queue_counter->per_link[i].tx :
|
||||
queue_counter->per_link[i].rx;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include "iwl-trans.h" /* for IWL_MAX_TID_COUNT */
|
||||
#include "fw-api.h" /* IWL_MVM_STATION_COUNT_MAX */
|
||||
#include "fw-api.h" /* IWL_STATION_COUNT_MAX */
|
||||
#include "rs.h"
|
||||
|
||||
struct iwl_mvm;
|
||||
@@ -361,7 +361,7 @@ struct iwl_mvm_mpdu_counter {
|
||||
*/
|
||||
struct iwl_mvm_tpt_counter {
|
||||
spinlock_t lock;
|
||||
struct iwl_mvm_mpdu_counter per_link[IWL_MVM_FW_MAX_LINK_ID];
|
||||
struct iwl_mvm_mpdu_counter per_link[IWL_FW_MAX_LINK_ID];
|
||||
unsigned long window_start;
|
||||
} ____cacheline_aligned_in_smp;
|
||||
|
||||
|
||||
@@ -114,16 +114,14 @@ static void iwl_mvm_cleanup_roc(struct iwl_mvm *mvm)
|
||||
iwl_mvm_flush_sta(mvm, mvm->aux_sta.sta_id,
|
||||
mvm->aux_sta.tfd_queue_msk);
|
||||
|
||||
if (mvm->mld_api_is_used) {
|
||||
iwl_mvm_mld_rm_aux_sta(mvm);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
/* In newer version of this command an aux station is added only
|
||||
* in cases of dedicated tx queue and need to be removed in end
|
||||
* of use */
|
||||
if (iwl_mvm_has_new_station_api(mvm->fw))
|
||||
* of use. For the even newer mld api, use the appropriate
|
||||
* function.
|
||||
*/
|
||||
if (mvm->mld_api_is_used)
|
||||
iwl_mvm_mld_rm_aux_sta(mvm);
|
||||
else if (iwl_mvm_has_new_station_api(mvm->fw))
|
||||
iwl_mvm_rm_aux_sta(mvm);
|
||||
}
|
||||
|
||||
|
||||
@@ -1203,6 +1203,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
bool is_ampdu = false;
|
||||
int hdrlen;
|
||||
|
||||
if (WARN_ON_ONCE(!sta))
|
||||
return -1;
|
||||
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
fc = hdr->frame_control;
|
||||
hdrlen = ieee80211_hdrlen(fc);
|
||||
@@ -1210,9 +1213,6 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
if (IWL_MVM_NON_TRANSMITTING_AP && ieee80211_is_probe_resp(fc))
|
||||
return -1;
|
||||
|
||||
if (WARN_ON_ONCE(!mvmsta))
|
||||
return -1;
|
||||
|
||||
if (WARN_ON_ONCE(mvmsta->deflink.sta_id == IWL_MVM_INVALID_STA))
|
||||
return -1;
|
||||
|
||||
@@ -1343,7 +1343,7 @@ drop:
|
||||
int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
struct ieee80211_tx_info info;
|
||||
struct sk_buff_head mpdus_skbs;
|
||||
struct ieee80211_vif *vif;
|
||||
@@ -1352,9 +1352,11 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct sk_buff *orig_skb = skb;
|
||||
const u8 *addr3;
|
||||
|
||||
if (WARN_ON_ONCE(!mvmsta))
|
||||
if (WARN_ON_ONCE(!sta))
|
||||
return -1;
|
||||
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
if (WARN_ON_ONCE(mvmsta->deflink.sta_id == IWL_MVM_INVALID_STA))
|
||||
return -1;
|
||||
|
||||
@@ -1678,7 +1680,7 @@ static void iwl_mvm_tx_status_check_trigger(struct iwl_mvm *mvm,
|
||||
* For 22000-series and lower, this is just 12 bits. For later, 16 bits.
|
||||
*/
|
||||
static inline u32 iwl_mvm_get_scd_ssn(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_tx_resp *tx_resp)
|
||||
struct iwl_tx_resp *tx_resp)
|
||||
{
|
||||
u32 val = le32_to_cpup((__le32 *)iwl_mvm_get_agg_status(mvm, tx_resp) +
|
||||
tx_resp->frame_count);
|
||||
@@ -1694,8 +1696,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *sta;
|
||||
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
|
||||
int txq_id = SEQ_TO_QUEUE(sequence);
|
||||
/* struct iwl_mvm_tx_resp_v3 is almost the same */
|
||||
struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
|
||||
/* struct iwl_tx_resp_v3 is almost the same */
|
||||
struct iwl_tx_resp *tx_resp = (void *)pkt->data;
|
||||
int sta_id = IWL_MVM_TX_RES_GET_RA(tx_resp->ra_tid);
|
||||
int tid = IWL_MVM_TX_RES_GET_TID(tx_resp->ra_tid);
|
||||
struct agg_tx_status *agg_status =
|
||||
@@ -1952,7 +1954,7 @@ static const char *iwl_get_agg_tx_status(u16 status)
|
||||
static void iwl_mvm_rx_tx_cmd_agg_dbg(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
|
||||
struct iwl_tx_resp *tx_resp = (void *)pkt->data;
|
||||
struct agg_tx_status *frame_status =
|
||||
iwl_mvm_get_agg_status(mvm, tx_resp);
|
||||
int i;
|
||||
@@ -1986,7 +1988,7 @@ static void iwl_mvm_rx_tx_cmd_agg_dbg(struct iwl_mvm *mvm,
|
||||
static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
|
||||
struct iwl_tx_resp *tx_resp = (void *)pkt->data;
|
||||
int sta_id = IWL_MVM_TX_RES_GET_RA(tx_resp->ra_tid);
|
||||
int tid = IWL_MVM_TX_RES_GET_TID(tx_resp->ra_tid);
|
||||
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
|
||||
@@ -2027,7 +2029,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
|
||||
void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
|
||||
struct iwl_tx_resp *tx_resp = (void *)pkt->data;
|
||||
|
||||
if (tx_resp->frame_count == 1)
|
||||
iwl_mvm_rx_tx_cmd_single(mvm, pkt);
|
||||
|
||||
@@ -297,6 +297,10 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
if (vif->type != NL80211_IFTYPE_STATION)
|
||||
return;
|
||||
|
||||
/* SMPS is handled by firmware */
|
||||
if (iwl_mvm_has_rlc_offload(mvm))
|
||||
return;
|
||||
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
if (WARN_ON_ONCE(!mvmvif->link[link_id]))
|
||||
@@ -743,58 +747,20 @@ bool iwl_mvm_is_vif_assoc(struct iwl_mvm *mvm)
|
||||
}
|
||||
|
||||
unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool tdls, bool cmd_q)
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger;
|
||||
struct iwl_fw_dbg_trigger_txq_timer *txq_timer;
|
||||
unsigned int default_timeout = cmd_q ?
|
||||
IWL_DEF_WD_TIMEOUT :
|
||||
unsigned int default_timeout =
|
||||
mvm->trans->trans_cfg->base_params->wd_timeout;
|
||||
|
||||
if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS)) {
|
||||
/*
|
||||
* We can't know when the station is asleep or awake, so we
|
||||
* must disable the queue hang detection.
|
||||
*/
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_STA_PM_NOTIF) &&
|
||||
vif && vif->type == NL80211_IFTYPE_AP)
|
||||
return IWL_WATCHDOG_DISABLED;
|
||||
return default_timeout;
|
||||
}
|
||||
|
||||
trigger = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS);
|
||||
txq_timer = (void *)trigger->data;
|
||||
|
||||
if (tdls)
|
||||
return le32_to_cpu(txq_timer->tdls);
|
||||
|
||||
if (cmd_q)
|
||||
return le32_to_cpu(txq_timer->command_queue);
|
||||
|
||||
if (WARN_ON(!vif))
|
||||
return default_timeout;
|
||||
|
||||
switch (ieee80211_vif_type_p2p(vif)) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
return le32_to_cpu(txq_timer->ibss);
|
||||
case NL80211_IFTYPE_STATION:
|
||||
return le32_to_cpu(txq_timer->bss);
|
||||
case NL80211_IFTYPE_AP:
|
||||
return le32_to_cpu(txq_timer->softap);
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
return le32_to_cpu(txq_timer->p2p_client);
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
return le32_to_cpu(txq_timer->p2p_go);
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
return le32_to_cpu(txq_timer->p2p_device);
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
return default_timeout;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return mvm->trans->trans_cfg->base_params->wd_timeout;
|
||||
}
|
||||
/*
|
||||
* We can't know when the station is asleep or awake, so we
|
||||
* must disable the queue hang detection.
|
||||
*/
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_STA_PM_NOTIF) &&
|
||||
vif->type == NL80211_IFTYPE_AP)
|
||||
return IWL_WATCHDOG_DISABLED;
|
||||
return default_timeout;
|
||||
}
|
||||
|
||||
void iwl_mvm_connection_loss(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
|
||||
@@ -500,9 +500,7 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = {
|
||||
{IWL_PCI_DEVICE(0x7E40, PCI_ANY_ID, iwl_ma_trans_cfg)},
|
||||
|
||||
/* Bz devices */
|
||||
{IWL_PCI_DEVICE(0x2727, PCI_ANY_ID, iwl_bz_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0x272D, PCI_ANY_ID, iwl_bz_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0x272b, PCI_ANY_ID, iwl_bz_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0x272b, PCI_ANY_ID, iwl_gl_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0xA840, 0x0000, iwl_bz_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0xA840, 0x0090, iwl_bz_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0xA840, 0x0094, iwl_bz_trans_cfg)},
|
||||
|
||||
@@ -526,6 +526,8 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
|
||||
keep_ram_busy = !iwl_pcie_set_ltr(trans);
|
||||
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
|
||||
IWL_DEBUG_POWER(trans, "function scratch register value is 0x%08x\n",
|
||||
iwl_read32(trans, CSR_FUNC_SCRATCH));
|
||||
iwl_write32(trans, CSR_FUNC_SCRATCH, CSR_FUNC_SCRATCH_INIT_VALUE);
|
||||
iwl_set_bit(trans, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_ROM_START);
|
||||
|
||||
@@ -1967,7 +1967,6 @@ void iwl_trans_pcie_configure(struct iwl_trans *trans,
|
||||
|
||||
trans_pcie->txqs.cmd.q_id = trans_cfg->cmd_queue;
|
||||
trans_pcie->txqs.cmd.fifo = trans_cfg->cmd_fifo;
|
||||
trans_pcie->txqs.cmd.wdg_timeout = trans_cfg->cmd_q_wdg_timeout;
|
||||
trans_pcie->txqs.page_offs = trans_cfg->cb_data_offs;
|
||||
trans_pcie->txqs.dev_cmd_offs = trans_cfg->cb_data_offs + sizeof(void *);
|
||||
trans_pcie->txqs.queue_alloc_cmd_ver = trans_cfg->queue_alloc_cmd_ver;
|
||||
@@ -3567,6 +3566,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
}
|
||||
trans->max_skb_frags = IWL_TRANS_PCIE_MAX_FRAGS(trans_pcie);
|
||||
|
||||
/* Set a short watchdog for the command queue */
|
||||
trans_pcie->txqs.cmd.wdg_timeout = IWL_DEF_WD_TIMEOUT;
|
||||
|
||||
trans_pcie->txqs.tso_hdr_page = alloc_percpu(struct iwl_tso_hdr_page);
|
||||
if (!trans_pcie->txqs.tso_hdr_page) {
|
||||
ret = -ENOMEM;
|
||||
|
||||
@@ -881,8 +881,6 @@ void mwifiex_update_ampdu_txwinsize(struct mwifiex_adapter *adapter)
|
||||
struct mwifiex_private *priv;
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (!adapter->priv[i])
|
||||
continue;
|
||||
priv = adapter->priv[i];
|
||||
tx_win_size = priv->add_ba_param.tx_win_size;
|
||||
|
||||
|
||||
@@ -108,9 +108,7 @@ static inline u8 mwifiex_space_avail_for_new_ba_stream(
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (priv)
|
||||
ba_stream_num += list_count_nodes(
|
||||
&priv->tx_ba_stream_tbl_ptr);
|
||||
ba_stream_num += list_count_nodes(&priv->tx_ba_stream_tbl_ptr);
|
||||
}
|
||||
|
||||
if (adapter->fw_api_ver == MWIFIEX_FW_V15) {
|
||||
|
||||
@@ -810,8 +810,6 @@ void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (!priv)
|
||||
continue;
|
||||
|
||||
spin_lock_bh(&priv->rx_reorder_tbl_lock);
|
||||
list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list)
|
||||
@@ -834,8 +832,6 @@ static void mwifiex_update_ampdu_rxwinsize(struct mwifiex_adapter *adapter,
|
||||
dev_dbg(adapter->dev, "Update rxwinsize %d\n", coex_flag);
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (!adapter->priv[i])
|
||||
continue;
|
||||
priv = adapter->priv[i];
|
||||
rx_win_size = priv->add_ba_param.rx_win_size;
|
||||
if (coex_flag) {
|
||||
@@ -882,17 +878,16 @@ void mwifiex_coex_ampdu_rxwinsize(struct mwifiex_adapter *adapter)
|
||||
u8 count = 0;
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (adapter->priv[i]) {
|
||||
priv = adapter->priv[i];
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
|
||||
if (priv->media_connected)
|
||||
count++;
|
||||
}
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
|
||||
if (priv->bss_started)
|
||||
count++;
|
||||
}
|
||||
priv = adapter->priv[i];
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
|
||||
if (priv->media_connected)
|
||||
count++;
|
||||
}
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
|
||||
if (priv->bss_started)
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count >= MWIFIEX_BSS_COEX_COUNT)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -221,6 +221,26 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
|
||||
if (ieee80211_is_auth(mgmt->frame_control))
|
||||
mwifiex_dbg(priv->adapter, MSG,
|
||||
"auth: send auth to %pM\n", mgmt->da);
|
||||
if (ieee80211_is_deauth(mgmt->frame_control))
|
||||
mwifiex_dbg(priv->adapter, MSG,
|
||||
"auth: send deauth to %pM\n", mgmt->da);
|
||||
if (ieee80211_is_disassoc(mgmt->frame_control))
|
||||
mwifiex_dbg(priv->adapter, MSG,
|
||||
"assoc: send disassoc to %pM\n", mgmt->da);
|
||||
if (ieee80211_is_assoc_resp(mgmt->frame_control))
|
||||
mwifiex_dbg(priv->adapter, MSG,
|
||||
"assoc: send assoc resp to %pM\n",
|
||||
mgmt->da);
|
||||
if (ieee80211_is_reassoc_resp(mgmt->frame_control))
|
||||
mwifiex_dbg(priv->adapter, MSG,
|
||||
"assoc: send reassoc resp to %pM\n",
|
||||
mgmt->da);
|
||||
}
|
||||
|
||||
pkt_len = len + ETH_ALEN;
|
||||
skb = dev_alloc_skb(MWIFIEX_MIN_DATA_HEADER_LEN +
|
||||
MWIFIEX_MGMT_FRAME_HEADER_SIZE +
|
||||
@@ -268,6 +288,8 @@ mwifiex_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
|
||||
|
||||
if (mask != priv->mgmt_frame_mask) {
|
||||
priv->mgmt_frame_mask = mask;
|
||||
if (priv->host_mlme_reg)
|
||||
priv->mgmt_frame_mask |= HOST_MLME_MGMT_MASK;
|
||||
mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
|
||||
HostCmd_ACT_GEN_SET, 0,
|
||||
&priv->mgmt_frame_mask, false);
|
||||
@@ -503,6 +525,9 @@ mwifiex_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
|
||||
|
||||
wiphy_dbg(wiphy, "set default mgmt key, key index=%d\n", key_index);
|
||||
|
||||
if (priv->adapter->host_mlme_enabled)
|
||||
return 0;
|
||||
|
||||
memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key));
|
||||
encrypt_key.key_len = WLAN_KEY_LEN_CCMP;
|
||||
encrypt_key.key_index = key_index;
|
||||
@@ -848,6 +873,7 @@ static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
unsigned long flags;
|
||||
|
||||
priv->host_mlme_reg = false;
|
||||
priv->mgmt_frame_mask = 0;
|
||||
if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
|
||||
HostCmd_ACT_GEN_SET, 0,
|
||||
@@ -3482,7 +3508,7 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (priv && priv->netdev)
|
||||
if (priv->netdev)
|
||||
netif_device_detach(priv->netdev);
|
||||
}
|
||||
|
||||
@@ -3554,7 +3580,7 @@ static int mwifiex_cfg80211_resume(struct wiphy *wiphy)
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (priv && priv->netdev)
|
||||
if (priv->netdev)
|
||||
netif_device_attach(priv->netdev);
|
||||
}
|
||||
|
||||
@@ -3633,6 +3659,9 @@ static int mwifiex_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
|
||||
if (!ISSUPP_FIRMWARE_SUPPLICANT(priv->adapter->fw_cap_info))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (priv->adapter->host_mlme_enabled)
|
||||
return 0;
|
||||
|
||||
return mwifiex_send_cmd(priv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG,
|
||||
HostCmd_ACT_GEN_SET, 0, data, true);
|
||||
}
|
||||
@@ -3947,12 +3976,43 @@ mwifiex_cfg80211_tdls_cancel_chan_switch(struct wiphy *wiphy,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
mwifiex_cfg80211_uap_add_station(struct mwifiex_private *priv, const u8 *mac,
|
||||
struct station_parameters *params)
|
||||
{
|
||||
struct mwifiex_sta_info add_sta;
|
||||
int ret;
|
||||
|
||||
memcpy(add_sta.peer_mac, mac, ETH_ALEN);
|
||||
add_sta.params = params;
|
||||
|
||||
ret = mwifiex_send_cmd(priv, HostCmd_CMD_ADD_NEW_STATION,
|
||||
HostCmd_ACT_ADD_STA, 0, (void *)&add_sta, true);
|
||||
|
||||
if (!ret) {
|
||||
struct station_info *sinfo;
|
||||
|
||||
sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
|
||||
if (!sinfo)
|
||||
return -ENOMEM;
|
||||
|
||||
cfg80211_new_sta(priv->netdev, mac, sinfo, GFP_KERNEL);
|
||||
kfree(sinfo);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *mac, struct station_parameters *params)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
|
||||
if (priv->adapter->host_mlme_enabled &&
|
||||
(GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP))
|
||||
return mwifiex_cfg80211_uap_add_station(priv, mac, params);
|
||||
|
||||
if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -4190,6 +4250,10 @@ mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
int ret;
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
|
||||
if (priv->adapter->host_mlme_enabled &&
|
||||
(GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP))
|
||||
return 0;
|
||||
|
||||
/* we support change_station handler only for TDLS peers*/
|
||||
if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
|
||||
return -EOPNOTSUPP;
|
||||
@@ -4206,8 +4270,307 @@ mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mwifiex_cfg80211_authenticate(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_auth_request *req)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
struct sk_buff *skb;
|
||||
u16 pkt_len, auth_alg;
|
||||
int ret;
|
||||
struct mwifiex_ieee80211_mgmt *mgmt;
|
||||
struct mwifiex_txinfo *tx_info;
|
||||
u32 tx_control = 0, pkt_type = PKT_TYPE_MGMT;
|
||||
u8 trans = 1, status_code = 0;
|
||||
u8 *varptr = NULL;
|
||||
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
|
||||
mwifiex_dbg(priv->adapter, ERROR, "Interface role is AP\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (priv->wdev.iftype != NL80211_IFTYPE_STATION) {
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"Interface type is not correct (type %d)\n",
|
||||
priv->wdev.iftype);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (priv->auth_alg != WLAN_AUTH_SAE &&
|
||||
(priv->auth_flag & HOST_MLME_AUTH_PENDING)) {
|
||||
mwifiex_dbg(priv->adapter, ERROR, "Pending auth on going\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (!priv->host_mlme_reg) {
|
||||
priv->host_mlme_reg = true;
|
||||
priv->mgmt_frame_mask |= HOST_MLME_MGMT_MASK;
|
||||
mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
|
||||
HostCmd_ACT_GEN_SET, 0,
|
||||
&priv->mgmt_frame_mask, false);
|
||||
}
|
||||
|
||||
switch (req->auth_type) {
|
||||
case NL80211_AUTHTYPE_OPEN_SYSTEM:
|
||||
auth_alg = WLAN_AUTH_OPEN;
|
||||
break;
|
||||
case NL80211_AUTHTYPE_SHARED_KEY:
|
||||
auth_alg = WLAN_AUTH_SHARED_KEY;
|
||||
break;
|
||||
case NL80211_AUTHTYPE_FT:
|
||||
auth_alg = WLAN_AUTH_FT;
|
||||
break;
|
||||
case NL80211_AUTHTYPE_NETWORK_EAP:
|
||||
auth_alg = WLAN_AUTH_LEAP;
|
||||
break;
|
||||
case NL80211_AUTHTYPE_SAE:
|
||||
auth_alg = WLAN_AUTH_SAE;
|
||||
break;
|
||||
default:
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"unsupported auth type=%d\n", req->auth_type);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (!priv->auth_flag) {
|
||||
ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET,
|
||||
req->bss->channel,
|
||||
AUTH_TX_DEFAULT_WAIT_TIME);
|
||||
|
||||
if (!ret) {
|
||||
priv->roc_cfg.cookie = get_random_u32() | 1;
|
||||
priv->roc_cfg.chan = *req->bss->channel;
|
||||
} else {
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
priv->sec_info.authentication_mode = auth_alg;
|
||||
|
||||
mwifiex_cancel_scan(adapter);
|
||||
|
||||
pkt_len = (u16)req->ie_len + req->auth_data_len +
|
||||
MWIFIEX_MGMT_HEADER_LEN + MWIFIEX_AUTH_BODY_LEN;
|
||||
if (req->auth_data_len >= 4)
|
||||
pkt_len -= 4;
|
||||
|
||||
skb = dev_alloc_skb(MWIFIEX_MIN_DATA_HEADER_LEN +
|
||||
MWIFIEX_MGMT_FRAME_HEADER_SIZE +
|
||||
pkt_len + sizeof(pkt_len));
|
||||
if (!skb) {
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"allocate skb failed for management frame\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||
memset(tx_info, 0, sizeof(*tx_info));
|
||||
tx_info->bss_num = priv->bss_num;
|
||||
tx_info->bss_type = priv->bss_type;
|
||||
tx_info->pkt_len = pkt_len;
|
||||
|
||||
skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN +
|
||||
MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
|
||||
memcpy(skb_push(skb, sizeof(pkt_len)), &pkt_len, sizeof(pkt_len));
|
||||
memcpy(skb_push(skb, sizeof(tx_control)),
|
||||
&tx_control, sizeof(tx_control));
|
||||
memcpy(skb_push(skb, sizeof(pkt_type)), &pkt_type, sizeof(pkt_type));
|
||||
|
||||
mgmt = (struct mwifiex_ieee80211_mgmt *)skb_put(skb, pkt_len);
|
||||
memset(mgmt, 0, pkt_len);
|
||||
mgmt->frame_control =
|
||||
cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
|
||||
memcpy(mgmt->da, req->bss->bssid, ETH_ALEN);
|
||||
memcpy(mgmt->sa, priv->curr_addr, ETH_ALEN);
|
||||
memcpy(mgmt->bssid, req->bss->bssid, ETH_ALEN);
|
||||
eth_broadcast_addr(mgmt->addr4);
|
||||
|
||||
if (req->auth_data_len >= 4) {
|
||||
if (req->auth_type == NL80211_AUTHTYPE_SAE) {
|
||||
__le16 *pos = (__le16 *)req->auth_data;
|
||||
|
||||
trans = le16_to_cpu(pos[0]);
|
||||
status_code = le16_to_cpu(pos[1]);
|
||||
}
|
||||
memcpy((u8 *)(&mgmt->auth.variable), req->auth_data + 4,
|
||||
req->auth_data_len - 4);
|
||||
varptr = (u8 *)&mgmt->auth.variable +
|
||||
(req->auth_data_len - 4);
|
||||
}
|
||||
|
||||
mgmt->auth.auth_alg = cpu_to_le16(auth_alg);
|
||||
mgmt->auth.auth_transaction = cpu_to_le16(trans);
|
||||
mgmt->auth.status_code = cpu_to_le16(status_code);
|
||||
|
||||
if (req->ie && req->ie_len) {
|
||||
if (!varptr)
|
||||
varptr = (u8 *)&mgmt->auth.variable;
|
||||
memcpy((u8 *)varptr, req->ie, req->ie_len);
|
||||
}
|
||||
|
||||
priv->auth_flag = HOST_MLME_AUTH_PENDING;
|
||||
priv->auth_alg = auth_alg;
|
||||
|
||||
skb->priority = WMM_HIGHEST_PRIORITY;
|
||||
__net_timestamp(skb);
|
||||
|
||||
mwifiex_dbg(priv->adapter, MSG,
|
||||
"auth: send authentication to %pM\n", req->bss->bssid);
|
||||
|
||||
mwifiex_queue_tx_pkt(priv, skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mwifiex_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_assoc_request *req)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
int ret;
|
||||
struct cfg80211_ssid req_ssid;
|
||||
const u8 *ssid_ie;
|
||||
|
||||
if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"%s: reject infra assoc request in non-STA role\n",
|
||||
dev->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags) ||
|
||||
test_bit(MWIFIEX_IS_CMD_TIMEDOUT, &adapter->work_flags)) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"%s: Ignore association.\t"
|
||||
"Card removed or FW in bad state\n",
|
||||
dev->name);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (priv->auth_alg == WLAN_AUTH_SAE)
|
||||
priv->auth_flag = HOST_MLME_AUTH_DONE;
|
||||
|
||||
if (priv->auth_flag && !(priv->auth_flag & HOST_MLME_AUTH_DONE))
|
||||
return -EBUSY;
|
||||
|
||||
if (priv->roc_cfg.cookie) {
|
||||
ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE,
|
||||
&priv->roc_cfg.chan, 0);
|
||||
if (!ret)
|
||||
memset(&priv->roc_cfg, 0,
|
||||
sizeof(struct mwifiex_roc_cfg));
|
||||
else
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (!mwifiex_stop_bg_scan(priv))
|
||||
cfg80211_sched_scan_stopped_locked(priv->wdev.wiphy, 0);
|
||||
|
||||
memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
|
||||
rcu_read_lock();
|
||||
ssid_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
|
||||
|
||||
if (!ssid_ie)
|
||||
goto ssid_err;
|
||||
|
||||
req_ssid.ssid_len = ssid_ie[1];
|
||||
if (req_ssid.ssid_len > IEEE80211_MAX_SSID_LEN) {
|
||||
mwifiex_dbg(adapter, ERROR, "invalid SSID - aborting\n");
|
||||
goto ssid_err;
|
||||
}
|
||||
|
||||
memcpy(req_ssid.ssid, ssid_ie + 2, req_ssid.ssid_len);
|
||||
if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) {
|
||||
mwifiex_dbg(adapter, ERROR, "invalid SSID - aborting\n");
|
||||
goto ssid_err;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
/* As this is new association, clear locally stored
|
||||
* keys and security related flags
|
||||
*/
|
||||
priv->sec_info.wpa_enabled = false;
|
||||
priv->sec_info.wpa2_enabled = false;
|
||||
priv->wep_key_curr_index = 0;
|
||||
priv->sec_info.encryption_mode = 0;
|
||||
priv->sec_info.is_authtype_auto = 0;
|
||||
if (mwifiex_set_encode(priv, NULL, NULL, 0, 0, NULL, 1)) {
|
||||
mwifiex_dbg(priv->adapter, ERROR, "deleting the crypto keys\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (req->crypto.n_ciphers_pairwise)
|
||||
priv->sec_info.encryption_mode =
|
||||
req->crypto.ciphers_pairwise[0];
|
||||
|
||||
if (req->crypto.cipher_group)
|
||||
priv->sec_info.encryption_mode = req->crypto.cipher_group;
|
||||
|
||||
if (req->ie)
|
||||
mwifiex_set_gen_ie(priv, req->ie, req->ie_len);
|
||||
|
||||
memcpy(priv->cfg_bssid, req->bss->bssid, ETH_ALEN);
|
||||
|
||||
mwifiex_dbg(adapter, MSG,
|
||||
"assoc: send association to %pM\n", req->bss->bssid);
|
||||
|
||||
cfg80211_ref_bss(adapter->wiphy, req->bss);
|
||||
ret = mwifiex_bss_start(priv, req->bss, &req_ssid);
|
||||
if (ret) {
|
||||
priv->auth_flag = 0;
|
||||
priv->auth_alg = WLAN_AUTH_NONE;
|
||||
eth_zero_addr(priv->cfg_bssid);
|
||||
}
|
||||
|
||||
if (priv->assoc_rsp_size) {
|
||||
priv->req_bss = req->bss;
|
||||
adapter->assoc_resp_received = true;
|
||||
queue_work(adapter->host_mlme_workqueue,
|
||||
&adapter->host_mlme_work);
|
||||
}
|
||||
|
||||
cfg80211_put_bss(priv->adapter->wiphy, req->bss);
|
||||
|
||||
return 0;
|
||||
|
||||
ssid_err:
|
||||
rcu_read_unlock();
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
static int
|
||||
mwifiex_cfg80211_deauthenticate(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_deauth_request *req)
|
||||
{
|
||||
return mwifiex_cfg80211_disconnect(wiphy, dev, req->reason_code);
|
||||
}
|
||||
|
||||
static int
|
||||
mwifiex_cfg80211_disassociate(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_disassoc_request *req)
|
||||
{
|
||||
return mwifiex_cfg80211_disconnect(wiphy, dev, req->reason_code);
|
||||
}
|
||||
|
||||
static int
|
||||
mwifiex_cfg80211_probe_client(struct wiphy *wiphy,
|
||||
struct net_device *dev, const u8 *peer,
|
||||
u64 *cookie)
|
||||
{
|
||||
/* hostapd looks for NL80211_CMD_PROBE_CLIENT support; otherwise,
|
||||
* it requires monitor-mode support (which mwifiex doesn't support).
|
||||
* Provide fake probe_client support to work around this.
|
||||
*/
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* station cfg80211 operations */
|
||||
static struct cfg80211_ops mwifiex_cfg80211_ops = {
|
||||
static const struct cfg80211_ops mwifiex_cfg80211_ops = {
|
||||
.add_virtual_intf = mwifiex_add_virtual_intf,
|
||||
.del_virtual_intf = mwifiex_del_virtual_intf,
|
||||
.change_virtual_intf = mwifiex_cfg80211_change_virtual_intf,
|
||||
@@ -4342,24 +4705,58 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
|
||||
u8 *country_code;
|
||||
u32 thr, retry;
|
||||
struct cfg80211_ops *ops;
|
||||
|
||||
ops = devm_kmemdup(adapter->dev, &mwifiex_cfg80211_ops,
|
||||
sizeof(mwifiex_cfg80211_ops), GFP_KERNEL);
|
||||
if (!ops)
|
||||
return -ENOMEM;
|
||||
|
||||
/* create a new wiphy for use with cfg80211 */
|
||||
wiphy = wiphy_new(&mwifiex_cfg80211_ops,
|
||||
sizeof(struct mwifiex_adapter *));
|
||||
wiphy = wiphy_new(ops, sizeof(struct mwifiex_adapter *));
|
||||
if (!wiphy) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"%s: creating new wiphy\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (adapter->host_mlme_enabled) {
|
||||
ops->auth = mwifiex_cfg80211_authenticate;
|
||||
ops->assoc = mwifiex_cfg80211_associate;
|
||||
ops->deauth = mwifiex_cfg80211_deauthenticate;
|
||||
ops->disassoc = mwifiex_cfg80211_disassociate;
|
||||
ops->disconnect = NULL;
|
||||
ops->connect = NULL;
|
||||
ops->probe_client = mwifiex_cfg80211_probe_client;
|
||||
}
|
||||
wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
|
||||
wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
|
||||
wiphy->mgmt_stypes = mwifiex_mgmt_stypes;
|
||||
if (adapter->host_mlme_enabled) {
|
||||
memcpy(adapter->mwifiex_mgmt_stypes,
|
||||
mwifiex_mgmt_stypes,
|
||||
NUM_NL80211_IFTYPES *
|
||||
sizeof(struct ieee80211_txrx_stypes));
|
||||
|
||||
adapter->mwifiex_mgmt_stypes[NL80211_IFTYPE_AP].tx = 0xffff;
|
||||
adapter->mwifiex_mgmt_stypes[NL80211_IFTYPE_AP].rx =
|
||||
BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
|
||||
BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
|
||||
BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
|
||||
BIT(IEEE80211_STYPE_DISASSOC >> 4) |
|
||||
BIT(IEEE80211_STYPE_AUTH >> 4) |
|
||||
BIT(IEEE80211_STYPE_DEAUTH >> 4) |
|
||||
BIT(IEEE80211_STYPE_ACTION >> 4);
|
||||
wiphy->mgmt_stypes = adapter->mwifiex_mgmt_stypes;
|
||||
} else {
|
||||
wiphy->mgmt_stypes = mwifiex_mgmt_stypes;
|
||||
}
|
||||
wiphy->max_remain_on_channel_duration = 5000;
|
||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
BIT(NL80211_IFTYPE_AP);
|
||||
|
||||
wiphy->max_num_akm_suites = CFG80211_MAX_NUM_AKM_SUITES;
|
||||
|
||||
if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info))
|
||||
wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
|
||||
|
||||
@@ -4411,14 +4808,18 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
|
||||
ether_addr_copy(wiphy->perm_addr, adapter->perm_addr);
|
||||
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
|
||||
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
|
||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
|
||||
wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
|
||||
WIPHY_FLAG_AP_UAPSD |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
WIPHY_FLAG_HAS_CHANNEL_SWITCH |
|
||||
WIPHY_FLAG_NETNS_OK |
|
||||
WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
|
||||
if (adapter->host_mlme_enabled)
|
||||
wiphy->flags |= WIPHY_FLAG_REPORTS_OBSS;
|
||||
else
|
||||
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
|
||||
|
||||
if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
|
||||
wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
|
||||
WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
|
||||
@@ -4448,6 +4849,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
NL80211_FEATURE_LOW_PRIORITY_SCAN |
|
||||
NL80211_FEATURE_NEED_OBSS_SCAN;
|
||||
|
||||
if (adapter->host_mlme_enabled)
|
||||
wiphy->features |= NL80211_FEATURE_SAE;
|
||||
|
||||
if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info))
|
||||
wiphy->features |= NL80211_FEATURE_HT_IBSS;
|
||||
|
||||
|
||||
@@ -482,7 +482,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
|
||||
if ((adapter->event_cause & EVENT_ID_MASK) == EVENT_RADAR_DETECTED) {
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (priv && mwifiex_is_11h_active(priv)) {
|
||||
if (mwifiex_is_11h_active(priv)) {
|
||||
adapter->event_cause |=
|
||||
((priv->bss_num & 0xff) << 16) |
|
||||
((priv->bss_type & 0xff) << 24);
|
||||
@@ -635,6 +635,8 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
|
||||
case HostCmd_CMD_UAP_STA_DEAUTH:
|
||||
case HOST_CMD_APCMD_SYS_RESET:
|
||||
case HOST_CMD_APCMD_STA_LIST:
|
||||
case HostCmd_CMD_CHAN_REPORT_REQUEST:
|
||||
case HostCmd_CMD_ADD_NEW_STATION:
|
||||
ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action,
|
||||
cmd_oid, data_buf,
|
||||
cmd_ptr);
|
||||
@@ -924,6 +926,24 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mwifiex_process_assoc_resp(struct mwifiex_adapter *adapter)
|
||||
{
|
||||
struct cfg80211_rx_assoc_resp_data assoc_resp = {
|
||||
.uapsd_queues = -1,
|
||||
};
|
||||
struct mwifiex_private *priv =
|
||||
mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
|
||||
|
||||
if (priv->assoc_rsp_size) {
|
||||
assoc_resp.links[0].bss = priv->req_bss;
|
||||
assoc_resp.buf = priv->assoc_rsp_buf;
|
||||
assoc_resp.len = priv->assoc_rsp_size;
|
||||
cfg80211_rx_assoc_resp(priv->netdev,
|
||||
&assoc_resp);
|
||||
priv->assoc_rsp_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the timeout of command sending.
|
||||
*
|
||||
@@ -1672,6 +1692,13 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
|
||||
if (adapter->fw_api_ver == MWIFIEX_FW_V15)
|
||||
adapter->scan_chan_gap_enabled = true;
|
||||
|
||||
if (adapter->key_api_major_ver != KEY_API_VER_MAJOR_V2)
|
||||
adapter->host_mlme_enabled = false;
|
||||
|
||||
mwifiex_dbg(adapter, MSG, "host_mlme: %s, key_api: %d\n",
|
||||
adapter->host_mlme_enabled ? "enable" : "disable",
|
||||
adapter->key_api_major_ver);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,29 @@
|
||||
* + sizeof(tx_control)
|
||||
*/
|
||||
|
||||
#define FRMCTL_LEN 2
|
||||
#define DURATION_LEN 2
|
||||
#define SEQCTL_LEN 2
|
||||
/* special FW 4 address management header */
|
||||
#define MWIFIEX_MGMT_HEADER_LEN (FRMCTL_LEN + DURATION_LEN + ETH_ALEN + \
|
||||
ETH_ALEN + ETH_ALEN + SEQCTL_LEN + ETH_ALEN)
|
||||
|
||||
#define AUTH_ALG_LEN 2
|
||||
#define AUTH_TRANSACTION_LEN 2
|
||||
#define AUTH_STATUS_LEN 2
|
||||
#define MWIFIEX_AUTH_BODY_LEN (AUTH_ALG_LEN + AUTH_TRANSACTION_LEN + \
|
||||
AUTH_STATUS_LEN)
|
||||
|
||||
#define HOST_MLME_AUTH_PENDING BIT(0)
|
||||
#define HOST_MLME_AUTH_DONE BIT(1)
|
||||
|
||||
#define HOST_MLME_MGMT_MASK (BIT(IEEE80211_STYPE_AUTH >> 4) | \
|
||||
BIT(IEEE80211_STYPE_DEAUTH >> 4) | \
|
||||
BIT(IEEE80211_STYPE_DISASSOC >> 4))
|
||||
#define AUTH_TX_DEFAULT_WAIT_TIME 2400
|
||||
|
||||
#define WLAN_AUTH_NONE 0xFFFF
|
||||
|
||||
#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2
|
||||
#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16
|
||||
#define MWIFIEX_MAX_TDLS_PEER_SUPPORTED 8
|
||||
|
||||
@@ -210,6 +210,9 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||
#define TLV_TYPE_RANDOM_MAC (PROPRIETARY_TLV_BASE_ID + 236)
|
||||
#define TLV_TYPE_CHAN_ATTR_CFG (PROPRIETARY_TLV_BASE_ID + 237)
|
||||
#define TLV_TYPE_MAX_CONN (PROPRIETARY_TLV_BASE_ID + 279)
|
||||
#define TLV_TYPE_HOST_MLME (PROPRIETARY_TLV_BASE_ID + 307)
|
||||
#define TLV_TYPE_UAP_STA_FLAGS (PROPRIETARY_TLV_BASE_ID + 313)
|
||||
#define TLV_TYPE_SAE_PWE_MODE (PROPRIETARY_TLV_BASE_ID + 339)
|
||||
|
||||
#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048
|
||||
|
||||
@@ -405,6 +408,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||
#define HostCmd_CMD_STA_CONFIGURE 0x023f
|
||||
#define HostCmd_CMD_CHAN_REGION_CFG 0x0242
|
||||
#define HostCmd_CMD_PACKET_AGGR_CTRL 0x0251
|
||||
#define HostCmd_CMD_ADD_NEW_STATION 0x025f
|
||||
|
||||
#define PROTOCOL_NO_SECURITY 0x01
|
||||
#define PROTOCOL_STATIC_WEP 0x02
|
||||
@@ -415,6 +419,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||
#define KEY_MGMT_NONE 0x04
|
||||
#define KEY_MGMT_PSK 0x02
|
||||
#define KEY_MGMT_EAP 0x01
|
||||
#define KEY_MGMT_PSK_SHA256 0x100
|
||||
#define KEY_MGMT_SAE 0x400
|
||||
#define CIPHER_TKIP 0x04
|
||||
#define CIPHER_AES_CCMP 0x08
|
||||
#define VALID_CIPHER_BITMAP 0x0c
|
||||
@@ -500,6 +506,9 @@ enum mwifiex_channel_flags {
|
||||
#define HostCmd_ACT_GET_TX 0x0008
|
||||
#define HostCmd_ACT_GET_BOTH 0x000c
|
||||
|
||||
#define HostCmd_ACT_REMOVE_STA 0x0
|
||||
#define HostCmd_ACT_ADD_STA 0x1
|
||||
|
||||
#define RF_ANTENNA_AUTO 0xFFFF
|
||||
|
||||
#define HostCmd_SET_SEQ_NO_BSS_INFO(seq, num, type) \
|
||||
@@ -744,6 +753,25 @@ struct uap_rxpd {
|
||||
u8 flags;
|
||||
} __packed;
|
||||
|
||||
struct mwifiex_auth {
|
||||
__le16 auth_alg;
|
||||
__le16 auth_transaction;
|
||||
__le16 status_code;
|
||||
/* possibly followed by Challenge text */
|
||||
u8 variable[];
|
||||
} __packed;
|
||||
|
||||
struct mwifiex_ieee80211_mgmt {
|
||||
__le16 frame_control;
|
||||
__le16 duration;
|
||||
u8 da[ETH_ALEN];
|
||||
u8 sa[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
__le16 seq_ctrl;
|
||||
u8 addr4[ETH_ALEN];
|
||||
struct mwifiex_auth auth;
|
||||
} __packed;
|
||||
|
||||
struct mwifiex_fw_chan_stats {
|
||||
u8 chan_num;
|
||||
u8 bandcfg;
|
||||
@@ -803,6 +831,11 @@ struct mwifiex_ie_types_ssid_param_set {
|
||||
u8 ssid[];
|
||||
} __packed;
|
||||
|
||||
struct mwifiex_ie_types_host_mlme {
|
||||
struct mwifiex_ie_types_header header;
|
||||
u8 host_mlme;
|
||||
} __packed;
|
||||
|
||||
struct mwifiex_ie_types_num_probes {
|
||||
struct mwifiex_ie_types_header header;
|
||||
__le16 num_probes;
|
||||
@@ -906,6 +939,13 @@ struct mwifiex_ie_types_tdls_idle_timeout {
|
||||
__le16 value;
|
||||
} __packed;
|
||||
|
||||
#define MWIFIEX_AUTHTYPE_SAE 6
|
||||
|
||||
struct mwifiex_ie_types_sae_pwe_mode {
|
||||
struct mwifiex_ie_types_header header;
|
||||
u8 pwe[];
|
||||
} __packed;
|
||||
|
||||
struct mwifiex_ie_types_rsn_param_set {
|
||||
struct mwifiex_ie_types_header header;
|
||||
u8 rsn_ie[];
|
||||
@@ -2298,6 +2338,20 @@ struct host_cmd_ds_sta_configure {
|
||||
u8 tlv_buffer[];
|
||||
} __packed;
|
||||
|
||||
struct mwifiex_ie_types_sta_flag {
|
||||
struct mwifiex_ie_types_header header;
|
||||
__le32 sta_flags;
|
||||
} __packed;
|
||||
|
||||
struct host_cmd_ds_add_station {
|
||||
__le16 action;
|
||||
__le16 aid;
|
||||
u8 peer_mac[ETH_ALEN];
|
||||
__le32 listen_interval;
|
||||
__le16 cap_info;
|
||||
u8 tlv[];
|
||||
} __packed;
|
||||
|
||||
struct host_cmd_ds_command {
|
||||
__le16 command;
|
||||
__le16 size;
|
||||
@@ -2376,6 +2430,7 @@ struct host_cmd_ds_command {
|
||||
struct host_cmd_ds_chan_region_cfg reg_cfg;
|
||||
struct host_cmd_ds_pkt_aggr_ctrl pkt_aggr_ctrl;
|
||||
struct host_cmd_ds_sta_configure sta_cfg;
|
||||
struct host_cmd_ds_add_station sta_info;
|
||||
} params;
|
||||
} __packed;
|
||||
|
||||
|
||||
@@ -81,6 +81,9 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
|
||||
priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
|
||||
priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
|
||||
|
||||
priv->auth_flag = 0;
|
||||
priv->auth_alg = WLAN_AUTH_NONE;
|
||||
|
||||
priv->sec_info.wep_enabled = 0;
|
||||
priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
|
||||
priv->sec_info.encryption_mode = 0;
|
||||
@@ -220,6 +223,9 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
|
||||
adapter->cmd_resp_received = false;
|
||||
adapter->event_received = false;
|
||||
adapter->data_received = false;
|
||||
adapter->assoc_resp_received = false;
|
||||
adapter->priv_link_lost = NULL;
|
||||
adapter->host_mlme_link_lost = false;
|
||||
|
||||
clear_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags);
|
||||
|
||||
@@ -362,15 +368,13 @@ static void mwifiex_invalidate_lists(struct mwifiex_adapter *adapter)
|
||||
list_del(&adapter->bss_prio_tbl[i].bss_prio_head);
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (adapter->priv[i]) {
|
||||
priv = adapter->priv[i];
|
||||
for (j = 0; j < MAX_NUM_TID; ++j)
|
||||
list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
|
||||
list_del(&priv->tx_ba_stream_tbl_ptr);
|
||||
list_del(&priv->rx_reorder_tbl_ptr);
|
||||
list_del(&priv->sta_list);
|
||||
list_del(&priv->auto_tdls_list);
|
||||
}
|
||||
priv = adapter->priv[i];
|
||||
for (j = 0; j < MAX_NUM_TID; ++j)
|
||||
list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
|
||||
list_del(&priv->tx_ba_stream_tbl_ptr);
|
||||
list_del(&priv->rx_reorder_tbl_ptr);
|
||||
list_del(&priv->sta_list);
|
||||
list_del(&priv->auto_tdls_list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,13 +423,11 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
|
||||
spin_lock_init(&adapter->mwifiex_cmd_lock);
|
||||
spin_lock_init(&adapter->queue_lock);
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (adapter->priv[i]) {
|
||||
priv = adapter->priv[i];
|
||||
spin_lock_init(&priv->wmm.ra_list_spinlock);
|
||||
spin_lock_init(&priv->curr_bcn_buf_lock);
|
||||
spin_lock_init(&priv->sta_list_spinlock);
|
||||
spin_lock_init(&priv->auto_tdls_lock);
|
||||
}
|
||||
priv = adapter->priv[i];
|
||||
spin_lock_init(&priv->wmm.ra_list_spinlock);
|
||||
spin_lock_init(&priv->curr_bcn_buf_lock);
|
||||
spin_lock_init(&priv->sta_list_spinlock);
|
||||
spin_lock_init(&priv->auto_tdls_lock);
|
||||
}
|
||||
|
||||
/* Initialize cmd_free_q */
|
||||
@@ -449,8 +451,6 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
|
||||
}
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (!adapter->priv[i])
|
||||
continue;
|
||||
priv = adapter->priv[i];
|
||||
for (j = 0; j < MAX_NUM_TID; ++j)
|
||||
INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j].ra_list);
|
||||
@@ -500,31 +500,24 @@ int mwifiex_init_fw(struct mwifiex_adapter *adapter)
|
||||
mwifiex_init_adapter(adapter);
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (adapter->priv[i]) {
|
||||
priv = adapter->priv[i];
|
||||
priv = adapter->priv[i];
|
||||
|
||||
/* Initialize private structure */
|
||||
ret = mwifiex_init_priv(priv);
|
||||
if (ret)
|
||||
return -1;
|
||||
}
|
||||
/* Initialize private structure */
|
||||
ret = mwifiex_init_priv(priv);
|
||||
if (ret)
|
||||
return -1;
|
||||
}
|
||||
if (adapter->mfg_mode) {
|
||||
adapter->hw_status = MWIFIEX_HW_STATUS_READY;
|
||||
ret = -EINPROGRESS;
|
||||
} else {
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (adapter->priv[i]) {
|
||||
ret = mwifiex_sta_init_cmd(adapter->priv[i],
|
||||
first_sta, true);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
|
||||
first_sta = false;
|
||||
}
|
||||
|
||||
|
||||
ret = mwifiex_sta_init_cmd(adapter->priv[i],
|
||||
first_sta, true);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
|
||||
first_sta = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,13 +624,11 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
|
||||
|
||||
/* Clean up Tx/Rx queues and delete BSS priority table */
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (adapter->priv[i]) {
|
||||
priv = adapter->priv[i];
|
||||
priv = adapter->priv[i];
|
||||
|
||||
mwifiex_clean_auto_tdls(priv);
|
||||
mwifiex_abort_cac(priv);
|
||||
mwifiex_free_priv(priv);
|
||||
}
|
||||
mwifiex_clean_auto_tdls(priv);
|
||||
mwifiex_abort_cac(priv);
|
||||
mwifiex_free_priv(priv);
|
||||
}
|
||||
|
||||
atomic_set(&adapter->tx_queued, 0);
|
||||
|
||||
@@ -158,6 +158,11 @@ struct mwifiex_bss_info {
|
||||
u8 bssid[ETH_ALEN];
|
||||
};
|
||||
|
||||
struct mwifiex_sta_info {
|
||||
u8 peer_mac[ETH_ALEN];
|
||||
struct station_parameters *params;
|
||||
};
|
||||
|
||||
#define MAX_NUM_TID 8
|
||||
|
||||
#define MAX_RX_WINSIZE 64
|
||||
|
||||
@@ -382,7 +382,9 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
|
||||
struct mwifiex_ie_types_ss_param_set *ss_tlv;
|
||||
struct mwifiex_ie_types_rates_param_set *rates_tlv;
|
||||
struct mwifiex_ie_types_auth_type *auth_tlv;
|
||||
struct mwifiex_ie_types_sae_pwe_mode *sae_pwe_tlv;
|
||||
struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
|
||||
struct mwifiex_ie_types_host_mlme *host_mlme_tlv;
|
||||
u8 rates[MWIFIEX_SUPPORTED_RATES];
|
||||
u32 rates_size;
|
||||
u16 tmp_cap;
|
||||
@@ -460,6 +462,24 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
|
||||
|
||||
pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len);
|
||||
|
||||
if (priv->sec_info.authentication_mode == WLAN_AUTH_SAE) {
|
||||
auth_tlv->auth_type = cpu_to_le16(MWIFIEX_AUTHTYPE_SAE);
|
||||
if (bss_desc->bcn_rsnx_ie &&
|
||||
bss_desc->bcn_rsnx_ie->ieee_hdr.len &&
|
||||
(bss_desc->bcn_rsnx_ie->data[0] &
|
||||
WLAN_RSNX_CAPA_SAE_H2E)) {
|
||||
sae_pwe_tlv =
|
||||
(struct mwifiex_ie_types_sae_pwe_mode *)pos;
|
||||
sae_pwe_tlv->header.type =
|
||||
cpu_to_le16(TLV_TYPE_SAE_PWE_MODE);
|
||||
sae_pwe_tlv->header.len =
|
||||
cpu_to_le16(sizeof(sae_pwe_tlv->pwe[0]));
|
||||
sae_pwe_tlv->pwe[0] = bss_desc->bcn_rsnx_ie->data[0];
|
||||
pos += sizeof(sae_pwe_tlv->header) +
|
||||
sizeof(sae_pwe_tlv->pwe[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_SUPPORT_MULTI_BANDS(priv->adapter) &&
|
||||
!(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
|
||||
(!bss_desc->disable_11n) &&
|
||||
@@ -491,6 +511,16 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
|
||||
sizeof(struct mwifiex_chan_scan_param_set);
|
||||
}
|
||||
|
||||
if (priv->adapter->host_mlme_enabled) {
|
||||
host_mlme_tlv = (struct mwifiex_ie_types_host_mlme *)pos;
|
||||
host_mlme_tlv->header.type = cpu_to_le16(TLV_TYPE_HOST_MLME);
|
||||
host_mlme_tlv->header.len =
|
||||
cpu_to_le16(sizeof(host_mlme_tlv->host_mlme));
|
||||
host_mlme_tlv->host_mlme = 1;
|
||||
pos += sizeof(host_mlme_tlv->header) +
|
||||
sizeof(host_mlme_tlv->host_mlme);
|
||||
}
|
||||
|
||||
if (!priv->wps.session_enable) {
|
||||
if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
|
||||
rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
|
||||
@@ -641,7 +671,21 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
|
||||
goto done;
|
||||
}
|
||||
|
||||
assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
|
||||
if (adapter->host_mlme_enabled) {
|
||||
struct ieee80211_mgmt *hdr;
|
||||
|
||||
hdr = (struct ieee80211_mgmt *)&resp->params;
|
||||
if (!memcmp(hdr->bssid,
|
||||
priv->attempted_bss_desc->mac_address,
|
||||
ETH_ALEN))
|
||||
assoc_rsp = (struct ieee_types_assoc_rsp *)
|
||||
&hdr->u.assoc_resp;
|
||||
else
|
||||
assoc_rsp =
|
||||
(struct ieee_types_assoc_rsp *)&resp->params;
|
||||
} else {
|
||||
assoc_rsp = (struct ieee_types_assoc_rsp *)&resp->params;
|
||||
}
|
||||
|
||||
cap_info = le16_to_cpu(assoc_rsp->cap_info_bitmap);
|
||||
status_code = le16_to_cpu(assoc_rsp->status_code);
|
||||
@@ -680,6 +724,9 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"ASSOC_RESP: UNSPECIFIED failure\n");
|
||||
}
|
||||
|
||||
if (priv->adapter->host_mlme_enabled)
|
||||
priv->assoc_rsp_size = 0;
|
||||
} else {
|
||||
ret = status_code;
|
||||
}
|
||||
@@ -778,7 +825,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
|
||||
|
||||
priv->adapter->dbg.num_cmd_assoc_success++;
|
||||
|
||||
mwifiex_dbg(priv->adapter, INFO, "info: ASSOC_RESP: associated\n");
|
||||
mwifiex_dbg(priv->adapter, MSG, "assoc: associated with %pM\n",
|
||||
priv->attempted_bss_desc->mac_address);
|
||||
|
||||
/* Add the ra_list here for infra mode as there will be only 1 ra
|
||||
always */
|
||||
@@ -1491,6 +1539,20 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
|
||||
if (!priv->media_connected)
|
||||
return 0;
|
||||
|
||||
if (priv->adapter->host_mlme_enabled) {
|
||||
priv->auth_flag = 0;
|
||||
priv->auth_alg = WLAN_AUTH_NONE;
|
||||
priv->host_mlme_reg = false;
|
||||
priv->mgmt_frame_mask = 0;
|
||||
if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
|
||||
HostCmd_ACT_GEN_SET, 0,
|
||||
&priv->mgmt_frame_mask, false)) {
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"could not unregister mgmt frame rx\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
switch (priv->bss_mode) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
@@ -1520,8 +1582,7 @@ void mwifiex_deauthenticate_all(struct mwifiex_adapter *adapter)
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (priv)
|
||||
mwifiex_deauthenticate(priv, NULL);
|
||||
mwifiex_deauthenticate(priv, NULL);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mwifiex_deauthenticate_all);
|
||||
|
||||
@@ -127,10 +127,8 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
|
||||
|
||||
/* Free private structures */
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (adapter->priv[i]) {
|
||||
mwifiex_free_curr_bcn(adapter->priv[i]);
|
||||
kfree(adapter->priv[i]);
|
||||
}
|
||||
mwifiex_free_curr_bcn(adapter->priv[i]);
|
||||
kfree(adapter->priv[i]);
|
||||
}
|
||||
|
||||
if (adapter->nd_info) {
|
||||
@@ -530,6 +528,11 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
|
||||
destroy_workqueue(adapter->rx_workqueue);
|
||||
adapter->rx_workqueue = NULL;
|
||||
}
|
||||
|
||||
if (adapter->host_mlme_workqueue) {
|
||||
destroy_workqueue(adapter->host_mlme_workqueue);
|
||||
adapter->host_mlme_workqueue = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -802,6 +805,10 @@ mwifiex_bypass_tx_queue(struct mwifiex_private *priv,
|
||||
"bypass txqueue; eth type %#x, mgmt %d\n",
|
||||
ntohs(eth_hdr->h_proto),
|
||||
mwifiex_is_skb_mgmt_frame(skb));
|
||||
if (eth_hdr->h_proto == htons(ETH_P_PAE))
|
||||
mwifiex_dbg(priv->adapter, MSG,
|
||||
"key: send EAPOL to %pM\n",
|
||||
eth_hdr->h_dest);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1162,7 +1169,7 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter)
|
||||
}
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (!adapter->priv[i] || !adapter->priv[i]->netdev)
|
||||
if (!adapter->priv[i]->netdev)
|
||||
continue;
|
||||
priv = adapter->priv[i];
|
||||
p += sprintf(p, "\n[interface : \"%s\"]\n",
|
||||
@@ -1201,7 +1208,7 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter)
|
||||
debug_info = kzalloc(sizeof(*debug_info), GFP_KERNEL);
|
||||
if (debug_info) {
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (!adapter->priv[i] || !adapter->priv[i]->netdev)
|
||||
if (!adapter->priv[i]->netdev)
|
||||
continue;
|
||||
priv = adapter->priv[i];
|
||||
mwifiex_get_debug_info(priv, debug_info);
|
||||
@@ -1384,6 +1391,35 @@ int is_command_pending(struct mwifiex_adapter *adapter)
|
||||
return !is_cmd_pend_q_empty;
|
||||
}
|
||||
|
||||
/* This is the host mlme work queue function.
|
||||
* It handles the host mlme operations.
|
||||
*/
|
||||
static void mwifiex_host_mlme_work_queue(struct work_struct *work)
|
||||
{
|
||||
struct mwifiex_adapter *adapter =
|
||||
container_of(work, struct mwifiex_adapter, host_mlme_work);
|
||||
|
||||
if (test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags))
|
||||
return;
|
||||
|
||||
/* Check for host mlme disconnection */
|
||||
if (adapter->host_mlme_link_lost) {
|
||||
if (adapter->priv_link_lost) {
|
||||
mwifiex_reset_connect_state(adapter->priv_link_lost,
|
||||
WLAN_REASON_DEAUTH_LEAVING,
|
||||
true);
|
||||
adapter->priv_link_lost = NULL;
|
||||
}
|
||||
adapter->host_mlme_link_lost = false;
|
||||
}
|
||||
|
||||
/* Check for host mlme Assoc Resp */
|
||||
if (adapter->assoc_resp_received) {
|
||||
mwifiex_process_assoc_resp(adapter);
|
||||
adapter->assoc_resp_received = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the RX work queue function.
|
||||
*
|
||||
@@ -1434,7 +1470,7 @@ static void mwifiex_uninit_sw(struct mwifiex_adapter *adapter)
|
||||
/* Stop data */
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (priv && priv->netdev) {
|
||||
if (priv->netdev) {
|
||||
mwifiex_stop_net_dev_queue(priv->netdev, adapter);
|
||||
if (netif_carrier_ok(priv->netdev))
|
||||
netif_carrier_off(priv->netdev);
|
||||
@@ -1459,8 +1495,6 @@ static void mwifiex_uninit_sw(struct mwifiex_adapter *adapter)
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (!priv)
|
||||
continue;
|
||||
rtnl_lock();
|
||||
if (priv->netdev &&
|
||||
priv->wdev.iftype != NL80211_IFTYPE_UNSPECIFIED) {
|
||||
@@ -1558,6 +1592,18 @@ mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
|
||||
INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue);
|
||||
}
|
||||
|
||||
if (adapter->host_mlme_enabled) {
|
||||
adapter->host_mlme_workqueue =
|
||||
alloc_workqueue("MWIFIEX_HOST_MLME_WORK_QUEUE",
|
||||
WQ_HIGHPRI |
|
||||
WQ_MEM_RECLAIM |
|
||||
WQ_UNBOUND, 0);
|
||||
if (!adapter->host_mlme_workqueue)
|
||||
goto err_kmalloc;
|
||||
INIT_WORK(&adapter->host_mlme_work,
|
||||
mwifiex_host_mlme_work_queue);
|
||||
}
|
||||
|
||||
/* Register the device. Fill up the private data structure with
|
||||
* relevant information from the card. Some code extracted from
|
||||
* mwifiex_register_dev()
|
||||
@@ -1721,6 +1767,18 @@ mwifiex_add_card(void *card, struct completion *fw_done,
|
||||
goto err_registerdev;
|
||||
}
|
||||
|
||||
if (adapter->host_mlme_enabled) {
|
||||
adapter->host_mlme_workqueue =
|
||||
alloc_workqueue("MWIFIEX_HOST_MLME_WORK_QUEUE",
|
||||
WQ_HIGHPRI |
|
||||
WQ_MEM_RECLAIM |
|
||||
WQ_UNBOUND, 0);
|
||||
if (!adapter->host_mlme_workqueue)
|
||||
goto err_kmalloc;
|
||||
INIT_WORK(&adapter->host_mlme_work,
|
||||
mwifiex_host_mlme_work_queue);
|
||||
}
|
||||
|
||||
if (mwifiex_init_hw_fw(adapter, true)) {
|
||||
pr_err("%s: firmware init failed\n", __func__);
|
||||
goto err_init_fw;
|
||||
|
||||
@@ -424,6 +424,8 @@ struct mwifiex_bssdescriptor {
|
||||
u16 wpa_offset;
|
||||
struct ieee_types_generic *bcn_rsn_ie;
|
||||
u16 rsn_offset;
|
||||
struct ieee_types_generic *bcn_rsnx_ie;
|
||||
u16 rsnx_offset;
|
||||
struct ieee_types_generic *bcn_wapi_ie;
|
||||
u16 wapi_offset;
|
||||
u8 *beacon_buf;
|
||||
@@ -525,6 +527,8 @@ struct mwifiex_private {
|
||||
u8 bss_priority;
|
||||
u8 bss_num;
|
||||
u8 bss_started;
|
||||
u8 auth_flag;
|
||||
u16 auth_alg;
|
||||
u8 frame_type;
|
||||
u8 curr_addr[ETH_ALEN];
|
||||
u8 media_connected;
|
||||
@@ -608,6 +612,7 @@ struct mwifiex_private {
|
||||
#define MWIFIEX_ASSOC_RSP_BUF_SIZE 500
|
||||
u8 assoc_rsp_buf[MWIFIEX_ASSOC_RSP_BUF_SIZE];
|
||||
u32 assoc_rsp_size;
|
||||
struct cfg80211_bss *req_bss;
|
||||
|
||||
#define MWIFIEX_GENIE_BUF_SIZE 256
|
||||
u8 gen_ie_buf[MWIFIEX_GENIE_BUF_SIZE];
|
||||
@@ -647,6 +652,7 @@ struct mwifiex_private {
|
||||
u16 gen_idx;
|
||||
u8 ap_11n_enabled;
|
||||
u8 ap_11ac_enabled;
|
||||
bool host_mlme_reg;
|
||||
u32 mgmt_frame_mask;
|
||||
struct mwifiex_roc_cfg roc_cfg;
|
||||
bool scan_aborting;
|
||||
@@ -793,7 +799,7 @@ struct mwifiex_auto_tdls_peer {
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 tdls_status;
|
||||
int rssi;
|
||||
long rssi_jiffies;
|
||||
unsigned long rssi_jiffies;
|
||||
u8 failure_count;
|
||||
u8 do_discover;
|
||||
u8 do_setup;
|
||||
@@ -876,6 +882,8 @@ struct mwifiex_adapter {
|
||||
struct work_struct main_work;
|
||||
struct workqueue_struct *rx_workqueue;
|
||||
struct work_struct rx_work;
|
||||
struct workqueue_struct *host_mlme_workqueue;
|
||||
struct work_struct host_mlme_work;
|
||||
bool rx_work_enabled;
|
||||
bool rx_processing;
|
||||
bool delay_main_work;
|
||||
@@ -907,6 +915,9 @@ struct mwifiex_adapter {
|
||||
u8 cmd_resp_received;
|
||||
u8 event_received;
|
||||
u8 data_received;
|
||||
u8 assoc_resp_received;
|
||||
struct mwifiex_private *priv_link_lost;
|
||||
u8 host_mlme_link_lost;
|
||||
u16 seq_num;
|
||||
struct cmd_ctrl_node *cmd_pool;
|
||||
struct cmd_ctrl_node *curr_cmd;
|
||||
@@ -996,6 +1007,8 @@ struct mwifiex_adapter {
|
||||
bool is_up;
|
||||
|
||||
bool ext_scan;
|
||||
bool host_mlme_enabled;
|
||||
struct ieee80211_txrx_stypes mwifiex_mgmt_stypes[NUM_NL80211_IFTYPES];
|
||||
u8 fw_api_ver;
|
||||
u8 key_api_major_ver, key_api_minor_ver;
|
||||
u8 max_p2p_conn, max_sta_conn;
|
||||
@@ -1061,6 +1074,9 @@ int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb);
|
||||
int mwifiex_uap_recv_packet(struct mwifiex_private *priv,
|
||||
struct sk_buff *skb);
|
||||
|
||||
void mwifiex_host_mlme_disconnect(struct mwifiex_private *priv,
|
||||
u16 reason_code, u8 *sa);
|
||||
|
||||
int mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
|
||||
struct sk_buff *skb);
|
||||
|
||||
@@ -1092,6 +1108,7 @@ void mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
|
||||
|
||||
int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter);
|
||||
int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter);
|
||||
void mwifiex_process_assoc_resp(struct mwifiex_adapter *adapter);
|
||||
int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
|
||||
struct sk_buff *skb);
|
||||
int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
|
||||
@@ -1286,14 +1303,12 @@ mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (adapter->priv[i]) {
|
||||
if (adapter->priv[i]->bss_mode == NL80211_IFTYPE_UNSPECIFIED)
|
||||
continue;
|
||||
if (adapter->priv[i]->bss_mode == NL80211_IFTYPE_UNSPECIFIED)
|
||||
continue;
|
||||
|
||||
if ((adapter->priv[i]->bss_num == bss_num) &&
|
||||
(adapter->priv[i]->bss_type == bss_type))
|
||||
break;
|
||||
}
|
||||
if ((adapter->priv[i]->bss_num == bss_num) &&
|
||||
(adapter->priv[i]->bss_type == bss_type))
|
||||
break;
|
||||
}
|
||||
return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
|
||||
}
|
||||
@@ -1309,11 +1324,9 @@ mwifiex_get_priv(struct mwifiex_adapter *adapter,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (adapter->priv[i]) {
|
||||
if (bss_role == MWIFIEX_BSS_ROLE_ANY ||
|
||||
GET_BSS_ROLE(adapter->priv[i]) == bss_role)
|
||||
break;
|
||||
}
|
||||
if (bss_role == MWIFIEX_BSS_ROLE_ANY ||
|
||||
GET_BSS_ROLE(adapter->priv[i]) == bss_role)
|
||||
break;
|
||||
}
|
||||
|
||||
return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
|
||||
@@ -1331,12 +1344,10 @@ mwifiex_get_unused_bss_num(struct mwifiex_adapter *adapter, u8 bss_type)
|
||||
|
||||
memset(index, 0, sizeof(index));
|
||||
for (i = 0; i < adapter->priv_num; i++)
|
||||
if (adapter->priv[i]) {
|
||||
if (adapter->priv[i]->bss_type == bss_type &&
|
||||
!(adapter->priv[i]->bss_mode ==
|
||||
NL80211_IFTYPE_UNSPECIFIED)) {
|
||||
index[adapter->priv[i]->bss_num] = 1;
|
||||
}
|
||||
if (adapter->priv[i]->bss_type == bss_type &&
|
||||
!(adapter->priv[i]->bss_mode ==
|
||||
NL80211_IFTYPE_UNSPECIFIED)) {
|
||||
index[adapter->priv[i]->bss_num] = 1;
|
||||
}
|
||||
for (j = 0; j < MWIFIEX_MAX_BSS_NUM; j++)
|
||||
if (!index[j])
|
||||
|
||||
@@ -1371,6 +1371,12 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||
bss_entry->rsn_offset = (u16) (current_ptr -
|
||||
bss_entry->beacon_buf);
|
||||
break;
|
||||
case WLAN_EID_RSNX:
|
||||
bss_entry->bcn_rsnx_ie =
|
||||
(struct ieee_types_generic *)current_ptr;
|
||||
bss_entry->rsnx_offset =
|
||||
(u16)(current_ptr - bss_entry->beacon_buf);
|
||||
break;
|
||||
case WLAN_EID_BSS_AC_ACCESS_DELAY:
|
||||
bss_entry->bcn_wapi_ie =
|
||||
(struct ieee_types_generic *) current_ptr;
|
||||
@@ -2045,8 +2051,6 @@ void mwifiex_cancel_scan(struct mwifiex_adapter *adapter)
|
||||
spin_unlock_bh(&adapter->mwifiex_cmd_lock);
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (!priv)
|
||||
continue;
|
||||
if (priv->scan_request) {
|
||||
struct cfg80211_scan_info info = {
|
||||
.aborted = true,
|
||||
|
||||
@@ -332,6 +332,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
|
||||
.can_auto_tdls = false,
|
||||
.can_ext_scan = false,
|
||||
.fw_ready_extra_delay = false,
|
||||
.host_mlme = false,
|
||||
};
|
||||
|
||||
static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
|
||||
@@ -348,6 +349,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
|
||||
.can_auto_tdls = false,
|
||||
.can_ext_scan = true,
|
||||
.fw_ready_extra_delay = false,
|
||||
.host_mlme = false,
|
||||
};
|
||||
|
||||
static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
|
||||
@@ -364,6 +366,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
|
||||
.can_auto_tdls = false,
|
||||
.can_ext_scan = true,
|
||||
.fw_ready_extra_delay = false,
|
||||
.host_mlme = false,
|
||||
};
|
||||
|
||||
static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
|
||||
@@ -380,6 +383,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
|
||||
.can_auto_tdls = false,
|
||||
.can_ext_scan = true,
|
||||
.fw_ready_extra_delay = false,
|
||||
.host_mlme = false,
|
||||
};
|
||||
|
||||
static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = {
|
||||
@@ -397,6 +401,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = {
|
||||
.can_auto_tdls = false,
|
||||
.can_ext_scan = true,
|
||||
.fw_ready_extra_delay = false,
|
||||
.host_mlme = false,
|
||||
};
|
||||
|
||||
static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = {
|
||||
@@ -414,6 +419,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = {
|
||||
.can_auto_tdls = false,
|
||||
.can_ext_scan = true,
|
||||
.fw_ready_extra_delay = true,
|
||||
.host_mlme = true,
|
||||
};
|
||||
|
||||
static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = {
|
||||
@@ -432,6 +438,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = {
|
||||
.can_auto_tdls = false,
|
||||
.can_ext_scan = true,
|
||||
.fw_ready_extra_delay = false,
|
||||
.host_mlme = false,
|
||||
};
|
||||
|
||||
static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
|
||||
@@ -448,6 +455,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
|
||||
.can_auto_tdls = true,
|
||||
.can_ext_scan = true,
|
||||
.fw_ready_extra_delay = false,
|
||||
.host_mlme = false,
|
||||
};
|
||||
|
||||
static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = {
|
||||
@@ -465,6 +473,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = {
|
||||
.can_auto_tdls = true,
|
||||
.can_ext_scan = true,
|
||||
.fw_ready_extra_delay = false,
|
||||
.host_mlme = false,
|
||||
};
|
||||
|
||||
static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
|
||||
@@ -481,6 +490,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
|
||||
.can_auto_tdls = false,
|
||||
.can_ext_scan = true,
|
||||
.fw_ready_extra_delay = false,
|
||||
.host_mlme = false,
|
||||
};
|
||||
|
||||
static struct memory_type_mapping generic_mem_type_map[] = {
|
||||
@@ -574,6 +584,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
|
||||
card->can_auto_tdls = data->can_auto_tdls;
|
||||
card->can_ext_scan = data->can_ext_scan;
|
||||
card->fw_ready_extra_delay = data->fw_ready_extra_delay;
|
||||
card->host_mlme = data->host_mlme;
|
||||
INIT_WORK(&card->work, mwifiex_sdio_work);
|
||||
}
|
||||
|
||||
@@ -2511,6 +2522,8 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
|
||||
adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
|
||||
}
|
||||
|
||||
adapter->host_mlme_enabled = card->host_mlme;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -256,6 +256,7 @@ struct sdio_mmc_card {
|
||||
bool can_auto_tdls;
|
||||
bool can_ext_scan;
|
||||
bool fw_ready_extra_delay;
|
||||
bool host_mlme;
|
||||
|
||||
struct mwifiex_sdio_mpa_tx mpa_tx;
|
||||
struct mwifiex_sdio_mpa_rx mpa_rx;
|
||||
@@ -280,6 +281,7 @@ struct mwifiex_sdio_device {
|
||||
bool can_auto_tdls;
|
||||
bool can_ext_scan;
|
||||
bool fw_ready_extra_delay;
|
||||
bool host_mlme;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user