wireless-next patches for v6.12

mwifiex has recently started to see active development which is good
 news. rtw89 is also under active development and got several new
 features. Otherwise not really anything out of ordinary.
 
 We have one conflict in ath12k but that's easy to fix:
 
 https://lore.kernel.org/all/20240808104348.6846e064@canb.auug.org.au/
 
 Major changes:
 
 mwifiex
 
 * support for up to ten Authentication and Key Management (AKM) suites
 
 * host MAC Sublayer Management Entity (MLME) client and AP mode support
 
 * WPA-PSK-SHA256 AKM suite support
 
 rtw88
 
 * improve USB performance by aggregation
 
 rtw89
 
 * Wi-Fi 6 chip RTL8852BE-VT support
 
 * WoWLAN net-detect support
 
 * hardware encryption in unicast management frames support
 
 * hardware rfkill support
 
 ath12k
 
 * DebugFS support for transmit DE stats
 
 * Make ASPM support hardware-dependent
 
 iwlwifi
 
 * channel puncturing for US/CAN from UEFI
 
 * bump FW API to 93 for BZ/SC devices
 -----BEGIN PGP SIGNATURE-----
 
 iQFFBAABCgAvFiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmbYfCARHGt2YWxvQGtl
 cm5lbC5vcmcACgkQbhckVSbrbZt+Qwf/X9oQ4sf8jV6eOV7EhoWhIHnQadvo5YBZ
 ulBm8In0QGjEOVWkI7kXGabKP5jhne2lVIyP1eFfP2/td/A2yDWIuEeBfDQD6f4K
 aiUGAa1gs4ZtGKJBniw/ukflSqJlR99N2qBO5T/smDm3Nw/aC522SO7BoLTpoJDQ
 SuW4atFHMShXYf/vIrAA2yB9ok2yw/QM+27M9qjj6D7zzqsQxDl9wKGW+2v8KiSa
 rXXbfnwfaQP21CYv5xYbEPACSRSV5Dr0TNopivWYxmm9svjLzwFN2JM2fHPxBEDh
 wP6Ojp+Z32c1VbQtclLrwIQdlZ5yhU5MEDlVg5VLym9F83hv+oXTbA==
 =lgVx
 -----END PGP SIGNATURE-----

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.c
  38055789d1 ("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:
Jakub Kicinski 2024-09-04 17:20:14 -07:00
commit 43b7724487
202 changed files with 6213 additions and 1568 deletions

View File

@ -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>;
};
};

View File

@ -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>;
};
};

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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,
},
};

View File

@ -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;

View File

@ -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)

View File

@ -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 &

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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];

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);
}
/**

View File

@ -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;

View File

@ -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");

View File

@ -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) */

View File

@ -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 */

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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 = {

View File

@ -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);

View File

@ -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)))

View File

@ -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));

View File

@ -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;

View File

@ -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;

View File

@ -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";

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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__ */

View File

@ -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,

View File

@ -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 */

View File

@ -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__ */

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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__ */

View File

@ -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);

View File

@ -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__ */

View File

@ -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[];

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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),
};

View File

@ -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)
{

View File

@ -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

View File

@ -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));

View File

@ -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;

View File

@ -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],

View File

@ -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)
{

View File

@ -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)

View File

@ -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);
}

View File

@ -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);

View File

@ -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),
};

View File

@ -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,

View File

@ -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);
}

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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,

View File

@ -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)},

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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])

View File

@ -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,

View File

@ -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;
}

View File

@ -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