forked from Minki/linux
wireless-drivers-next patches for 4.21
Last set of patches for 4.21. mt76 is still in very active development and having some refactoring as well as new features. But also other drivers got few new features and fixes. Major changes: ath10k * add amsdu support for QCA6174 monitor mode * report tx rate using the new ieee80211_tx_rate_update() API * wcn3990 support is not experimental anymore iwlwifi * support for FW version 43 for 9000 and 22000 series brcmfmac * add support for CYW43012 SDIO chipset * add the raw 4354 PCIe device ID for unprogrammed Cypress boards mwifiex * add NL80211_STA_INFO_RX_BITRATE support mt76 * use the same firmware for mt76x2e and mt76x2u * mt76x0e survey support * more unification between mt76x2 and mt76x0 * mt76x0e AP mode support * mt76x0e DFS support * rework and fix tx status handling for mt76x0 and mt76x2 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJcG9TEAAoJEG4XJFUm622byW8H/1vMVJhXwgIZbHeoUKNa47Yp Z7Jv5vW8IGXu+lp7DyoedDCbq4+lskNSlDV1DmysNChLgDnApU/3oCd/jH8EiGPV JAFUHb85HuVLTTpPpNHtnYz3IzL7r098TNVxOU0VD+xILM0Mf0aCeXztgmFWpGaY /rfHkId8oKUezIjdu6Dc96mqITrT6WRNtnOMfjr6dZPjClRTS44Hyz3Ga3rXABBL /n8BCkl0GpKGrL3mBy2CCR5mVY8zfxMB4Aj2zx7bccZ8i2i2QjrGlXCHyB6ImNrR lv4L1fUVXZWVdeOe8EbpftY7zEsPrX+XNm6h1kckdB7UyuBROpQLsVb+yxlLh9g= =mhAw -----END PGP SIGNATURE----- Merge tag 'wireless-drivers-next-for-davem-2018-12-20' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next Kalle Valo says: ==================== wireless-drivers-next patches for 4.21 Last set of patches for 4.21. mt76 is still in very active development and having some refactoring as well as new features. But also other drivers got few new features and fixes. Major changes: ath10k * add amsdu support for QCA6174 monitor mode * report tx rate using the new ieee80211_tx_rate_update() API * wcn3990 support is not experimental anymore iwlwifi * support for FW version 43 for 9000 and 22000 series brcmfmac * add support for CYW43012 SDIO chipset * add the raw 4354 PCIe device ID for unprogrammed Cypress boards mwifiex * add NL80211_STA_INFO_RX_BITRATE support mt76 * use the same firmware for mt76x2e and mt76x2u * mt76x0e survey support * more unification between mt76x2 and mt76x0 * mt76x0e AP mode support * mt76x0e DFS support * rework and fix tx status handling for mt76x0 and mt76x2 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
e69fbf31ca
@ -21,10 +21,22 @@ can be provided per device.
|
||||
|
||||
SNOC based devices (i.e. wcn3990) uses compatible string "qcom,wcn3990-wifi".
|
||||
|
||||
Optional properties:
|
||||
- reg: Address and length of the register set for the device.
|
||||
- reg-names: Must include the list of following reg names,
|
||||
"membase"
|
||||
- interrupts: reference to the list of 17 interrupt numbers for "qcom,ipq4019-wifi"
|
||||
compatible target.
|
||||
reference to the list of 12 interrupt numbers for "qcom,wcn3990-wifi"
|
||||
compatible target.
|
||||
Must contain interrupt-names property per entry for
|
||||
"qcom,ath10k", "qcom,ipq4019-wifi" compatible targets.
|
||||
|
||||
- interrupt-names: Must include the entries for MSI interrupt
|
||||
names ("msi0" to "msi15") and legacy interrupt
|
||||
name ("legacy") for "qcom,ath10k", "qcom,ipq4019-wifi"
|
||||
compatible targets.
|
||||
|
||||
Optional properties:
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reseti.txt for details.
|
||||
- reset-names: Must include the list of following reset names,
|
||||
@ -37,12 +49,9 @@ Optional properties:
|
||||
- clocks: List of clock specifiers, must contain an entry for each required
|
||||
entry in clock-names.
|
||||
- clock-names: Should contain the clock names "wifi_wcss_cmd", "wifi_wcss_ref",
|
||||
"wifi_wcss_rtc".
|
||||
- interrupts: List of interrupt lines. Must contain an entry
|
||||
for each entry in the interrupt-names property.
|
||||
- interrupt-names: Must include the entries for MSI interrupt
|
||||
names ("msi0" to "msi15") and legacy interrupt
|
||||
name ("legacy"),
|
||||
"wifi_wcss_rtc" for "qcom,ipq4019-wifi" compatible target and
|
||||
"cxo_ref_clk_pin" for "qcom,wcn3990-wifi"
|
||||
compatible target.
|
||||
- qcom,msi_addr: MSI interrupt address.
|
||||
- qcom,msi_base: Base value to add before writing MSI data into
|
||||
MSI address register.
|
||||
@ -55,14 +64,25 @@ Optional properties:
|
||||
- qcom,ath10k-pre-calibration-data : pre calibration data as an array,
|
||||
the length can vary between hw versions.
|
||||
- <supply-name>-supply: handle to the regulator device tree node
|
||||
optional "supply-name" is "vdd-0.8-cx-mx".
|
||||
optional "supply-name" are "vdd-0.8-cx-mx",
|
||||
"vdd-1.8-xo", "vdd-1.3-rfa" and "vdd-3.3-ch0".
|
||||
- memory-region:
|
||||
Usage: optional
|
||||
Value type: <phandle>
|
||||
Definition: reference to the reserved-memory for the msa region
|
||||
used by the wifi firmware running in Q6.
|
||||
- iommus:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: A list of phandle and IOMMU specifier pairs.
|
||||
- ext-fem-name:
|
||||
Usage: Optional
|
||||
Value type: string
|
||||
Definition: Name of external front end module used. Some valid FEM names
|
||||
for example: "microsemi-lx5586", "sky85703-11"
|
||||
and "sky85803" etc.
|
||||
|
||||
Example (to supply the calibration data alone):
|
||||
Example (to supply PCI based wifi block details):
|
||||
|
||||
In this example, the node is defined as child node of the PCI controller.
|
||||
|
||||
@ -74,10 +94,10 @@ pci {
|
||||
#address-cells = <3>;
|
||||
device_type = "pci";
|
||||
|
||||
ath10k@0,0 {
|
||||
wifi@0,0 {
|
||||
reg = <0 0 0 0 0>;
|
||||
device_type = "pci";
|
||||
qcom,ath10k-calibration-data = [ 01 02 03 ... ];
|
||||
ext-fem-name = "microsemi-lx5586";
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -138,21 +158,25 @@ wifi@18000000 {
|
||||
compatible = "qcom,wcn3990-wifi";
|
||||
reg = <0x18800000 0x800000>;
|
||||
reg-names = "membase";
|
||||
clocks = <&clock_gcc clk_aggre2_noc_clk>;
|
||||
clock-names = "smmu_aggre2_noc_clk"
|
||||
clocks = <&clock_gcc clk_rf_clk2_pin>;
|
||||
clock-names = "cxo_ref_clk_pin";
|
||||
interrupts =
|
||||
<0 130 0 /* CE0 */ >,
|
||||
<0 131 0 /* CE1 */ >,
|
||||
<0 132 0 /* CE2 */ >,
|
||||
<0 133 0 /* CE3 */ >,
|
||||
<0 134 0 /* CE4 */ >,
|
||||
<0 135 0 /* CE5 */ >,
|
||||
<0 136 0 /* CE6 */ >,
|
||||
<0 137 0 /* CE7 */ >,
|
||||
<0 138 0 /* CE8 */ >,
|
||||
<0 139 0 /* CE9 */ >,
|
||||
<0 140 0 /* CE10 */ >,
|
||||
<0 141 0 /* CE11 */ >;
|
||||
<GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 415 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
|
||||
vdd-0.8-cx-mx-supply = <&pm8998_l5>;
|
||||
vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
|
||||
vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
|
||||
vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
|
||||
memory-region = <&wifi_msa_mem>;
|
||||
iommus = <&apps_smmu 0x0040 0x1>;
|
||||
};
|
||||
|
@ -47,8 +47,7 @@ config ATH10K_SNOC
|
||||
select QCOM_QMI_HELPERS
|
||||
---help---
|
||||
This module adds support for integrated WCN3990 chip connected
|
||||
to system NOC(SNOC). Currently work in progress and will not
|
||||
fully work.
|
||||
to system NOC(SNOC).
|
||||
|
||||
config ATH10K_DEBUG
|
||||
bool "Atheros ath10k debugging"
|
||||
|
@ -494,6 +494,7 @@ struct ath10k_sta {
|
||||
u32 smps;
|
||||
u16 peer_id;
|
||||
struct rate_info txrate;
|
||||
struct ieee80211_tx_info tx_info;
|
||||
|
||||
struct work_struct update_wk;
|
||||
u64 rx_duration;
|
||||
|
@ -71,7 +71,7 @@ void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar, u16 peer_id, u8 tid
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
|
||||
peer = ath10k_peer_find_by_id(ar, peer_id);
|
||||
if (!peer)
|
||||
if (!peer || !peer->sta)
|
||||
goto out;
|
||||
|
||||
arsta = (struct ath10k_sta *)peer->sta->drv_priv;
|
||||
|
@ -469,6 +469,166 @@ static struct sk_buff *ath10k_htt_rx_pop_paddr(struct ath10k_htt *htt,
|
||||
return msdu;
|
||||
}
|
||||
|
||||
static inline void ath10k_htt_append_frag_list(struct sk_buff *skb_head,
|
||||
struct sk_buff *frag_list,
|
||||
unsigned int frag_len)
|
||||
{
|
||||
skb_shinfo(skb_head)->frag_list = frag_list;
|
||||
skb_head->data_len = frag_len;
|
||||
skb_head->len += skb_head->data_len;
|
||||
}
|
||||
|
||||
static int ath10k_htt_rx_handle_amsdu_mon_32(struct ath10k_htt *htt,
|
||||
struct sk_buff *msdu,
|
||||
struct htt_rx_in_ord_msdu_desc **msdu_desc)
|
||||
{
|
||||
struct ath10k *ar = htt->ar;
|
||||
u32 paddr;
|
||||
struct sk_buff *frag_buf;
|
||||
struct sk_buff *prev_frag_buf;
|
||||
u8 last_frag;
|
||||
struct htt_rx_in_ord_msdu_desc *ind_desc = *msdu_desc;
|
||||
struct htt_rx_desc *rxd;
|
||||
int amsdu_len = __le16_to_cpu(ind_desc->msdu_len);
|
||||
|
||||
rxd = (void *)msdu->data;
|
||||
trace_ath10k_htt_rx_desc(ar, rxd, sizeof(*rxd));
|
||||
|
||||
skb_put(msdu, sizeof(struct htt_rx_desc));
|
||||
skb_pull(msdu, sizeof(struct htt_rx_desc));
|
||||
skb_put(msdu, min(amsdu_len, HTT_RX_MSDU_SIZE));
|
||||
amsdu_len -= msdu->len;
|
||||
|
||||
last_frag = ind_desc->reserved;
|
||||
if (last_frag) {
|
||||
if (amsdu_len) {
|
||||
ath10k_warn(ar, "invalid amsdu len %u, left %d",
|
||||
__le16_to_cpu(ind_desc->msdu_len),
|
||||
amsdu_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ind_desc++;
|
||||
paddr = __le32_to_cpu(ind_desc->msdu_paddr);
|
||||
frag_buf = ath10k_htt_rx_pop_paddr(htt, paddr);
|
||||
if (!frag_buf) {
|
||||
ath10k_warn(ar, "failed to pop frag-1 paddr: 0x%x", paddr);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
skb_put(frag_buf, min(amsdu_len, HTT_RX_BUF_SIZE));
|
||||
ath10k_htt_append_frag_list(msdu, frag_buf, amsdu_len);
|
||||
|
||||
amsdu_len -= frag_buf->len;
|
||||
prev_frag_buf = frag_buf;
|
||||
last_frag = ind_desc->reserved;
|
||||
while (!last_frag) {
|
||||
ind_desc++;
|
||||
paddr = __le32_to_cpu(ind_desc->msdu_paddr);
|
||||
frag_buf = ath10k_htt_rx_pop_paddr(htt, paddr);
|
||||
if (!frag_buf) {
|
||||
ath10k_warn(ar, "failed to pop frag-n paddr: 0x%x",
|
||||
paddr);
|
||||
prev_frag_buf->next = NULL;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
skb_put(frag_buf, min(amsdu_len, HTT_RX_BUF_SIZE));
|
||||
last_frag = ind_desc->reserved;
|
||||
amsdu_len -= frag_buf->len;
|
||||
|
||||
prev_frag_buf->next = frag_buf;
|
||||
prev_frag_buf = frag_buf;
|
||||
}
|
||||
|
||||
if (amsdu_len) {
|
||||
ath10k_warn(ar, "invalid amsdu len %u, left %d",
|
||||
__le16_to_cpu(ind_desc->msdu_len), amsdu_len);
|
||||
}
|
||||
|
||||
*msdu_desc = ind_desc;
|
||||
|
||||
prev_frag_buf->next = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ath10k_htt_rx_handle_amsdu_mon_64(struct ath10k_htt *htt,
|
||||
struct sk_buff *msdu,
|
||||
struct htt_rx_in_ord_msdu_desc_ext **msdu_desc)
|
||||
{
|
||||
struct ath10k *ar = htt->ar;
|
||||
u64 paddr;
|
||||
struct sk_buff *frag_buf;
|
||||
struct sk_buff *prev_frag_buf;
|
||||
u8 last_frag;
|
||||
struct htt_rx_in_ord_msdu_desc_ext *ind_desc = *msdu_desc;
|
||||
struct htt_rx_desc *rxd;
|
||||
int amsdu_len = __le16_to_cpu(ind_desc->msdu_len);
|
||||
|
||||
rxd = (void *)msdu->data;
|
||||
trace_ath10k_htt_rx_desc(ar, rxd, sizeof(*rxd));
|
||||
|
||||
skb_put(msdu, sizeof(struct htt_rx_desc));
|
||||
skb_pull(msdu, sizeof(struct htt_rx_desc));
|
||||
skb_put(msdu, min(amsdu_len, HTT_RX_MSDU_SIZE));
|
||||
amsdu_len -= msdu->len;
|
||||
|
||||
last_frag = ind_desc->reserved;
|
||||
if (last_frag) {
|
||||
if (amsdu_len) {
|
||||
ath10k_warn(ar, "invalid amsdu len %u, left %d",
|
||||
__le16_to_cpu(ind_desc->msdu_len),
|
||||
amsdu_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ind_desc++;
|
||||
paddr = __le64_to_cpu(ind_desc->msdu_paddr);
|
||||
frag_buf = ath10k_htt_rx_pop_paddr(htt, paddr);
|
||||
if (!frag_buf) {
|
||||
ath10k_warn(ar, "failed to pop frag-1 paddr: 0x%llx", paddr);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
skb_put(frag_buf, min(amsdu_len, HTT_RX_BUF_SIZE));
|
||||
ath10k_htt_append_frag_list(msdu, frag_buf, amsdu_len);
|
||||
|
||||
amsdu_len -= frag_buf->len;
|
||||
prev_frag_buf = frag_buf;
|
||||
last_frag = ind_desc->reserved;
|
||||
while (!last_frag) {
|
||||
ind_desc++;
|
||||
paddr = __le64_to_cpu(ind_desc->msdu_paddr);
|
||||
frag_buf = ath10k_htt_rx_pop_paddr(htt, paddr);
|
||||
if (!frag_buf) {
|
||||
ath10k_warn(ar, "failed to pop frag-n paddr: 0x%llx",
|
||||
paddr);
|
||||
prev_frag_buf->next = NULL;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
skb_put(frag_buf, min(amsdu_len, HTT_RX_BUF_SIZE));
|
||||
last_frag = ind_desc->reserved;
|
||||
amsdu_len -= frag_buf->len;
|
||||
|
||||
prev_frag_buf->next = frag_buf;
|
||||
prev_frag_buf = frag_buf;
|
||||
}
|
||||
|
||||
if (amsdu_len) {
|
||||
ath10k_warn(ar, "invalid amsdu len %u, left %d",
|
||||
__le16_to_cpu(ind_desc->msdu_len), amsdu_len);
|
||||
}
|
||||
|
||||
*msdu_desc = ind_desc;
|
||||
|
||||
prev_frag_buf->next = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_htt_rx_pop_paddr32_list(struct ath10k_htt *htt,
|
||||
struct htt_rx_in_ord_ind *ev,
|
||||
struct sk_buff_head *list)
|
||||
@ -477,7 +637,7 @@ static int ath10k_htt_rx_pop_paddr32_list(struct ath10k_htt *htt,
|
||||
struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs32;
|
||||
struct htt_rx_desc *rxd;
|
||||
struct sk_buff *msdu;
|
||||
int msdu_count;
|
||||
int msdu_count, ret;
|
||||
bool is_offload;
|
||||
u32 paddr;
|
||||
|
||||
@ -495,6 +655,18 @@ static int ath10k_htt_rx_pop_paddr32_list(struct ath10k_htt *htt,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!is_offload && ar->monitor_arvif) {
|
||||
ret = ath10k_htt_rx_handle_amsdu_mon_32(htt, msdu,
|
||||
&msdu_desc);
|
||||
if (ret) {
|
||||
__skb_queue_purge(list);
|
||||
return ret;
|
||||
}
|
||||
__skb_queue_tail(list, msdu);
|
||||
msdu_desc++;
|
||||
continue;
|
||||
}
|
||||
|
||||
__skb_queue_tail(list, msdu);
|
||||
|
||||
if (!is_offload) {
|
||||
@ -527,7 +699,7 @@ static int ath10k_htt_rx_pop_paddr64_list(struct ath10k_htt *htt,
|
||||
struct htt_rx_in_ord_msdu_desc_ext *msdu_desc = ev->msdu_descs64;
|
||||
struct htt_rx_desc *rxd;
|
||||
struct sk_buff *msdu;
|
||||
int msdu_count;
|
||||
int msdu_count, ret;
|
||||
bool is_offload;
|
||||
u64 paddr;
|
||||
|
||||
@ -544,6 +716,18 @@ static int ath10k_htt_rx_pop_paddr64_list(struct ath10k_htt *htt,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!is_offload && ar->monitor_arvif) {
|
||||
ret = ath10k_htt_rx_handle_amsdu_mon_64(htt, msdu,
|
||||
&msdu_desc);
|
||||
if (ret) {
|
||||
__skb_queue_purge(list);
|
||||
return ret;
|
||||
}
|
||||
__skb_queue_tail(list, msdu);
|
||||
msdu_desc++;
|
||||
continue;
|
||||
}
|
||||
|
||||
__skb_queue_tail(list, msdu);
|
||||
|
||||
if (!is_offload) {
|
||||
@ -1159,7 +1343,8 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
|
||||
struct sk_buff *msdu,
|
||||
struct ieee80211_rx_status *status,
|
||||
enum htt_rx_mpdu_encrypt_type enctype,
|
||||
bool is_decrypted)
|
||||
bool is_decrypted,
|
||||
const u8 first_hdr[64])
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct htt_rx_desc *rxd;
|
||||
@ -1167,6 +1352,9 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
|
||||
size_t crypto_len;
|
||||
bool is_first;
|
||||
bool is_last;
|
||||
bool msdu_limit_err;
|
||||
int bytes_aligned = ar->hw_params.decap_align_bytes;
|
||||
u8 *qos;
|
||||
|
||||
rxd = (void *)msdu->data - sizeof(*rxd);
|
||||
is_first = !!(rxd->msdu_end.common.info0 &
|
||||
@ -1184,16 +1372,45 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
|
||||
* [FCS] <-- at end, needs to be trimmed
|
||||
*/
|
||||
|
||||
/* Some hardwares(QCA99x0 variants) limit number of msdus in a-msdu when
|
||||
* deaggregate, so that unwanted MSDU-deaggregation is avoided for
|
||||
* error packets. If limit exceeds, hw sends all remaining MSDUs as
|
||||
* a single last MSDU with this msdu limit error set.
|
||||
*/
|
||||
msdu_limit_err = ath10k_rx_desc_msdu_limit_error(&ar->hw_params, rxd);
|
||||
|
||||
/* If MSDU limit error happens, then don't warn on, the partial raw MSDU
|
||||
* without first MSDU is expected in that case, and handled later here.
|
||||
*/
|
||||
/* This probably shouldn't happen but warn just in case */
|
||||
if (WARN_ON_ONCE(!is_first))
|
||||
if (WARN_ON_ONCE(!is_first && !msdu_limit_err))
|
||||
return;
|
||||
|
||||
/* This probably shouldn't happen but warn just in case */
|
||||
if (WARN_ON_ONCE(!(is_first && is_last)))
|
||||
if (WARN_ON_ONCE(!(is_first && is_last) && !msdu_limit_err))
|
||||
return;
|
||||
|
||||
skb_trim(msdu, msdu->len - FCS_LEN);
|
||||
|
||||
/* Push original 80211 header */
|
||||
if (unlikely(msdu_limit_err)) {
|
||||
hdr = (struct ieee80211_hdr *)first_hdr;
|
||||
hdr_len = ieee80211_hdrlen(hdr->frame_control);
|
||||
crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype);
|
||||
|
||||
if (ieee80211_is_data_qos(hdr->frame_control)) {
|
||||
qos = ieee80211_get_qos_ctl(hdr);
|
||||
qos[0] |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
|
||||
}
|
||||
|
||||
if (crypto_len)
|
||||
memcpy(skb_push(msdu, crypto_len),
|
||||
(void *)hdr + round_up(hdr_len, bytes_aligned),
|
||||
crypto_len);
|
||||
|
||||
memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
|
||||
}
|
||||
|
||||
/* In most cases this will be true for sniffed frames. It makes sense
|
||||
* to deliver them as-is without stripping the crypto param. This is
|
||||
* necessary for software based decryption.
|
||||
@ -1467,7 +1684,7 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar,
|
||||
switch (decap) {
|
||||
case RX_MSDU_DECAP_RAW:
|
||||
ath10k_htt_rx_h_undecap_raw(ar, msdu, status, enctype,
|
||||
is_decrypted);
|
||||
is_decrypted, first_hdr);
|
||||
break;
|
||||
case RX_MSDU_DECAP_NATIVE_WIFI:
|
||||
ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr,
|
||||
@ -2627,7 +2844,7 @@ void ath10k_htt_htc_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
|
||||
static inline int ath10k_get_legacy_rate_idx(struct ath10k *ar, u8 rate)
|
||||
static inline s8 ath10k_get_legacy_rate_idx(struct ath10k *ar, u8 rate)
|
||||
{
|
||||
static const u8 legacy_rates[] = {1, 2, 5, 11, 6, 9, 12,
|
||||
18, 24, 36, 48, 54};
|
||||
@ -2646,7 +2863,7 @@ static void
|
||||
ath10k_accumulate_per_peer_tx_stats(struct ath10k *ar,
|
||||
struct ath10k_sta *arsta,
|
||||
struct ath10k_per_peer_tx_stats *pstats,
|
||||
u8 legacy_rate_idx)
|
||||
s8 legacy_rate_idx)
|
||||
{
|
||||
struct rate_info *txrate = &arsta->txrate;
|
||||
struct ath10k_htt_tx_stats *tx_stats;
|
||||
@ -2766,8 +2983,10 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
|
||||
struct ath10k_per_peer_tx_stats *peer_stats)
|
||||
{
|
||||
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
struct ieee80211_chanctx_conf *conf = NULL;
|
||||
u8 rate = 0, sgi;
|
||||
s8 rate_idx = 0;
|
||||
bool skip_auto_rate;
|
||||
struct rate_info txrate;
|
||||
|
||||
lockdep_assert_held(&ar->data_lock);
|
||||
@ -2777,6 +2996,13 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
|
||||
txrate.nss = ATH10K_HW_NSS(peer_stats->ratecode);
|
||||
txrate.mcs = ATH10K_HW_MCS_RATE(peer_stats->ratecode);
|
||||
sgi = ATH10K_HW_GI(peer_stats->flags);
|
||||
skip_auto_rate = ATH10K_FW_SKIPPED_RATE_CTRL(peer_stats->flags);
|
||||
|
||||
/* Firmware's rate control skips broadcast/management frames,
|
||||
* if host has configure fixed rates and in some other special cases.
|
||||
*/
|
||||
if (skip_auto_rate)
|
||||
return;
|
||||
|
||||
if (txrate.flags == WMI_RATE_PREAMBLE_VHT && txrate.mcs > 9) {
|
||||
ath10k_warn(ar, "Invalid VHT mcs %hhd peer stats", txrate.mcs);
|
||||
@ -2791,7 +3017,7 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
|
||||
}
|
||||
|
||||
memset(&arsta->txrate, 0, sizeof(arsta->txrate));
|
||||
|
||||
memset(&arsta->tx_info.status, 0, sizeof(arsta->tx_info.status));
|
||||
if (txrate.flags == WMI_RATE_PREAMBLE_CCK ||
|
||||
txrate.flags == WMI_RATE_PREAMBLE_OFDM) {
|
||||
rate = ATH10K_HW_LEGACY_RATE(peer_stats->ratecode);
|
||||
@ -2810,11 +3036,59 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
|
||||
arsta->txrate.mcs = txrate.mcs;
|
||||
}
|
||||
|
||||
if (sgi)
|
||||
arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
switch (txrate.flags) {
|
||||
case WMI_RATE_PREAMBLE_OFDM:
|
||||
if (arsta->arvif && arsta->arvif->vif)
|
||||
conf = rcu_dereference(arsta->arvif->vif->chanctx_conf);
|
||||
if (conf && conf->def.chan->band == NL80211_BAND_5GHZ)
|
||||
arsta->tx_info.status.rates[0].idx = rate_idx - 4;
|
||||
break;
|
||||
case WMI_RATE_PREAMBLE_CCK:
|
||||
arsta->tx_info.status.rates[0].idx = rate_idx;
|
||||
if (sgi)
|
||||
arsta->tx_info.status.rates[0].flags |=
|
||||
(IEEE80211_TX_RC_USE_SHORT_PREAMBLE |
|
||||
IEEE80211_TX_RC_SHORT_GI);
|
||||
break;
|
||||
case WMI_RATE_PREAMBLE_HT:
|
||||
arsta->tx_info.status.rates[0].idx =
|
||||
txrate.mcs + ((txrate.nss - 1) * 8);
|
||||
if (sgi)
|
||||
arsta->tx_info.status.rates[0].flags |=
|
||||
IEEE80211_TX_RC_SHORT_GI;
|
||||
arsta->tx_info.status.rates[0].flags |= IEEE80211_TX_RC_MCS;
|
||||
break;
|
||||
case WMI_RATE_PREAMBLE_VHT:
|
||||
ieee80211_rate_set_vht(&arsta->tx_info.status.rates[0],
|
||||
txrate.mcs, txrate.nss);
|
||||
if (sgi)
|
||||
arsta->tx_info.status.rates[0].flags |=
|
||||
IEEE80211_TX_RC_SHORT_GI;
|
||||
arsta->tx_info.status.rates[0].flags |= IEEE80211_TX_RC_VHT_MCS;
|
||||
break;
|
||||
}
|
||||
|
||||
arsta->txrate.nss = txrate.nss;
|
||||
arsta->txrate.bw = ath10k_bw_to_mac80211_bw(txrate.bw);
|
||||
if (sgi)
|
||||
arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
|
||||
switch (arsta->txrate.bw) {
|
||||
case RATE_INFO_BW_40:
|
||||
arsta->tx_info.status.rates[0].flags |=
|
||||
IEEE80211_TX_RC_40_MHZ_WIDTH;
|
||||
break;
|
||||
case RATE_INFO_BW_80:
|
||||
arsta->tx_info.status.rates[0].flags |=
|
||||
IEEE80211_TX_RC_80_MHZ_WIDTH;
|
||||
break;
|
||||
}
|
||||
|
||||
if (peer_stats->succ_pkts) {
|
||||
arsta->tx_info.flags = IEEE80211_TX_STAT_ACK;
|
||||
arsta->tx_info.status.rates[0].count = 1;
|
||||
ieee80211_tx_rate_update(ar->hw, sta, &arsta->tx_info);
|
||||
}
|
||||
|
||||
if (ath10k_debug_is_extd_tx_stats_enabled(ar))
|
||||
ath10k_accumulate_per_peer_tx_stats(ar, arsta, peer_stats,
|
||||
@ -2847,7 +3121,7 @@ static void ath10k_htt_fetch_peer_stats(struct ath10k *ar,
|
||||
rcu_read_lock();
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
peer = ath10k_peer_find_by_id(ar, peer_id);
|
||||
if (!peer) {
|
||||
if (!peer || !peer->sta) {
|
||||
ath10k_warn(ar, "Invalid peer id %d peer stats buffer\n",
|
||||
peer_id);
|
||||
goto out;
|
||||
@ -2900,7 +3174,7 @@ static void ath10k_fetch_10_2_tx_stats(struct ath10k *ar, u8 *data)
|
||||
rcu_read_lock();
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
peer = ath10k_peer_find_by_id(ar, peer_id);
|
||||
if (!peer) {
|
||||
if (!peer || !peer->sta) {
|
||||
ath10k_warn(ar, "Invalid peer id %d in peer stats buffer\n",
|
||||
peer_id);
|
||||
goto out;
|
||||
|
@ -1119,8 +1119,15 @@ static int ath10k_qca99x0_rx_desc_get_l3_pad_bytes(struct htt_rx_desc *rxd)
|
||||
RX_MSDU_END_INFO1_L3_HDR_PAD);
|
||||
}
|
||||
|
||||
static bool ath10k_qca99x0_rx_desc_msdu_limit_error(struct htt_rx_desc *rxd)
|
||||
{
|
||||
return !!(rxd->msdu_end.common.info0 &
|
||||
__cpu_to_le32(RX_MSDU_END_INFO0_MSDU_LIMIT_ERR));
|
||||
}
|
||||
|
||||
const struct ath10k_hw_ops qca99x0_ops = {
|
||||
.rx_desc_get_l3_pad_bytes = ath10k_qca99x0_rx_desc_get_l3_pad_bytes,
|
||||
.rx_desc_get_msdu_limit_error = ath10k_qca99x0_rx_desc_msdu_limit_error,
|
||||
};
|
||||
|
||||
const struct ath10k_hw_ops qca6174_ops = {
|
||||
|
@ -624,6 +624,7 @@ struct ath10k_hw_ops {
|
||||
int (*rx_desc_get_l3_pad_bytes)(struct htt_rx_desc *rxd);
|
||||
void (*set_coverage_class)(struct ath10k *ar, s16 value);
|
||||
int (*enable_pll_clk)(struct ath10k *ar);
|
||||
bool (*rx_desc_get_msdu_limit_error)(struct htt_rx_desc *rxd);
|
||||
};
|
||||
|
||||
extern const struct ath10k_hw_ops qca988x_ops;
|
||||
@ -642,6 +643,15 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ath10k_rx_desc_msdu_limit_error(struct ath10k_hw_params *hw,
|
||||
struct htt_rx_desc *rxd)
|
||||
{
|
||||
if (hw->hw_ops->rx_desc_get_msdu_limit_error)
|
||||
return hw->hw_ops->rx_desc_get_msdu_limit_error(rxd);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Target specific defines for MAIN firmware */
|
||||
#define TARGET_NUM_VDEVS 8
|
||||
#define TARGET_NUM_PEER_AST 2
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <net/mac80211.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include "hif.h"
|
||||
#include "core.h"
|
||||
@ -4637,11 +4638,44 @@ static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __ath10k_fetch_bb_timing_dt(struct ath10k *ar,
|
||||
struct wmi_bb_timing_cfg_arg *bb_timing)
|
||||
{
|
||||
struct device_node *node;
|
||||
const char *fem_name;
|
||||
int ret;
|
||||
|
||||
node = ar->dev->of_node;
|
||||
if (!node)
|
||||
return -ENOENT;
|
||||
|
||||
ret = of_property_read_string_index(node, "ext-fem-name", 0, &fem_name);
|
||||
if (ret)
|
||||
return -ENOENT;
|
||||
|
||||
/*
|
||||
* If external Front End module used in hardware, then default base band timing
|
||||
* parameter cannot be used since they were fine tuned for reference hardware,
|
||||
* so choosing different value suitable for that external FEM.
|
||||
*/
|
||||
if (!strcmp("microsemi-lx5586", fem_name)) {
|
||||
bb_timing->bb_tx_timing = 0x00;
|
||||
bb_timing->bb_xpa_timing = 0x0101;
|
||||
} else {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot bb_tx_timing 0x%x bb_xpa_timing 0x%x\n",
|
||||
bb_timing->bb_tx_timing, bb_timing->bb_xpa_timing);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
u32 param;
|
||||
int ret = 0;
|
||||
struct wmi_bb_timing_cfg_arg bb_timing = {0};
|
||||
|
||||
/*
|
||||
* This makes sense only when restarting hw. It is harmless to call
|
||||
@ -4796,6 +4830,19 @@ static int ath10k_start(struct ieee80211_hw *hw)
|
||||
clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
|
||||
}
|
||||
|
||||
if (test_bit(WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT, ar->wmi.svc_map)) {
|
||||
ret = __ath10k_fetch_bb_timing_dt(ar, &bb_timing);
|
||||
if (!ret) {
|
||||
ret = ath10k_wmi_pdev_bb_timing(ar, &bb_timing);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to set bb timings: %d\n",
|
||||
ret);
|
||||
goto err_core_stop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ar->num_started_vdevs = 0;
|
||||
ath10k_regd_update(ar);
|
||||
|
||||
@ -5154,6 +5201,17 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (test_bit(WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,
|
||||
ar->wmi.svc_map)) {
|
||||
vdev_param = ar->wmi.vdev_param->disable_4addr_src_lrn;
|
||||
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
|
||||
WMI_VDEV_DISABLE_4_ADDR_SRC_LRN);
|
||||
if (ret && ret != -EOPNOTSUPP) {
|
||||
ath10k_warn(ar, "failed to disable 4addr src lrn vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
}
|
||||
}
|
||||
|
||||
ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
list_add(&arvif->list, &ar->arvifs);
|
||||
@ -5754,30 +5812,6 @@ static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
|
||||
return data.num_tdls_stations;
|
||||
}
|
||||
|
||||
static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
||||
int *num_tdls_vifs = data;
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_STATION)
|
||||
return;
|
||||
|
||||
if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
|
||||
(*num_tdls_vifs)++;
|
||||
}
|
||||
|
||||
static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
|
||||
{
|
||||
int num_tdls_vifs = 0;
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
ath10k_mac_tdls_vifs_count_iter,
|
||||
&num_tdls_vifs);
|
||||
return num_tdls_vifs;
|
||||
}
|
||||
|
||||
static int ath10k_hw_scan(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_scan_request *hw_req)
|
||||
@ -6285,7 +6319,6 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
*/
|
||||
enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
|
||||
u32 num_tdls_stations;
|
||||
u32 num_tdls_vifs;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
|
||||
@ -6293,17 +6326,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
ar->num_stations + 1, ar->max_num_stations,
|
||||
ar->num_peers + 1, ar->max_num_peers);
|
||||
|
||||
if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {
|
||||
arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats),
|
||||
GFP_KERNEL);
|
||||
if (!arsta->tx_stats) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
|
||||
num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
|
||||
|
||||
if (sta->tdls) {
|
||||
if (num_tdls_stations >= ar->max_num_tdls_vdevs) {
|
||||
@ -6323,12 +6346,22 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {
|
||||
arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats),
|
||||
GFP_KERNEL);
|
||||
if (!arsta->tx_stats) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
|
||||
sta->addr, peer_type);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n",
|
||||
sta->addr, arvif->vdev_id, ret);
|
||||
ath10k_mac_dec_num_stations(arvif, sta);
|
||||
kfree(arsta->tx_stats);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -6341,6 +6374,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
|
||||
ath10k_mac_dec_num_stations(arvif, sta);
|
||||
kfree(arsta->tx_stats);
|
||||
ret = -ENOENT;
|
||||
goto exit;
|
||||
}
|
||||
@ -6361,6 +6395,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
ath10k_peer_delete(ar, arvif->vdev_id,
|
||||
sta->addr);
|
||||
ath10k_mac_dec_num_stations(arvif, sta);
|
||||
kfree(arsta->tx_stats);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -6372,6 +6407,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
sta->addr, arvif->vdev_id, ret);
|
||||
ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
|
||||
ath10k_mac_dec_num_stations(arvif, sta);
|
||||
kfree(arsta->tx_stats);
|
||||
|
||||
if (num_tdls_stations != 0)
|
||||
goto exit;
|
||||
@ -6387,11 +6423,6 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
"mac vdev %d peer delete %pM sta %pK (sta gone)\n",
|
||||
arvif->vdev_id, sta->addr, sta);
|
||||
|
||||
if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {
|
||||
kfree(arsta->tx_stats);
|
||||
arsta->tx_stats = NULL;
|
||||
}
|
||||
|
||||
if (sta->tdls) {
|
||||
ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id,
|
||||
sta,
|
||||
@ -6431,6 +6462,11 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
}
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {
|
||||
kfree(arsta->tx_stats);
|
||||
arsta->tx_stats = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
|
||||
ath10k_mac_txq_unref(ar, sta->txq[i]);
|
||||
|
||||
|
@ -931,9 +931,9 @@ static int ath10k_qmi_setup_msa_resources(struct ath10k_qmi *qmi, u32 msa_size)
|
||||
qmi->msa_mem_size = resource_size(&r);
|
||||
qmi->msa_va = devm_memremap(dev, qmi->msa_pa, qmi->msa_mem_size,
|
||||
MEMREMAP_WT);
|
||||
if (!qmi->msa_va) {
|
||||
if (IS_ERR(qmi->msa_va)) {
|
||||
dev_err(dev, "failed to map memory region: %pa\n", &r.start);
|
||||
return -EBUSY;
|
||||
return PTR_ERR(qmi->msa_va);
|
||||
}
|
||||
} else {
|
||||
qmi->msa_va = dmam_alloc_coherent(dev, msa_size,
|
||||
|
@ -572,6 +572,7 @@ struct rx_msdu_start {
|
||||
#define RX_MSDU_END_INFO0_REPORTED_MPDU_LENGTH_LSB 0
|
||||
#define RX_MSDU_END_INFO0_FIRST_MSDU BIT(14)
|
||||
#define RX_MSDU_END_INFO0_LAST_MSDU BIT(15)
|
||||
#define RX_MSDU_END_INFO0_MSDU_LIMIT_ERR BIT(18)
|
||||
#define RX_MSDU_END_INFO0_PRE_DELIM_ERR BIT(30)
|
||||
#define RX_MSDU_END_INFO0_RESERVED_3B BIT(31)
|
||||
|
||||
@ -676,6 +677,12 @@ struct rx_msdu_end {
|
||||
* Indicates the last MSDU of the A-MSDU. MPDU end status is
|
||||
* only valid when last_msdu is set.
|
||||
*
|
||||
*msdu_limit_error
|
||||
* Indicates that the MSDU threshold was exceeded and thus
|
||||
* all the rest of the MSDUs will not be scattered and
|
||||
* will not be decapsulated but will be received in RAW format
|
||||
* as a single MSDU buffer.
|
||||
*
|
||||
*reserved_3a
|
||||
* Reserved: HW should fill with zero. FW should ignore.
|
||||
*
|
||||
|
@ -1654,7 +1654,6 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n");
|
||||
ath10k_warn(ar, "Warning: SNOC support is still work-in-progress, it will not work properly!");
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -219,6 +219,9 @@ struct wmi_ops {
|
||||
struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value);
|
||||
struct sk_buff *(*gen_pdev_get_tpc_table_cmdid)(struct ath10k *ar,
|
||||
u32 param);
|
||||
struct sk_buff *(*gen_bb_timing)
|
||||
(struct ath10k *ar,
|
||||
const struct wmi_bb_timing_cfg_arg *arg);
|
||||
|
||||
};
|
||||
|
||||
@ -1576,4 +1579,21 @@ ath10k_wmi_report_radar_found(struct ath10k *ar,
|
||||
ar->wmi.cmd->radar_found_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pdev_bb_timing(struct ath10k *ar,
|
||||
const struct wmi_bb_timing_cfg_arg *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_bb_timing)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_bb_timing(ar, arg);
|
||||
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->set_bb_timing_cmdid);
|
||||
}
|
||||
#endif
|
||||
|
@ -621,7 +621,7 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
ath10k_wmi_event_mgmt_tx_compl(ar, skb);
|
||||
break;
|
||||
default:
|
||||
ath10k_warn(ar, "Unknown eventid: %d\n", id);
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "Unknown eventid: %d\n", id);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -539,6 +539,7 @@ static struct wmi_cmd_map wmi_10_2_4_cmd_map = {
|
||||
WMI_10_2_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
|
||||
.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.radar_found_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.set_bb_timing_cmdid = WMI_10_2_PDEV_SET_BB_TIMING_CONFIG_CMDID,
|
||||
};
|
||||
|
||||
/* 10.4 WMI cmd track */
|
||||
@ -825,6 +826,7 @@ static struct wmi_vdev_param_map wmi_vdev_param_map = {
|
||||
.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* 10.X WMI VDEV param map */
|
||||
@ -900,6 +902,7 @@ static struct wmi_vdev_param_map wmi_10x_vdev_param_map = {
|
||||
.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
|
||||
@ -974,6 +977,7 @@ static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
|
||||
.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = {
|
||||
@ -1051,6 +1055,7 @@ static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = {
|
||||
.bw_nss_ratemask = WMI_10_4_VDEV_PARAM_BW_NSS_RATEMASK,
|
||||
.inc_tsf = WMI_10_4_VDEV_PARAM_TSF_INCREMENT,
|
||||
.dec_tsf = WMI_10_4_VDEV_PARAM_TSF_DECREMENT,
|
||||
.disable_4addr_src_lrn = WMI_10_4_VDEV_PARAM_DISABLE_4_ADDR_SRC_LRN,
|
||||
};
|
||||
|
||||
static struct wmi_pdev_param_map wmi_pdev_param_map = {
|
||||
@ -2578,7 +2583,7 @@ static void ath10k_wmi_event_chan_info_unpaired(struct ath10k *ar,
|
||||
|
||||
survey = &ar->survey[idx];
|
||||
|
||||
if (!params->mac_clk_mhz || !survey)
|
||||
if (!params->mac_clk_mhz)
|
||||
return;
|
||||
|
||||
memset(survey, 0, sizeof(*survey));
|
||||
@ -8839,6 +8844,27 @@ ath10k_wmi_barrier(struct ath10k *ar)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_10_2_4_op_gen_bb_timing(struct ath10k *ar,
|
||||
const struct wmi_bb_timing_cfg_arg *arg)
|
||||
{
|
||||
struct wmi_pdev_bb_timing_cfg_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
cmd = (struct wmi_pdev_bb_timing_cfg_cmd *)skb->data;
|
||||
cmd->bb_tx_timing = __cpu_to_le32(arg->bb_tx_timing);
|
||||
cmd->bb_xpa_timing = __cpu_to_le32(arg->bb_xpa_timing);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi pdev bb_tx_timing 0x%x bb_xpa_timing 0x%x\n",
|
||||
arg->bb_tx_timing, arg->bb_xpa_timing);
|
||||
return skb;
|
||||
}
|
||||
|
||||
static const struct wmi_ops wmi_ops = {
|
||||
.rx = ath10k_wmi_op_rx,
|
||||
.map_svc = wmi_main_svc_map,
|
||||
@ -9112,6 +9138,7 @@ static const struct wmi_ops wmi_10_2_4_ops = {
|
||||
.gen_pdev_enable_adaptive_cca =
|
||||
ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
|
||||
.get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype,
|
||||
.gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing,
|
||||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
|
@ -205,6 +205,8 @@ enum wmi_service {
|
||||
WMI_SERVICE_SPOOF_MAC_SUPPORT,
|
||||
WMI_SERVICE_TX_DATA_ACK_RSSI,
|
||||
WMI_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT,
|
||||
WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,
|
||||
WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT,
|
||||
WMI_SERVICE_THERM_THROT,
|
||||
|
||||
/* keep last */
|
||||
@ -245,6 +247,9 @@ enum wmi_10x_service {
|
||||
WMI_10X_SERVICE_PEER_STATS,
|
||||
WMI_10X_SERVICE_RESET_CHIP,
|
||||
WMI_10X_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
|
||||
WMI_10X_SERVICE_VDEV_BCN_RATE_CONTROL,
|
||||
WMI_10X_SERVICE_PER_PACKET_SW_ENCRYPT,
|
||||
WMI_10X_SERVICE_BB_TIMING_CONFIG_SUPPORT,
|
||||
};
|
||||
|
||||
enum wmi_main_service {
|
||||
@ -360,6 +365,9 @@ enum wmi_10_4_service {
|
||||
WMI_10_4_SERVICE_PEER_TID_CONFIGS_SUPPORT,
|
||||
WMI_10_4_SERVICE_VDEV_BCN_RATE_CONTROL,
|
||||
WMI_10_4_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT,
|
||||
WMI_10_4_SERVICE_HTT_ASSERT_TRIGGER_SUPPORT,
|
||||
WMI_10_4_SERVICE_VDEV_FILTER_NEIGHBOR_RX_PACKETS,
|
||||
WMI_10_4_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,
|
||||
};
|
||||
|
||||
static inline char *wmi_service_name(int service_id)
|
||||
@ -569,6 +577,8 @@ static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out,
|
||||
WMI_SERVICE_RESET_CHIP, len);
|
||||
SVCMAP(WMI_10X_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
|
||||
WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, len);
|
||||
SVCMAP(WMI_10X_SERVICE_BB_TIMING_CONFIG_SUPPORT,
|
||||
WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT, len);
|
||||
}
|
||||
|
||||
static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out,
|
||||
@ -787,6 +797,8 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
|
||||
WMI_SERVICE_TX_DATA_ACK_RSSI, len);
|
||||
SVCMAP(WMI_10_4_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT,
|
||||
WMI_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT, len);
|
||||
SVCMAP(WMI_10_4_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,
|
||||
WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT, len);
|
||||
}
|
||||
|
||||
#undef SVCMAP
|
||||
@ -987,6 +999,7 @@ struct wmi_cmd_map {
|
||||
u32 pdev_wds_entry_list_cmdid;
|
||||
u32 tdls_set_offchan_mode_cmdid;
|
||||
u32 radar_found_cmdid;
|
||||
u32 set_bb_timing_cmdid;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1602,6 +1615,8 @@ enum wmi_10_2_cmd_id {
|
||||
WMI_10_2_SET_LTEU_CONFIG_CMDID,
|
||||
WMI_10_2_SET_CCA_PARAMS,
|
||||
WMI_10_2_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
|
||||
WMI_10_2_FWTEST_CMDID,
|
||||
WMI_10_2_PDEV_SET_BB_TIMING_CONFIG_CMDID,
|
||||
WMI_10_2_PDEV_UTF_CMDID = WMI_10_2_END_CMDID - 1,
|
||||
};
|
||||
|
||||
@ -4985,6 +5000,7 @@ enum wmi_rate_preamble {
|
||||
(((preamble) << 6) | ((nss) << 4) | (rate))
|
||||
#define ATH10K_HW_AMPDU(flags) ((flags) & 0x1)
|
||||
#define ATH10K_HW_BA_FAIL(flags) (((flags) >> 1) & 0x3)
|
||||
#define ATH10K_FW_SKIPPED_RATE_CTRL(flags) (((flags) >> 6) & 0x1)
|
||||
|
||||
#define ATH10K_VHT_MCS_NUM 10
|
||||
#define ATH10K_BW_NUM 4
|
||||
@ -5066,6 +5082,7 @@ struct wmi_vdev_param_map {
|
||||
u32 bw_nss_ratemask;
|
||||
u32 inc_tsf;
|
||||
u32 dec_tsf;
|
||||
u32 disable_4addr_src_lrn;
|
||||
};
|
||||
|
||||
#define WMI_VDEV_PARAM_UNSUPPORTED 0
|
||||
@ -5405,8 +5422,20 @@ enum wmi_10_4_vdev_param {
|
||||
WMI_10_4_VDEV_PARAM_ATF_SSID_SCHED_POLICY,
|
||||
WMI_10_4_VDEV_PARAM_DISABLE_DYN_BW_RTS,
|
||||
WMI_10_4_VDEV_PARAM_TSF_DECREMENT,
|
||||
WMI_10_4_VDEV_PARAM_SELFGEN_FIXED_RATE,
|
||||
WMI_10_4_VDEV_PARAM_AMPDU_SUBFRAME_SIZE_PER_AC,
|
||||
WMI_10_4_VDEV_PARAM_NSS_VHT160,
|
||||
WMI_10_4_VDEV_PARAM_NSS_VHT80_80,
|
||||
WMI_10_4_VDEV_PARAM_AMSDU_SUBFRAME_SIZE_PER_AC,
|
||||
WMI_10_4_VDEV_PARAM_DISABLE_CABQ,
|
||||
WMI_10_4_VDEV_PARAM_SIFS_TRIGGER_RATE,
|
||||
WMI_10_4_VDEV_PARAM_TX_POWER,
|
||||
WMI_10_4_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
|
||||
WMI_10_4_VDEV_PARAM_DISABLE_4_ADDR_SRC_LRN,
|
||||
};
|
||||
|
||||
#define WMI_VDEV_DISABLE_4_ADDR_SRC_LRN 1
|
||||
|
||||
#define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0)
|
||||
#define WMI_VDEV_PARAM_TXBF_MU_TX_BFEE BIT(1)
|
||||
#define WMI_VDEV_PARAM_TXBF_SU_TX_BFER BIT(2)
|
||||
@ -7154,6 +7183,23 @@ struct wmi_pdev_chan_info_req_cmd {
|
||||
__le32 reserved;
|
||||
} __packed;
|
||||
|
||||
/* bb timing register configurations */
|
||||
struct wmi_bb_timing_cfg_arg {
|
||||
/* Tx_end to pa off timing */
|
||||
u32 bb_tx_timing;
|
||||
|
||||
/* Tx_end to external pa off timing */
|
||||
u32 bb_xpa_timing;
|
||||
};
|
||||
|
||||
struct wmi_pdev_bb_timing_cfg_cmd {
|
||||
/* Tx_end to pa off timing */
|
||||
__le32 bb_tx_timing;
|
||||
|
||||
/* Tx_end to external pa off timing */
|
||||
__le32 bb_xpa_timing;
|
||||
} __packed;
|
||||
|
||||
struct ath10k;
|
||||
struct ath10k_vif;
|
||||
struct ath10k_fw_stats_pdev;
|
||||
|
@ -291,7 +291,7 @@ static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
|
||||
}
|
||||
|
||||
if (!test_bit(WLAN_ENABLED, &vif->flags)) {
|
||||
ath6kl_err("wlan disabled\n");
|
||||
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "wlan disabled\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -939,7 +939,7 @@ static int ath6kl_set_probed_ssids(struct ath6kl *ar,
|
||||
else
|
||||
ssid_list[i].flag = ANY_SSID_FLAG;
|
||||
|
||||
if (n_match_ssid == 0)
|
||||
if (ar->wiphy->max_match_sets != 0 && n_match_ssid == 0)
|
||||
ssid_list[i].flag |= MATCH_SSID_FLAG;
|
||||
}
|
||||
|
||||
@ -1093,7 +1093,7 @@ void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
|
||||
if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
|
||||
for (i = 0; i < vif->scan_req->n_ssids; i++) {
|
||||
ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
i + 1, DISABLE_SSID_FLAG,
|
||||
i, DISABLE_SSID_FLAG,
|
||||
0, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ static void wil_print_ring(struct seq_file *s, struct wil6210_priv *wil,
|
||||
seq_puts(s, "}\n");
|
||||
}
|
||||
|
||||
static int wil_ring_debugfs_show(struct seq_file *s, void *data)
|
||||
static int ring_show(struct seq_file *s, void *data)
|
||||
{
|
||||
uint i;
|
||||
struct wil6210_priv *wil = s->private;
|
||||
@ -183,18 +183,7 @@ static int wil_ring_debugfs_show(struct seq_file *s, void *data)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_ring_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_ring_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_ring = {
|
||||
.open = wil_ring_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(ring);
|
||||
|
||||
static void wil_print_sring(struct seq_file *s, struct wil6210_priv *wil,
|
||||
struct wil_status_ring *sring)
|
||||
@ -240,7 +229,7 @@ static void wil_print_sring(struct seq_file *s, struct wil6210_priv *wil,
|
||||
seq_puts(s, "}\n");
|
||||
}
|
||||
|
||||
static int wil_srings_debugfs_show(struct seq_file *s, void *data)
|
||||
static int srings_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
int i = 0;
|
||||
@ -251,18 +240,7 @@ static int wil_srings_debugfs_show(struct seq_file *s, void *data)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_srings_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_srings_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_srings = {
|
||||
.open = wil_srings_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(srings);
|
||||
|
||||
static void wil_seq_hexdump(struct seq_file *s, void *p, int len,
|
||||
const char *prefix)
|
||||
@ -348,7 +326,7 @@ static void wil_print_mbox_ring(struct seq_file *s, const char *prefix,
|
||||
wil_halp_unvote(wil);
|
||||
}
|
||||
|
||||
static int wil_mbox_debugfs_show(struct seq_file *s, void *data)
|
||||
static int mbox_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
int ret;
|
||||
@ -366,18 +344,7 @@ static int wil_mbox_debugfs_show(struct seq_file *s, void *data)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_mbox_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_mbox_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_mbox = {
|
||||
.open = wil_mbox_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(mbox);
|
||||
|
||||
static int wil_debugfs_iomem_x32_set(void *data, u64 val)
|
||||
{
|
||||
@ -624,7 +591,7 @@ static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_memread_debugfs_show(struct seq_file *s, void *data)
|
||||
static int memread_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
void __iomem *a;
|
||||
@ -645,18 +612,7 @@ static int wil_memread_debugfs_show(struct seq_file *s, void *data)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_memread_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_memread_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_memread = {
|
||||
.open = wil_memread_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(memread);
|
||||
|
||||
static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
@ -1060,7 +1016,7 @@ static void wil_seq_print_skb(struct seq_file *s, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
/*---------Tx/Rx descriptor------------*/
|
||||
static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
|
||||
static int txdesc_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
struct wil_ring *ring;
|
||||
@ -1153,21 +1109,10 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_txdesc_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_txdesc_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_txdesc = {
|
||||
.open = wil_txdesc_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(txdesc);
|
||||
|
||||
/*---------Tx/Rx status message------------*/
|
||||
static int wil_status_msg_debugfs_show(struct seq_file *s, void *data)
|
||||
static int status_msg_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
int sring_idx = dbg_sring_index;
|
||||
@ -1209,19 +1154,7 @@ static int wil_status_msg_debugfs_show(struct seq_file *s, void *data)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_status_msg_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_status_msg_debugfs_show,
|
||||
inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_status_msg = {
|
||||
.open = wil_status_msg_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(status_msg);
|
||||
|
||||
static int wil_print_rx_buff(struct seq_file *s, struct list_head *lh)
|
||||
{
|
||||
@ -1239,7 +1172,7 @@ static int wil_print_rx_buff(struct seq_file *s, struct list_head *lh)
|
||||
return i;
|
||||
}
|
||||
|
||||
static int wil_rx_buff_mgmt_debugfs_show(struct seq_file *s, void *data)
|
||||
static int rx_buff_mgmt_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
struct wil_rx_buff_mgmt *rbm = &wil->rx_buff_mgmt;
|
||||
@ -1264,19 +1197,7 @@ static int wil_rx_buff_mgmt_debugfs_show(struct seq_file *s, void *data)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_rx_buff_mgmt_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_rx_buff_mgmt_debugfs_show,
|
||||
inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_rx_buff_mgmt = {
|
||||
.open = wil_rx_buff_mgmt_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(rx_buff_mgmt);
|
||||
|
||||
/*---------beamforming------------*/
|
||||
static char *wil_bfstatus_str(u32 status)
|
||||
@ -1306,7 +1227,7 @@ static bool is_all_zeros(void * const x_, size_t sz)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int wil_bf_debugfs_show(struct seq_file *s, void *data)
|
||||
static int bf_show(struct seq_file *s, void *data)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
@ -1360,18 +1281,7 @@ static int wil_bf_debugfs_show(struct seq_file *s, void *data)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_bf_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_bf_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_bf = {
|
||||
.open = wil_bf_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(bf);
|
||||
|
||||
/*---------temp------------*/
|
||||
static void print_temp(struct seq_file *s, const char *prefix, s32 t)
|
||||
@ -1388,7 +1298,7 @@ static void print_temp(struct seq_file *s, const char *prefix, s32 t)
|
||||
}
|
||||
}
|
||||
|
||||
static int wil_temp_debugfs_show(struct seq_file *s, void *data)
|
||||
static int temp_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
s32 t_m, t_r;
|
||||
@ -1404,21 +1314,10 @@ static int wil_temp_debugfs_show(struct seq_file *s, void *data)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_temp_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_temp_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_temp = {
|
||||
.open = wil_temp_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(temp);
|
||||
|
||||
/*---------freq------------*/
|
||||
static int wil_freq_debugfs_show(struct seq_file *s, void *data)
|
||||
static int freq_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
struct wireless_dev *wdev = wil->main_ndev->ieee80211_ptr;
|
||||
@ -1428,21 +1327,10 @@ static int wil_freq_debugfs_show(struct seq_file *s, void *data)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_freq_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_freq_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_freq = {
|
||||
.open = wil_freq_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(freq);
|
||||
|
||||
/*---------link------------*/
|
||||
static int wil_link_debugfs_show(struct seq_file *s, void *data)
|
||||
static int link_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
struct station_info *sinfo;
|
||||
@ -1494,21 +1382,10 @@ out:
|
||||
kfree(sinfo);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wil_link_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_link_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_link = {
|
||||
.open = wil_link_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(link);
|
||||
|
||||
/*---------info------------*/
|
||||
static int wil_info_debugfs_show(struct seq_file *s, void *data)
|
||||
static int info_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
struct net_device *ndev = wil->main_ndev;
|
||||
@ -1543,18 +1420,7 @@ static int wil_info_debugfs_show(struct seq_file *s, void *data)
|
||||
#undef CHECK_QSTATE
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_info_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_info_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_info = {
|
||||
.open = wil_info_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(info);
|
||||
|
||||
/*---------recovery------------*/
|
||||
/* mode = [manual|auto]
|
||||
@ -1670,7 +1536,7 @@ has_keys:
|
||||
seq_puts(s, "\n");
|
||||
}
|
||||
|
||||
static int wil_sta_debugfs_show(struct seq_file *s, void *data)
|
||||
static int sta_show(struct seq_file *s, void *data)
|
||||
__acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
@ -1752,20 +1618,9 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
|
||||
|
||||
return 0;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(sta);
|
||||
|
||||
static int wil_sta_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_sta_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_sta = {
|
||||
.open = wil_sta_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
|
||||
static int wil_mids_debugfs_show(struct seq_file *s, void *data)
|
||||
static int mids_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
struct wil6210_vif *vif;
|
||||
@ -1788,18 +1643,7 @@ static int wil_mids_debugfs_show(struct seq_file *s, void *data)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_mids_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_mids_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_mids = {
|
||||
.open = wil_mids_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(mids);
|
||||
|
||||
static int wil_tx_latency_debugfs_show(struct seq_file *s, void *data)
|
||||
__acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
|
||||
@ -2443,23 +2287,23 @@ static const struct {
|
||||
umode_t mode;
|
||||
const struct file_operations *fops;
|
||||
} dbg_files[] = {
|
||||
{"mbox", 0444, &fops_mbox},
|
||||
{"rings", 0444, &fops_ring},
|
||||
{"stations", 0444, &fops_sta},
|
||||
{"mids", 0444, &fops_mids},
|
||||
{"desc", 0444, &fops_txdesc},
|
||||
{"bf", 0444, &fops_bf},
|
||||
{"mem_val", 0644, &fops_memread},
|
||||
{"mbox", 0444, &mbox_fops},
|
||||
{"rings", 0444, &ring_fops},
|
||||
{"stations", 0444, &sta_fops},
|
||||
{"mids", 0444, &mids_fops},
|
||||
{"desc", 0444, &txdesc_fops},
|
||||
{"bf", 0444, &bf_fops},
|
||||
{"mem_val", 0644, &memread_fops},
|
||||
{"rxon", 0244, &fops_rxon},
|
||||
{"tx_mgmt", 0244, &fops_txmgmt},
|
||||
{"wmi_send", 0244, &fops_wmi},
|
||||
{"back", 0644, &fops_back},
|
||||
{"pmccfg", 0644, &fops_pmccfg},
|
||||
{"pmcdata", 0444, &fops_pmcdata},
|
||||
{"temp", 0444, &fops_temp},
|
||||
{"freq", 0444, &fops_freq},
|
||||
{"link", 0444, &fops_link},
|
||||
{"info", 0444, &fops_info},
|
||||
{"temp", 0444, &temp_fops},
|
||||
{"freq", 0444, &freq_fops},
|
||||
{"link", 0444, &link_fops},
|
||||
{"info", 0444, &info_fops},
|
||||
{"recovery", 0644, &fops_recovery},
|
||||
{"led_cfg", 0644, &fops_led_cfg},
|
||||
{"led_blink_time", 0644, &fops_led_blink_time},
|
||||
@ -2467,9 +2311,9 @@ static const struct {
|
||||
{"fw_version", 0444, &fops_fw_version},
|
||||
{"suspend_stats", 0644, &fops_suspend_stats},
|
||||
{"compressed_rx_status", 0644, &fops_compressed_rx_status},
|
||||
{"srings", 0444, &fops_srings},
|
||||
{"status_msg", 0444, &fops_status_msg},
|
||||
{"rx_buff_mgmt", 0444, &fops_rx_buff_mgmt},
|
||||
{"srings", 0444, &srings_fops},
|
||||
{"status_msg", 0444, &status_msg_fops},
|
||||
{"rx_buff_mgmt", 0444, &rx_buff_mgmt_fops},
|
||||
{"tx_latency", 0644, &fops_tx_latency},
|
||||
{"link_stats", 0644, &fops_link_stats},
|
||||
{"link_stats_global", 0644, &fops_link_stats_global},
|
||||
|
@ -404,7 +404,6 @@ static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
|
||||
{
|
||||
struct wil6210_priv *wil;
|
||||
struct net_device *ndev;
|
||||
struct wireless_dev *wdev;
|
||||
int cid = -ENOENT;
|
||||
|
||||
if (unlikely(!vif))
|
||||
@ -412,7 +411,6 @@ static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
|
||||
|
||||
wil = vif_to_wil(vif);
|
||||
ndev = vif_to_ndev(vif);
|
||||
wdev = vif_to_wdev(vif);
|
||||
|
||||
might_sleep();
|
||||
wil_info(wil, "disconnect bssid=%pM, reason=%d\n", bssid, reason_code);
|
||||
|
@ -5895,7 +5895,6 @@ static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
|
||||
struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan;
|
||||
struct b43_ppr *ppr = &nphy->tx_pwr_max_ppr;
|
||||
u8 max; /* qdBm */
|
||||
bool tx_pwr_state;
|
||||
|
||||
if (nphy->tx_pwr_last_recalc_freq == channel->center_freq &&
|
||||
nphy->tx_pwr_last_recalc_limit == phy->desired_txpower)
|
||||
@ -5931,7 +5930,6 @@ static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
|
||||
b43_ppr_apply_min(dev, ppr, INT_TO_Q52(8));
|
||||
|
||||
/* Apply */
|
||||
tx_pwr_state = nphy->txpwrctrl;
|
||||
b43_mac_suspend(dev);
|
||||
b43_nphy_tx_power_ctl_setup(dev);
|
||||
if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
|
||||
@ -6044,7 +6042,6 @@ static int b43_phy_initn(struct b43_wldev *dev)
|
||||
u8 tx_pwr_state;
|
||||
struct nphy_txgains target;
|
||||
u16 tmp;
|
||||
enum nl80211_band tmp2;
|
||||
bool do_rssi_cal;
|
||||
|
||||
u16 clip[2];
|
||||
@ -6138,7 +6135,6 @@ static int b43_phy_initn(struct b43_wldev *dev)
|
||||
b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4);
|
||||
}
|
||||
|
||||
tmp2 = b43_current_band(dev->wl);
|
||||
if (b43_nphy_ipa(dev)) {
|
||||
b43_phy_set(dev, B43_NPHY_PAPD_EN0, 0x1);
|
||||
b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ0, 0x007F,
|
||||
|
@ -983,6 +983,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_4373),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_43012),
|
||||
{ /* end: all zeroes */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
|
||||
|
@ -5196,10 +5196,17 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
|
||||
.del_pmk = brcmf_cfg80211_del_pmk,
|
||||
};
|
||||
|
||||
struct cfg80211_ops *brcmf_cfg80211_get_ops(void)
|
||||
struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings)
|
||||
{
|
||||
return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
|
||||
struct cfg80211_ops *ops;
|
||||
|
||||
ops = kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (ops && settings->roamoff)
|
||||
ops->update_connect_params = NULL;
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
||||
@ -6309,6 +6316,16 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
|
||||
.tx = 0xffff,
|
||||
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
|
||||
BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
|
||||
},
|
||||
[NL80211_IFTYPE_AP] = {
|
||||
.tx = 0xffff,
|
||||
.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)
|
||||
}
|
||||
};
|
||||
|
||||
@ -6639,6 +6656,12 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
|
||||
|
||||
brcmf_configure_arp_nd_offload(ifp, true);
|
||||
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_FAKEFRAG, 1);
|
||||
if (err) {
|
||||
brcmf_err("failed to set frameburst mode\n");
|
||||
goto default_conf_out;
|
||||
}
|
||||
|
||||
cfg->dongle_up = true;
|
||||
default_conf_out:
|
||||
|
||||
|
@ -404,7 +404,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
|
||||
void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
|
||||
s32 brcmf_cfg80211_up(struct net_device *ndev);
|
||||
s32 brcmf_cfg80211_down(struct net_device *ndev);
|
||||
struct cfg80211_ops *brcmf_cfg80211_get_ops(void);
|
||||
struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings);
|
||||
enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
|
||||
|
||||
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
||||
|
@ -165,6 +165,7 @@ struct sbconfig {
|
||||
#define SRCI_LSS_MASK 0x00f00000
|
||||
#define SRCI_LSS_SHIFT 20
|
||||
#define SRCI_SRNB_MASK 0xf0
|
||||
#define SRCI_SRNB_MASK_EXT 0x100
|
||||
#define SRCI_SRNB_SHIFT 4
|
||||
#define SRCI_SRBSZ_MASK 0xf
|
||||
#define SRCI_SRBSZ_SHIFT 0
|
||||
@ -592,7 +593,13 @@ static void brcmf_chip_socram_ramsize(struct brcmf_core_priv *sr, u32 *ramsize,
|
||||
if (lss != 0)
|
||||
*ramsize += (1 << ((lss - 1) + SR_BSZ_BASE));
|
||||
} else {
|
||||
nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
|
||||
/* length of SRAM Banks increased for corerev greater than 23 */
|
||||
if (sr->pub.rev >= 23) {
|
||||
nb = (coreinfo & (SRCI_SRNB_MASK | SRCI_SRNB_MASK_EXT))
|
||||
>> SRCI_SRNB_SHIFT;
|
||||
} else {
|
||||
nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
|
||||
}
|
||||
for (i = 0; i < nb; i++) {
|
||||
retent = brcmf_chip_socram_banksize(sr, i, &banksize);
|
||||
*ramsize += banksize;
|
||||
@ -779,7 +786,7 @@ static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv *ci, u32 *eromaddr,
|
||||
u32 *regbase, u32 *wrapbase)
|
||||
{
|
||||
u8 desc;
|
||||
u32 val;
|
||||
u32 val, szdesc;
|
||||
u8 mpnum = 0;
|
||||
u8 stype, sztype, wraptype;
|
||||
|
||||
@ -825,14 +832,15 @@ static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv *ci, u32 *eromaddr,
|
||||
|
||||
/* next size descriptor can be skipped */
|
||||
if (sztype == DMP_SLAVE_SIZE_DESC) {
|
||||
val = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
|
||||
szdesc = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
|
||||
/* skip upper size descriptor if present */
|
||||
if (val & DMP_DESC_ADDRSIZE_GT32)
|
||||
if (szdesc & DMP_DESC_ADDRSIZE_GT32)
|
||||
brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
|
||||
}
|
||||
|
||||
/* only look for 4K register regions */
|
||||
if (sztype != DMP_SLAVE_SIZE_4K)
|
||||
/* look for 4K or 8K register regions */
|
||||
if (sztype != DMP_SLAVE_SIZE_4K &&
|
||||
sztype != DMP_SLAVE_SIZE_8K)
|
||||
continue;
|
||||
|
||||
stype = (val & DMP_SLAVE_TYPE) >> DMP_SLAVE_TYPE_S;
|
||||
@ -889,7 +897,8 @@ int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci)
|
||||
|
||||
/* need core with ports */
|
||||
if (nmw + nsw == 0 &&
|
||||
id != BCMA_CORE_PMU)
|
||||
id != BCMA_CORE_PMU &&
|
||||
id != BCMA_CORE_GCI)
|
||||
continue;
|
||||
|
||||
/* try to obtain register address info */
|
||||
@ -1356,6 +1365,16 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
|
||||
addr = CORE_CC_REG(base, sr_control1);
|
||||
reg = chip->ops->read32(chip->ctx, addr);
|
||||
return reg != 0;
|
||||
case CY_CC_4373_CHIP_ID:
|
||||
/* explicitly check SR engine enable bit */
|
||||
addr = CORE_CC_REG(base, sr_control0);
|
||||
reg = chip->ops->read32(chip->ctx, addr);
|
||||
return (reg & CC_SR_CTL0_ENABLE_MASK) != 0;
|
||||
case CY_CC_43012_CHIP_ID:
|
||||
addr = CORE_CC_REG(pmu->base, retention_ctl);
|
||||
reg = chip->ops->read32(chip->ctx, addr);
|
||||
return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
|
||||
PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
|
||||
default:
|
||||
addr = CORE_CC_REG(pmu->base, pmucapabilities_ext);
|
||||
reg = chip->ops->read32(chip->ctx, addr);
|
||||
|
@ -1130,7 +1130,7 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
ops = brcmf_cfg80211_get_ops();
|
||||
ops = brcmf_cfg80211_get_ops(settings);
|
||||
if (!ops)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -512,7 +512,7 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
static u8 *brcmf_fw_nvram_from_efi(size_t *data_len) { return NULL; }
|
||||
static inline u8 *brcmf_fw_nvram_from_efi(size_t *data_len) { return NULL; }
|
||||
#endif
|
||||
|
||||
static void brcmf_fw_free_request(struct brcmf_fw_request *req)
|
||||
|
@ -80,6 +80,7 @@
|
||||
#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
|
||||
#define BRCMF_C_SET_ASSOC_PREFER 205
|
||||
#define BRCMF_C_GET_VALID_CHANNELS 217
|
||||
#define BRCMF_C_SET_FAKEFRAG 219
|
||||
#define BRCMF_C_GET_KEY_PRIMARY 235
|
||||
#define BRCMF_C_SET_KEY_PRIMARY 236
|
||||
#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
|
||||
|
@ -511,6 +511,7 @@ struct brcmf_fws_info {
|
||||
struct work_struct fws_dequeue_work;
|
||||
u32 fifo_enqpkt[BRCMF_FWS_FIFO_COUNT];
|
||||
int fifo_credit[BRCMF_FWS_FIFO_COUNT];
|
||||
int init_fifo_credit[BRCMF_FWS_FIFO_COUNT];
|
||||
int credits_borrowed[BRCMF_FWS_FIFO_AC_VO + 1];
|
||||
int deq_node_pos[BRCMF_FWS_FIFO_COUNT];
|
||||
u32 fifo_credit_map;
|
||||
@ -1237,6 +1238,9 @@ static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
|
||||
}
|
||||
|
||||
fws->fifo_credit[fifo] += credits;
|
||||
if (fws->fifo_credit[fifo] > fws->init_fifo_credit[fifo])
|
||||
fws->fifo_credit[fifo] = fws->init_fifo_credit[fifo];
|
||||
|
||||
}
|
||||
|
||||
static void brcmf_fws_schedule_deq(struct brcmf_fws_info *fws)
|
||||
@ -1451,9 +1455,10 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
|
||||
|
||||
static int
|
||||
brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
|
||||
u32 genbit, u16 seq)
|
||||
u32 genbit, u16 seq, u8 compcnt)
|
||||
{
|
||||
u32 fifo;
|
||||
u8 cnt = 0;
|
||||
int ret;
|
||||
bool remove_from_hanger = true;
|
||||
struct sk_buff *skb;
|
||||
@ -1464,60 +1469,71 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
|
||||
brcmf_dbg(DATA, "flags %d\n", flags);
|
||||
|
||||
if (flags == BRCMF_FWS_TXSTATUS_DISCARD)
|
||||
fws->stats.txs_discard++;
|
||||
fws->stats.txs_discard += compcnt;
|
||||
else if (flags == BRCMF_FWS_TXSTATUS_CORE_SUPPRESS) {
|
||||
fws->stats.txs_supp_core++;
|
||||
fws->stats.txs_supp_core += compcnt;
|
||||
remove_from_hanger = false;
|
||||
} else if (flags == BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS) {
|
||||
fws->stats.txs_supp_ps++;
|
||||
fws->stats.txs_supp_ps += compcnt;
|
||||
remove_from_hanger = false;
|
||||
} else if (flags == BRCMF_FWS_TXSTATUS_FW_TOSSED)
|
||||
fws->stats.txs_tossed++;
|
||||
fws->stats.txs_tossed += compcnt;
|
||||
else if (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)
|
||||
fws->stats.txs_host_tossed++;
|
||||
fws->stats.txs_host_tossed += compcnt;
|
||||
else
|
||||
brcmf_err("unexpected txstatus\n");
|
||||
|
||||
ret = brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
|
||||
remove_from_hanger);
|
||||
if (ret != 0) {
|
||||
brcmf_err("no packet in hanger slot: hslot=%d\n", hslot);
|
||||
return ret;
|
||||
}
|
||||
while (cnt < compcnt) {
|
||||
ret = brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
|
||||
remove_from_hanger);
|
||||
if (ret != 0) {
|
||||
brcmf_err("no packet in hanger slot: hslot=%d\n",
|
||||
hslot);
|
||||
goto cont;
|
||||
}
|
||||
|
||||
skcb = brcmf_skbcb(skb);
|
||||
entry = skcb->mac;
|
||||
if (WARN_ON(!entry)) {
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
entry->transit_count--;
|
||||
if (entry->suppressed && entry->suppr_transit_count)
|
||||
entry->suppr_transit_count--;
|
||||
skcb = brcmf_skbcb(skb);
|
||||
entry = skcb->mac;
|
||||
if (WARN_ON(!entry)) {
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
goto cont;
|
||||
}
|
||||
entry->transit_count--;
|
||||
if (entry->suppressed && entry->suppr_transit_count)
|
||||
entry->suppr_transit_count--;
|
||||
|
||||
brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags,
|
||||
skcb->htod, seq);
|
||||
brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name,
|
||||
flags, skcb->htod, seq);
|
||||
|
||||
/* pick up the implicit credit from this packet */
|
||||
fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
|
||||
if ((fws->fcmode == BRCMF_FWS_FCMODE_IMPLIED_CREDIT) ||
|
||||
(brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) ||
|
||||
(flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)) {
|
||||
brcmf_fws_return_credits(fws, fifo, 1);
|
||||
brcmf_fws_schedule_deq(fws);
|
||||
}
|
||||
brcmf_fws_macdesc_return_req_credit(skb);
|
||||
/* pick up the implicit credit from this packet */
|
||||
fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
|
||||
if (fws->fcmode == BRCMF_FWS_FCMODE_IMPLIED_CREDIT ||
|
||||
(brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) ||
|
||||
flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED) {
|
||||
brcmf_fws_return_credits(fws, fifo, 1);
|
||||
brcmf_fws_schedule_deq(fws);
|
||||
}
|
||||
brcmf_fws_macdesc_return_req_credit(skb);
|
||||
|
||||
ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
|
||||
if (ret) {
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
return -EINVAL;
|
||||
ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
|
||||
if (ret) {
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
goto cont;
|
||||
}
|
||||
if (!remove_from_hanger)
|
||||
ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb,
|
||||
genbit, seq);
|
||||
if (remove_from_hanger || ret)
|
||||
brcmf_txfinalize(ifp, skb, true);
|
||||
|
||||
cont:
|
||||
hslot = (hslot + 1) & (BRCMF_FWS_TXSTAT_HSLOT_MASK >>
|
||||
BRCMF_FWS_TXSTAT_HSLOT_SHIFT);
|
||||
if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode))
|
||||
seq = (seq + 1) & BRCMF_SKB_HTOD_SEQ_NR_MASK;
|
||||
|
||||
cnt++;
|
||||
}
|
||||
if (!remove_from_hanger)
|
||||
ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb,
|
||||
genbit, seq);
|
||||
if (remove_from_hanger || ret)
|
||||
brcmf_txfinalize(ifp, skb, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1543,7 +1559,8 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
|
||||
return BRCMF_FWS_RET_OK_SCHEDULE;
|
||||
}
|
||||
|
||||
static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
|
||||
static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 type,
|
||||
u8 *data)
|
||||
{
|
||||
__le32 status_le;
|
||||
__le16 seq_le;
|
||||
@ -1552,23 +1569,31 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
|
||||
u32 genbit;
|
||||
u8 flags;
|
||||
u16 seq;
|
||||
u8 compcnt;
|
||||
u8 compcnt_offset = BRCMF_FWS_TYPE_TXSTATUS_LEN;
|
||||
|
||||
fws->stats.txs_indicate++;
|
||||
memcpy(&status_le, data, sizeof(status_le));
|
||||
status = le32_to_cpu(status_le);
|
||||
flags = brcmf_txstatus_get_field(status, FLAGS);
|
||||
hslot = brcmf_txstatus_get_field(status, HSLOT);
|
||||
genbit = brcmf_txstatus_get_field(status, GENERATION);
|
||||
if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
|
||||
memcpy(&seq_le, &data[BRCMF_FWS_TYPE_PKTTAG_LEN],
|
||||
memcpy(&seq_le, &data[BRCMF_FWS_TYPE_TXSTATUS_LEN],
|
||||
sizeof(seq_le));
|
||||
seq = le16_to_cpu(seq_le);
|
||||
compcnt_offset += BRCMF_FWS_TYPE_SEQ_LEN;
|
||||
} else {
|
||||
seq = 0;
|
||||
}
|
||||
|
||||
if (type == BRCMF_FWS_TYPE_COMP_TXSTATUS)
|
||||
compcnt = data[compcnt_offset];
|
||||
else
|
||||
compcnt = 1;
|
||||
fws->stats.txs_indicate += compcnt;
|
||||
|
||||
brcmf_fws_lock(fws);
|
||||
brcmf_fws_txs_process(fws, flags, hslot, genbit, seq);
|
||||
brcmf_fws_txs_process(fws, flags, hslot, genbit, seq, compcnt);
|
||||
brcmf_fws_unlock(fws);
|
||||
return BRCMF_FWS_RET_OK_NOSCHEDULE;
|
||||
}
|
||||
@ -1595,19 +1620,21 @@ static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
|
||||
brcmf_err("event payload too small (%d)\n", e->datalen);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (fws->creditmap_received)
|
||||
return 0;
|
||||
|
||||
fws->creditmap_received = true;
|
||||
|
||||
brcmf_dbg(TRACE, "enter: credits %pM\n", credits);
|
||||
brcmf_fws_lock(fws);
|
||||
for (i = 0; i < ARRAY_SIZE(fws->fifo_credit); i++) {
|
||||
if (*credits)
|
||||
fws->fifo_credit[i] += credits[i] - fws->init_fifo_credit[i];
|
||||
fws->init_fifo_credit[i] = credits[i];
|
||||
if (fws->fifo_credit[i] > 0)
|
||||
fws->fifo_credit_map |= 1 << i;
|
||||
else
|
||||
fws->fifo_credit_map &= ~(1 << i);
|
||||
fws->fifo_credit[i] = *credits++;
|
||||
WARN_ONCE(fws->fifo_credit[i] < 0,
|
||||
"fifo_credit[%d] is negative(%d)\n", i,
|
||||
fws->fifo_credit[i]);
|
||||
}
|
||||
brcmf_fws_schedule_deq(fws);
|
||||
brcmf_fws_unlock(fws);
|
||||
@ -1882,8 +1909,6 @@ void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb)
|
||||
|
||||
err = BRCMF_FWS_RET_OK_NOSCHEDULE;
|
||||
switch (type) {
|
||||
case BRCMF_FWS_TYPE_COMP_TXSTATUS:
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
|
||||
rd = (struct brcmf_skb_reorder_data *)skb->cb;
|
||||
rd->reorder = data;
|
||||
@ -1906,7 +1931,8 @@ void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb)
|
||||
err = brcmf_fws_request_indicate(fws, type, data);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_TXSTATUS:
|
||||
brcmf_fws_txstatus_indicate(fws, data);
|
||||
case BRCMF_FWS_TYPE_COMP_TXSTATUS:
|
||||
brcmf_fws_txstatus_indicate(fws, type, data);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_FIFO_CREDITBACK:
|
||||
err = brcmf_fws_fifocreditback_indicate(fws, data);
|
||||
@ -1995,7 +2021,7 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
|
||||
fws->stats.rollback_failed++;
|
||||
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
|
||||
brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
|
||||
hslot, 0, 0);
|
||||
hslot, 0, 0, 1);
|
||||
} else {
|
||||
fws->stats.rollback_success++;
|
||||
brcmf_fws_return_credits(fws, fifo, 1);
|
||||
@ -2013,7 +2039,7 @@ static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws)
|
||||
}
|
||||
|
||||
for (lender_ac = 0; lender_ac <= BRCMF_FWS_FIFO_AC_VO; lender_ac++) {
|
||||
if (fws->fifo_credit[lender_ac]) {
|
||||
if (fws->fifo_credit[lender_ac] > 0) {
|
||||
fws->credits_borrowed[lender_ac]++;
|
||||
fws->fifo_credit[lender_ac]--;
|
||||
if (fws->fifo_credit[lender_ac] == 0)
|
||||
@ -2210,8 +2236,9 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) &&
|
||||
(fifo == BRCMF_FWS_FIFO_BCMC))) {
|
||||
while ((fws->fifo_credit[fifo] > 0) ||
|
||||
((!fws->bcmc_credit_check) &&
|
||||
(fifo == BRCMF_FWS_FIFO_BCMC))) {
|
||||
skb = brcmf_fws_deq(fws, fifo);
|
||||
if (!skb)
|
||||
break;
|
||||
@ -2222,7 +2249,7 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
|
||||
break;
|
||||
}
|
||||
if ((fifo == BRCMF_FWS_FIFO_AC_BE) &&
|
||||
(fws->fifo_credit[fifo] == 0) &&
|
||||
(fws->fifo_credit[fifo] <= 0) &&
|
||||
(!fws->bus_flow_blocked)) {
|
||||
while (brcmf_fws_borrow_credit(fws) == 0) {
|
||||
skb = brcmf_fws_deq(fws, fifo);
|
||||
@ -2455,7 +2482,8 @@ void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
|
||||
}
|
||||
brcmf_fws_lock(fws);
|
||||
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
|
||||
brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0);
|
||||
brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0,
|
||||
1);
|
||||
brcmf_fws_unlock(fws);
|
||||
}
|
||||
|
||||
|
@ -2019,6 +2019,7 @@ static const struct dev_pm_ops brcmf_pciedrvr_pm = {
|
||||
static const struct pci_device_id brcmf_pcie_devid_table[] = {
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_RAW_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),
|
||||
|
@ -49,6 +49,11 @@
|
||||
#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500)
|
||||
#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500)
|
||||
|
||||
/* watermark expressed in number of words */
|
||||
#define DEFAULT_F2_WATERMARK 0x8
|
||||
#define CY_4373_F2_WATERMARK 0x40
|
||||
#define CY_43012_F2_WATERMARK 0x60
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#define BRCMF_TRAP_INFO_SIZE 80
|
||||
@ -138,6 +143,8 @@ struct rte_console {
|
||||
/* 1: isolate internal sdio signals, put external pads in tri-state; requires
|
||||
* sdio bus power cycle to clear (rev 9) */
|
||||
#define SBSDIO_DEVCTL_PADS_ISO 0x08
|
||||
/* 1: enable F2 Watermark */
|
||||
#define SBSDIO_DEVCTL_F2WM_ENAB 0x10
|
||||
/* Force SD->SB reset mapping (rev 11) */
|
||||
#define SBSDIO_DEVCTL_SB_RST_CTL 0x30
|
||||
/* Determined by CoreControl bit */
|
||||
@ -618,6 +625,7 @@ BRCMF_FW_DEF(43455, "brcmfmac43455-sdio");
|
||||
BRCMF_FW_DEF(4354, "brcmfmac4354-sdio");
|
||||
BRCMF_FW_DEF(4356, "brcmfmac4356-sdio");
|
||||
BRCMF_FW_DEF(4373, "brcmfmac4373-sdio");
|
||||
BRCMF_FW_DEF(43012, "brcmfmac43012-sdio");
|
||||
|
||||
static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
|
||||
@ -637,7 +645,8 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
|
||||
BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373)
|
||||
BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373),
|
||||
BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012)
|
||||
};
|
||||
|
||||
static void pkt_align(struct sk_buff *p, int len, int align)
|
||||
@ -671,6 +680,14 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
|
||||
/* 1st KSO write goes to AOS wake up core if device is asleep */
|
||||
brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err);
|
||||
|
||||
/* In case of 43012 chip, the chip could go down immediately after
|
||||
* KSO bit is cleared. So the further reads of KSO register could
|
||||
* fail. Thereby just bailing out immediately after clearing KSO
|
||||
* bit, to avoid polling of KSO bit.
|
||||
*/
|
||||
if (!on && bus->ci->chip == CY_CC_43012_CHIP_ID)
|
||||
return err;
|
||||
|
||||
if (on) {
|
||||
/* device WAKEUP through KSO:
|
||||
* write bit 0 & read back until
|
||||
@ -2396,6 +2413,14 @@ static int brcmf_sdio_tx_ctrlframe(struct brcmf_sdio *bus, u8 *frame, u16 len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool brcmf_chip_is_ulp(struct brcmf_chip *ci)
|
||||
{
|
||||
if (ci->chip == CY_CC_43012_CHIP_ID)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static void brcmf_sdio_bus_stop(struct device *dev)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
@ -2403,7 +2428,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
|
||||
struct brcmf_sdio *bus = sdiodev->bus;
|
||||
struct brcmf_core *core = bus->sdio_core;
|
||||
u32 local_hostintmask;
|
||||
u8 saveclk;
|
||||
u8 saveclk, bpreq;
|
||||
int err;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
@ -2430,9 +2455,14 @@ static void brcmf_sdio_bus_stop(struct device *dev)
|
||||
/* Force backplane clocks to assure F2 interrupt propagates */
|
||||
saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
&err);
|
||||
if (!err)
|
||||
brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
(saveclk | SBSDIO_FORCE_HT), &err);
|
||||
if (!err) {
|
||||
bpreq = saveclk;
|
||||
bpreq |= brcmf_chip_is_ulp(bus->ci) ?
|
||||
SBSDIO_HT_AVAIL_REQ : SBSDIO_FORCE_HT;
|
||||
brcmf_sdiod_writeb(sdiodev,
|
||||
SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
bpreq, &err);
|
||||
}
|
||||
if (err)
|
||||
brcmf_err("Failed to force clock for F2: err %d\n",
|
||||
err);
|
||||
@ -3322,20 +3352,49 @@ err:
|
||||
return bcmerror;
|
||||
}
|
||||
|
||||
static bool brcmf_sdio_aos_no_decode(struct brcmf_sdio *bus)
|
||||
{
|
||||
if (bus->ci->chip == CY_CC_43012_CHIP_ID ||
|
||||
bus->ci->chip == CY_CC_4373_CHIP_ID ||
|
||||
bus->ci->chip == BRCM_CC_4339_CHIP_ID ||
|
||||
bus->ci->chip == BRCM_CC_4345_CHIP_ID ||
|
||||
bus->ci->chip == BRCM_CC_4354_CHIP_ID)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
|
||||
{
|
||||
int err = 0;
|
||||
u8 val;
|
||||
u8 wakeupctrl;
|
||||
u8 cardcap;
|
||||
u8 chipclkcsr;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
if (brcmf_chip_is_ulp(bus->ci)) {
|
||||
wakeupctrl = SBSDIO_FUNC1_WCTRL_ALPWAIT_SHIFT;
|
||||
chipclkcsr = SBSDIO_HT_AVAIL_REQ;
|
||||
} else {
|
||||
wakeupctrl = SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
|
||||
chipclkcsr = SBSDIO_FORCE_HT;
|
||||
}
|
||||
|
||||
if (brcmf_sdio_aos_no_decode(bus)) {
|
||||
cardcap = SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC;
|
||||
} else {
|
||||
cardcap = (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
|
||||
SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT);
|
||||
}
|
||||
|
||||
val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err);
|
||||
if (err) {
|
||||
brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
|
||||
val |= 1 << wakeupctrl;
|
||||
brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err);
|
||||
if (err) {
|
||||
brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n");
|
||||
@ -3344,8 +3403,7 @@ static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
|
||||
|
||||
/* Add CMD14 Support */
|
||||
brcmf_sdiod_func0_wb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP,
|
||||
(SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
|
||||
SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT),
|
||||
cardcap,
|
||||
&err);
|
||||
if (err) {
|
||||
brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n");
|
||||
@ -3353,7 +3411,7 @@ static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
|
||||
}
|
||||
|
||||
brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
SBSDIO_FORCE_HT, &err);
|
||||
chipclkcsr, &err);
|
||||
if (err) {
|
||||
brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n");
|
||||
return;
|
||||
@ -4045,7 +4103,8 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
|
||||
const struct firmware *code;
|
||||
void *nvram;
|
||||
u32 nvram_len;
|
||||
u8 saveclk;
|
||||
u8 saveclk, bpreq;
|
||||
u8 devctl;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
|
||||
|
||||
@ -4078,8 +4137,11 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
|
||||
/* Force clocks on backplane to be sure F2 interrupt propagates */
|
||||
saveclk = brcmf_sdiod_readb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR, &err);
|
||||
if (!err) {
|
||||
bpreq = saveclk;
|
||||
bpreq |= brcmf_chip_is_ulp(bus->ci) ?
|
||||
SBSDIO_HT_AVAIL_REQ : SBSDIO_FORCE_HT;
|
||||
brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
(saveclk | SBSDIO_FORCE_HT), &err);
|
||||
bpreq, &err);
|
||||
}
|
||||
if (err) {
|
||||
brcmf_err("Failed to force clock for F2: err %d\n", err);
|
||||
@ -4101,8 +4163,37 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
|
||||
brcmf_sdiod_writel(sdiod, core->base + SD_REG(hostintmask),
|
||||
bus->hostintmask, NULL);
|
||||
|
||||
|
||||
brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, 8, &err);
|
||||
switch (sdiod->func1->device) {
|
||||
case SDIO_DEVICE_ID_CYPRESS_4373:
|
||||
brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes\n",
|
||||
CY_4373_F2_WATERMARK);
|
||||
brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK,
|
||||
CY_4373_F2_WATERMARK, &err);
|
||||
devctl = brcmf_sdiod_readb(sdiod, SBSDIO_DEVICE_CTL,
|
||||
&err);
|
||||
devctl |= SBSDIO_DEVCTL_F2WM_ENAB;
|
||||
brcmf_sdiod_writeb(sdiod, SBSDIO_DEVICE_CTL, devctl,
|
||||
&err);
|
||||
brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_MESBUSYCTRL,
|
||||
CY_4373_F2_WATERMARK |
|
||||
SBSDIO_MESBUSYCTRL_ENAB, &err);
|
||||
break;
|
||||
case SDIO_DEVICE_ID_CYPRESS_43012:
|
||||
brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes\n",
|
||||
CY_43012_F2_WATERMARK);
|
||||
brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK,
|
||||
CY_43012_F2_WATERMARK, &err);
|
||||
devctl = brcmf_sdiod_readb(sdiod, SBSDIO_DEVICE_CTL,
|
||||
&err);
|
||||
devctl |= SBSDIO_DEVCTL_F2WM_ENAB;
|
||||
brcmf_sdiod_writeb(sdiod, SBSDIO_DEVICE_CTL, devctl,
|
||||
&err);
|
||||
break;
|
||||
default:
|
||||
brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK,
|
||||
DEFAULT_F2_WATERMARK, &err);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Disable F2 again */
|
||||
sdio_disable_func(sdiod->func2);
|
||||
|
@ -77,7 +77,7 @@
|
||||
#define SBSDIO_GPIO_OUT 0x10006
|
||||
/* gpio enable */
|
||||
#define SBSDIO_GPIO_EN 0x10007
|
||||
/* rev < 7, watermark for sdio device */
|
||||
/* rev < 7, watermark for sdio device TX path */
|
||||
#define SBSDIO_WATERMARK 0x10008
|
||||
/* control busy signal generation */
|
||||
#define SBSDIO_DEVICE_CTL 0x10009
|
||||
@ -104,6 +104,13 @@
|
||||
#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C
|
||||
/* MesBusyCtl (rev 11) */
|
||||
#define SBSDIO_FUNC1_MESBUSYCTRL 0x1001D
|
||||
/* Watermark for sdio device RX path */
|
||||
#define SBSDIO_MESBUSY_RXFIFO_WM_MASK 0x7F
|
||||
#define SBSDIO_MESBUSY_RXFIFO_WM_SHIFT 0
|
||||
/* Enable busy capability for MES access */
|
||||
#define SBSDIO_MESBUSYCTRL_ENAB 0x80
|
||||
#define SBSDIO_MESBUSYCTRL_ENAB_SHIFT 7
|
||||
|
||||
/* Sdio Core Rev 12 */
|
||||
#define SBSDIO_FUNC1_WAKEUPCTRL 0x1001E
|
||||
#define SBSDIO_FUNC1_WCTRL_ALPWAIT_MASK 0x1
|
||||
|
@ -60,6 +60,7 @@
|
||||
#define BRCM_CC_43664_CHIP_ID 43664
|
||||
#define BRCM_CC_4371_CHIP_ID 0x4371
|
||||
#define CY_CC_4373_CHIP_ID 0x4373
|
||||
#define CY_CC_43012_CHIP_ID 43012
|
||||
|
||||
/* USB Device IDs */
|
||||
#define BRCM_USB_43143_DEVICE_ID 0xbd1e
|
||||
@ -74,6 +75,7 @@
|
||||
/* PCIE Device IDs */
|
||||
#define BRCM_PCIE_4350_DEVICE_ID 0x43a3
|
||||
#define BRCM_PCIE_4354_DEVICE_ID 0x43df
|
||||
#define BRCM_PCIE_4354_RAW_DEVICE_ID 0x4354
|
||||
#define BRCM_PCIE_4356_DEVICE_ID 0x43ec
|
||||
#define BRCM_PCIE_43567_DEVICE_ID 0x43d3
|
||||
#define BRCM_PCIE_43570_DEVICE_ID 0x43d9
|
||||
|
@ -269,6 +269,25 @@ struct chipcregs {
|
||||
/* GSIO (spi/i2c) present, rev >= 37 */
|
||||
#define CC_CAP2_GSIO 0x00000002
|
||||
|
||||
/* sr_control0, rev >= 48 */
|
||||
#define CC_SR_CTL0_ENABLE_MASK BIT(0)
|
||||
#define CC_SR_CTL0_ENABLE_SHIFT 0
|
||||
#define CC_SR_CTL0_EN_SR_ENG_CLK_SHIFT 1 /* sr_clk to sr_memory enable */
|
||||
#define CC_SR_CTL0_RSRC_TRIGGER_SHIFT 2 /* Rising edge resource trigger 0 to
|
||||
* sr_engine
|
||||
*/
|
||||
#define CC_SR_CTL0_MIN_DIV_SHIFT 6 /* Min division value for fast clk
|
||||
* in sr_engine
|
||||
*/
|
||||
#define CC_SR_CTL0_EN_SBC_STBY_SHIFT 16
|
||||
#define CC_SR_CTL0_EN_SR_ALP_CLK_MASK_SHIFT 18
|
||||
#define CC_SR_CTL0_EN_SR_HT_CLK_SHIFT 19
|
||||
#define CC_SR_CTL0_ALLOW_PIC_SHIFT 20 /* Allow pic to separate power
|
||||
* domains
|
||||
*/
|
||||
#define CC_SR_CTL0_MAX_SR_LQ_CLK_CNT_SHIFT 25
|
||||
#define CC_SR_CTL0_EN_MEM_DISABLE_FOR_SLEEP 30
|
||||
|
||||
/* pmucapabilities */
|
||||
#define PCAP_REV_MASK 0x000000ff
|
||||
#define PCAP_RC_MASK 0x00001f00
|
||||
|
@ -5603,12 +5603,8 @@ static void shim__set_security(struct net_device *dev,
|
||||
|
||||
if ((sec->flags & SEC_ACTIVE_KEY) &&
|
||||
priv->ieee->sec.active_key != sec->active_key) {
|
||||
if (sec->active_key <= 3) {
|
||||
priv->ieee->sec.active_key = sec->active_key;
|
||||
priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
|
||||
} else
|
||||
priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
|
||||
|
||||
priv->ieee->sec.active_key = sec->active_key;
|
||||
priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
|
||||
priv->status |= STATUS_SECURITY_UPDATED;
|
||||
}
|
||||
|
||||
|
@ -10722,11 +10722,8 @@ static void shim__set_security(struct net_device *dev,
|
||||
}
|
||||
|
||||
if (sec->flags & SEC_ACTIVE_KEY) {
|
||||
if (sec->active_key <= 3) {
|
||||
priv->ieee->sec.active_key = sec->active_key;
|
||||
priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
|
||||
} else
|
||||
priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
|
||||
priv->ieee->sec.active_key = sec->active_key;
|
||||
priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
|
||||
priv->status |= STATUS_SECURITY_UPDATED;
|
||||
} else
|
||||
priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
|
||||
|
@ -1,6 +1,6 @@
|
||||
config IWLWIFI
|
||||
tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) "
|
||||
depends on PCI && MAC80211 && HAS_IOMEM
|
||||
depends on PCI && HAS_IOMEM
|
||||
select FW_LOADER
|
||||
---help---
|
||||
Select to build the driver supporting the:
|
||||
@ -53,6 +53,7 @@ config IWLWIFI_LEDS
|
||||
|
||||
config IWLDVM
|
||||
tristate "Intel Wireless WiFi DVM Firmware support"
|
||||
depends on MAC80211
|
||||
help
|
||||
This is the driver that supports the DVM firmware. The list
|
||||
of the devices that use this firmware is available here:
|
||||
@ -61,6 +62,7 @@ config IWLDVM
|
||||
config IWLMVM
|
||||
tristate "Intel Wireless WiFi MVM Firmware support"
|
||||
select WANT_DEV_COREDUMP
|
||||
depends on MAC80211
|
||||
help
|
||||
This is the driver that supports the MVM firmware. The list
|
||||
of the devices that use this firmware is available here:
|
||||
|
@ -48,7 +48,7 @@
|
||||
static const struct iwl_base_params iwl1000_base_params = {
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.pll_cfg = true,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_1000,
|
||||
.shadow_ram_support = false,
|
||||
|
@ -57,7 +57,7 @@
|
||||
#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl2000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
|
||||
@ -71,7 +71,7 @@ static const struct iwl_base_params iwl2000_base_params = {
|
||||
|
||||
|
||||
static const struct iwl_base_params iwl2030_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
|
||||
|
@ -56,14 +56,13 @@
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_22000_UCODE_API_MAX 41
|
||||
#define IWL_22000_UCODE_API_MAX 43
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_22000_UCODE_API_MIN 39
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_22000_NVM_VERSION 0x0a1d
|
||||
#define IWL_22000_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL_22000_DCCM_OFFSET 0x800000 /* LMAC1 */
|
||||
@ -106,10 +105,8 @@
|
||||
#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_22000 10
|
||||
|
||||
static const struct iwl_base_params iwl_22000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_22000,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 256,
|
||||
.shadow_ram_support = true,
|
||||
@ -121,7 +118,7 @@ static const struct iwl_base_params iwl_22000_base_params = {
|
||||
};
|
||||
|
||||
static const struct iwl_base_params iwl_22560_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_22000,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 65536,
|
||||
.shadow_ram_support = true,
|
||||
@ -142,7 +139,7 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
|
||||
.ucode_api_max = IWL_22000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL_22000_UCODE_API_MIN, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_22000, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.dccm_offset = IWL_22000_DCCM_OFFSET, \
|
||||
.dccm_len = IWL_22000_DCCM_LEN, \
|
||||
@ -157,7 +154,6 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
|
||||
.mac_addr_from_csr = true, \
|
||||
.ht_params = &iwl_22000_ht_params, \
|
||||
.nvm_ver = IWL_22000_NVM_VERSION, \
|
||||
.nvm_calib_ver = IWL_22000_TX_POWER_VERSION, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.use_tfh = true, \
|
||||
.rf_id = true, \
|
||||
|
@ -66,7 +66,7 @@
|
||||
#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl6000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
@ -79,7 +79,7 @@ static const struct iwl_base_params iwl6000_base_params = {
|
||||
};
|
||||
|
||||
static const struct iwl_base_params iwl6050_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
|
||||
@ -92,7 +92,7 @@ static const struct iwl_base_params iwl6050_base_params = {
|
||||
};
|
||||
|
||||
static const struct iwl_base_params iwl6000_g2_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
|
@ -80,17 +80,11 @@
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL7260_NVM_VERSION 0x0a1d
|
||||
#define IWL7260_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
#define IWL3160_NVM_VERSION 0x709
|
||||
#define IWL3160_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
#define IWL3165_NVM_VERSION 0x709
|
||||
#define IWL3165_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
#define IWL3168_NVM_VERSION 0xd01
|
||||
#define IWL3168_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
#define IWL7265_NVM_VERSION 0x0a1d
|
||||
#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
#define IWL7265D_NVM_VERSION 0x0c11
|
||||
#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
|
||||
/* DCCM offsets and lengths */
|
||||
#define IWL7000_DCCM_OFFSET 0x800000
|
||||
@ -113,10 +107,8 @@
|
||||
#define IWL7265D_FW_PRE "iwlwifi-7265D-"
|
||||
#define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_7000 0
|
||||
|
||||
static const struct iwl_base_params iwl7000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_7000,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_16K,
|
||||
.num_of_queues = 31,
|
||||
.max_tfd_queue_size = 256,
|
||||
.shadow_ram_support = true,
|
||||
@ -159,7 +151,7 @@ static const struct iwl_ht_params iwl7000_ht_params = {
|
||||
.device_family = IWL_DEVICE_FAMILY_7000, \
|
||||
.base_params = &iwl7000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000, \
|
||||
.nvm_hw_section_num = 0, \
|
||||
.non_shared_ant = ANT_A, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.dccm_offset = IWL7000_DCCM_OFFSET, \
|
||||
@ -191,7 +183,6 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
@ -203,7 +194,6 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.high_temp = true,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
@ -217,7 +207,6 @@ const struct iwl_cfg iwl7260_2n_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
@ -229,7 +218,6 @@ const struct iwl_cfg iwl7260_n_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
@ -241,7 +229,6 @@ const struct iwl_cfg iwl3160_2ac_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
};
|
||||
@ -252,7 +239,6 @@ const struct iwl_cfg iwl3160_2n_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
};
|
||||
@ -263,7 +249,6 @@ const struct iwl_cfg iwl3160_n_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
};
|
||||
@ -291,7 +276,6 @@ const struct iwl_cfg iwl3165_2ac_cfg = {
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3165_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3165_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -302,7 +286,6 @@ const struct iwl_cfg iwl3168_2ac_cfg = {
|
||||
IWL_DEVICE_3008,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3168_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3168_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
.nvm_type = IWL_NVM_SDP,
|
||||
@ -314,7 +297,6 @@ const struct iwl_cfg iwl7265_2ac_cfg = {
|
||||
IWL_DEVICE_7005,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -325,7 +307,6 @@ const struct iwl_cfg iwl7265_2n_cfg = {
|
||||
IWL_DEVICE_7005,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -336,7 +317,6 @@ const struct iwl_cfg iwl7265_n_cfg = {
|
||||
IWL_DEVICE_7005,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -347,7 +327,6 @@ const struct iwl_cfg iwl7265d_2ac_cfg = {
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -358,7 +337,6 @@ const struct iwl_cfg iwl7265d_2n_cfg = {
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -369,7 +347,6 @@ const struct iwl_cfg iwl7265d_n_cfg = {
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
@ -75,7 +75,6 @@
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL8000_NVM_VERSION 0x0a1d
|
||||
#define IWL8000_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL8260_DCCM_OFFSET 0x800000
|
||||
@ -93,11 +92,10 @@
|
||||
#define IWL8265_MODULE_FIRMWARE(api) \
|
||||
IWL8265_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_8000 10
|
||||
#define DEFAULT_NVM_FILE_FAMILY_8000C "nvmData-8000C"
|
||||
|
||||
static const struct iwl_base_params iwl8000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_8000,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
.num_of_queues = 31,
|
||||
.max_tfd_queue_size = 256,
|
||||
.shadow_ram_support = true,
|
||||
@ -139,7 +137,7 @@ static const struct iwl_tt_params iwl8000_tt_params = {
|
||||
.device_family = IWL_DEVICE_FAMILY_8000, \
|
||||
.base_params = &iwl8000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.features = NETIF_F_RXCSUM, \
|
||||
.non_shared_ant = ANT_A, \
|
||||
.dccm_offset = IWL8260_DCCM_OFFSET, \
|
||||
@ -177,7 +175,6 @@ const struct iwl_cfg iwl8260_2n_cfg = {
|
||||
IWL_DEVICE_8260,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl8260_2ac_cfg = {
|
||||
@ -186,7 +183,6 @@ const struct iwl_cfg iwl8260_2ac_cfg = {
|
||||
IWL_DEVICE_8260,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
@ -196,7 +192,6 @@ const struct iwl_cfg iwl8265_2ac_cfg = {
|
||||
IWL_DEVICE_8265,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.vht_mu_mimo_supported = true,
|
||||
};
|
||||
@ -207,7 +202,6 @@ const struct iwl_cfg iwl8275_2ac_cfg = {
|
||||
IWL_DEVICE_8265,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.vht_mu_mimo_supported = true,
|
||||
};
|
||||
@ -218,7 +212,6 @@ const struct iwl_cfg iwl4165_2ac_cfg = {
|
||||
IWL_DEVICE_8000,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
|
@ -57,14 +57,13 @@
|
||||
#include "fw/file.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL9000_UCODE_API_MAX 41
|
||||
#define IWL9000_UCODE_API_MAX 43
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL9000_UCODE_API_MIN 30
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL9000_NVM_VERSION 0x0a1d
|
||||
#define IWL9000_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL9000_DCCM_OFFSET 0x800000
|
||||
@ -90,10 +89,8 @@
|
||||
#define IWL9260B_MODULE_FIRMWARE(api) \
|
||||
IWL9260B_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_9000 10
|
||||
|
||||
static const struct iwl_base_params iwl9000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_9000,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
.num_of_queues = 31,
|
||||
.max_tfd_queue_size = 256,
|
||||
.shadow_ram_support = true,
|
||||
@ -137,7 +134,7 @@ static const struct iwl_tt_params iwl9000_tt_params = {
|
||||
.device_family = IWL_DEVICE_FAMILY_9000, \
|
||||
.base_params = &iwl9000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_9000, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.dccm_offset = IWL9000_DCCM_OFFSET, \
|
||||
.dccm_len = IWL9000_DCCM_LEN, \
|
||||
@ -157,17 +154,17 @@ static const struct iwl_tt_params iwl9000_tt_params = {
|
||||
.min_umac_error_event_table = 0x800000, \
|
||||
.csr = &iwl_csr_v1, \
|
||||
.d3_debug_data_base_addr = 0x401000, \
|
||||
.d3_debug_data_length = 92 * 1024
|
||||
.d3_debug_data_length = 92 * 1024, \
|
||||
.ht_params = &iwl9000_ht_params, \
|
||||
.nvm_ver = IWL9000_NVM_VERSION, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
|
||||
const struct iwl_cfg iwl9160_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 9160",
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9260_2ac_cfg = {
|
||||
@ -175,10 +172,6 @@ const struct iwl_cfg iwl9260_2ac_cfg = {
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9260_killer_2ac_cfg = {
|
||||
@ -186,10 +179,6 @@ const struct iwl_cfg iwl9260_killer_2ac_cfg = {
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9270_2ac_cfg = {
|
||||
@ -197,10 +186,6 @@ const struct iwl_cfg iwl9270_2ac_cfg = {
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9460_2ac_cfg = {
|
||||
@ -208,10 +193,6 @@ const struct iwl_cfg iwl9460_2ac_cfg = {
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9460_2ac_cfg_soc = {
|
||||
@ -220,10 +201,6 @@ const struct iwl_cfg iwl9460_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -234,10 +211,6 @@ const struct iwl_cfg iwl9461_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -248,10 +221,6 @@ const struct iwl_cfg iwl9462_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -261,10 +230,6 @@ const struct iwl_cfg iwl9560_2ac_cfg = {
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9560_2ac_cfg_soc = {
|
||||
@ -273,10 +238,6 @@ const struct iwl_cfg iwl9560_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -287,10 +248,6 @@ const struct iwl_cfg iwl9560_killer_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -301,10 +258,6 @@ const struct iwl_cfg iwl9560_killer_s_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -315,10 +268,6 @@ const struct iwl_cfg iwl9460_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
@ -330,10 +279,6 @@ const struct iwl_cfg iwl9461_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
@ -345,10 +290,6 @@ const struct iwl_cfg iwl9462_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
@ -360,10 +301,6 @@ const struct iwl_cfg iwl9560_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
@ -375,10 +312,6 @@ const struct iwl_cfg iwl9560_killer_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
@ -390,10 +323,6 @@ const struct iwl_cfg iwl9560_killer_s_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
|
@ -1224,6 +1224,23 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_nvm_check_version(struct iwl_nvm_data *data,
|
||||
struct iwl_trans *trans)
|
||||
{
|
||||
if (data->nvm_version >= trans->cfg->nvm_ver ||
|
||||
data->calib_version >= trans->cfg->nvm_calib_ver) {
|
||||
IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n",
|
||||
data->nvm_version, data->calib_version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWL_ERR(trans,
|
||||
"Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
|
||||
data->nvm_version, trans->cfg->nvm_ver,
|
||||
data->calib_version, trans->cfg->nvm_calib_ver);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
const struct iwl_cfg *cfg,
|
||||
const struct iwl_fw *fw,
|
||||
|
@ -8,6 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -30,6 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -127,17 +129,6 @@ struct iwl_phy_cfg_cmd {
|
||||
struct iwl_calib_ctrl calib_control;
|
||||
} __packed;
|
||||
|
||||
#define PHY_CFG_RADIO_TYPE (BIT(0) | BIT(1))
|
||||
#define PHY_CFG_RADIO_STEP (BIT(2) | BIT(3))
|
||||
#define PHY_CFG_RADIO_DASH (BIT(4) | BIT(5))
|
||||
#define PHY_CFG_PRODUCT_NUMBER (BIT(6) | BIT(7))
|
||||
#define PHY_CFG_TX_CHAIN_A BIT(8)
|
||||
#define PHY_CFG_TX_CHAIN_B BIT(9)
|
||||
#define PHY_CFG_TX_CHAIN_C BIT(10)
|
||||
#define PHY_CFG_RX_CHAIN_A BIT(12)
|
||||
#define PHY_CFG_RX_CHAIN_B BIT(13)
|
||||
#define PHY_CFG_RX_CHAIN_C BIT(14)
|
||||
|
||||
/*
|
||||
* enum iwl_dc2dc_config_id - flag ids
|
||||
*
|
||||
|
@ -104,6 +104,11 @@ enum iwl_data_path_subcmd_ids {
|
||||
*/
|
||||
HE_AIR_SNIFFER_CONFIG_CMD = 0x13,
|
||||
|
||||
/**
|
||||
* @RX_NO_DATA_NOTIF: &struct iwl_rx_no_data
|
||||
*/
|
||||
RX_NO_DATA_NOTIF = 0xF5,
|
||||
|
||||
/**
|
||||
* @TLC_MNG_UPDATE_NOTIF: &struct iwl_tlc_update_notif
|
||||
*/
|
||||
|
@ -443,7 +443,7 @@ struct iwl_he_backoff_conf {
|
||||
* Support for Nss x BW (or RU) matrix:
|
||||
* (0=SISO, 1=MIMO2) x (0-20MHz, 1-40MHz, 2-80MHz, 3-160MHz)
|
||||
* Each entry contains 2 QAM thresholds for 8us and 16us:
|
||||
* 0=BPSK, 1=QPSK, 2=16QAM, 3=64QAM, 4=256QAM, 5=1024QAM, 6/7=RES
|
||||
* 0=BPSK, 1=QPSK, 2=16QAM, 3=64QAM, 4=256QAM, 5=1024QAM, 6=RES, 7=NONE
|
||||
* i.e. QAM_th1 < QAM_th2 such if TX uses QAM_tx:
|
||||
* QAM_tx < QAM_th1 --> PPE=0us
|
||||
* QAM_th1 <= QAM_tx < QAM_th2 --> PPE=8us
|
||||
|
@ -345,66 +345,98 @@ enum iwl_rx_mpdu_mac_info {
|
||||
IWL_RX_MPDU_PHY_PHY_INDEX_MASK = 0xf0,
|
||||
};
|
||||
|
||||
/*
|
||||
* enum iwl_rx_he_phy - HE PHY data
|
||||
*/
|
||||
enum iwl_rx_he_phy {
|
||||
IWL_RX_HE_PHY_BEAM_CHNG = BIT(0),
|
||||
IWL_RX_HE_PHY_UPLINK = BIT(1),
|
||||
IWL_RX_HE_PHY_BSS_COLOR_MASK = 0xfc,
|
||||
IWL_RX_HE_PHY_SPATIAL_REUSE_MASK = 0xf00,
|
||||
IWL_RX_HE_PHY_SU_EXT_BW10 = BIT(12),
|
||||
IWL_RX_HE_PHY_TXOP_DUR_MASK = 0xfe000,
|
||||
IWL_RX_HE_PHY_LDPC_EXT_SYM = BIT(20),
|
||||
IWL_RX_HE_PHY_PRE_FEC_PAD_MASK = 0x600000,
|
||||
IWL_RX_HE_PHY_PE_DISAMBIG = BIT(23),
|
||||
IWL_RX_HE_PHY_DOPPLER = BIT(24),
|
||||
/* TSF overload low dword */
|
||||
enum iwl_rx_phy_data0 {
|
||||
/* info type: HE any */
|
||||
IWL_RX_PHY_DATA0_HE_BEAM_CHNG = 0x00000001,
|
||||
IWL_RX_PHY_DATA0_HE_UPLINK = 0x00000002,
|
||||
IWL_RX_PHY_DATA0_HE_BSS_COLOR_MASK = 0x000000fc,
|
||||
IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK = 0x00000f00,
|
||||
/* 1 bit reserved */
|
||||
IWL_RX_PHY_DATA0_HE_TXOP_DUR_MASK = 0x000fe000,
|
||||
IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM = 0x00100000,
|
||||
IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK = 0x00600000,
|
||||
IWL_RX_PHY_DATA0_HE_PE_DISAMBIG = 0x00800000,
|
||||
IWL_RX_PHY_DATA0_HE_DOPPLER = 0x01000000,
|
||||
/* 6 bits reserved */
|
||||
IWL_RX_HE_PHY_DELIM_EOF = BIT(31),
|
||||
IWL_RX_PHY_DATA0_HE_DELIM_EOF = 0x80000000,
|
||||
};
|
||||
|
||||
/* second dword - common data */
|
||||
IWL_RX_HE_PHY_HE_LTF_NUM_MASK = 0xe000000000ULL,
|
||||
IWL_RX_HE_PHY_RU_ALLOC_SEC80 = BIT_ULL(32 + 8),
|
||||
enum iwl_rx_phy_info_type {
|
||||
IWL_RX_PHY_INFO_TYPE_NONE = 0,
|
||||
IWL_RX_PHY_INFO_TYPE_CCK = 1,
|
||||
IWL_RX_PHY_INFO_TYPE_OFDM_LGCY = 2,
|
||||
IWL_RX_PHY_INFO_TYPE_HT = 3,
|
||||
IWL_RX_PHY_INFO_TYPE_VHT_SU = 4,
|
||||
IWL_RX_PHY_INFO_TYPE_VHT_MU = 5,
|
||||
IWL_RX_PHY_INFO_TYPE_HE_SU = 6,
|
||||
IWL_RX_PHY_INFO_TYPE_HE_MU = 7,
|
||||
IWL_RX_PHY_INFO_TYPE_HE_TB = 8,
|
||||
IWL_RX_PHY_INFO_TYPE_HE_MU_EXT = 9,
|
||||
IWL_RX_PHY_INFO_TYPE_HE_TB_EXT = 10,
|
||||
};
|
||||
|
||||
/* TSF overload high dword */
|
||||
enum iwl_rx_phy_data1 {
|
||||
/*
|
||||
* check this first - if TSF overload is set,
|
||||
* see &enum iwl_rx_phy_info_type
|
||||
*/
|
||||
IWL_RX_PHY_DATA1_INFO_TYPE_MASK = 0xf0000000,
|
||||
|
||||
/* info type: HT/VHT/HE any */
|
||||
IWL_RX_PHY_DATA1_LSIG_LEN_MASK = 0x0fff0000,
|
||||
|
||||
/* info type: HE MU/MU-EXT */
|
||||
IWL_RX_PHY_DATA1_HE_MU_SIGB_COMPRESSION = 0x00000001,
|
||||
IWL_RX_PHY_DATA1_HE_MU_SIBG_SYM_OR_USER_NUM_MASK = 0x0000001e,
|
||||
|
||||
/* info type: HE any */
|
||||
IWL_RX_PHY_DATA1_HE_LTF_NUM_MASK = 0x000000e0,
|
||||
IWL_RX_PHY_DATA1_HE_RU_ALLOC_SEC80 = 0x00000100,
|
||||
/* trigger encoded */
|
||||
IWL_RX_HE_PHY_RU_ALLOC_MASK = 0xfe0000000000ULL,
|
||||
IWL_RX_HE_PHY_INFO_TYPE_MASK = 0xf000000000000000ULL,
|
||||
IWL_RX_HE_PHY_INFO_TYPE_SU = 0x0, /* TSF low valid (first DW) */
|
||||
IWL_RX_HE_PHY_INFO_TYPE_MU = 0x1, /* TSF low/high valid (both DWs) */
|
||||
IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO = 0x2, /* same + SIGB-common0/1/2 valid */
|
||||
IWL_RX_HE_PHY_INFO_TYPE_TB = 0x3, /* TSF low/high valid (both DWs) */
|
||||
IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK = 0x0000fe00,
|
||||
|
||||
/* second dword - MU data */
|
||||
IWL_RX_HE_PHY_MU_SIGB_COMPRESSION = BIT_ULL(32 + 0),
|
||||
IWL_RX_HE_PHY_MU_SIBG_SYM_OR_USER_NUM_MASK = 0x1e00000000ULL,
|
||||
IWL_RX_HE_PHY_MU_SIGB_MCS_MASK = 0xf000000000000ULL,
|
||||
IWL_RX_HE_PHY_MU_SIGB_DCM = BIT_ULL(32 + 21),
|
||||
IWL_RX_HE_PHY_MU_PREAMBLE_PUNC_TYPE_MASK = 0xc0000000000000ULL,
|
||||
|
||||
/* second dword - TB data */
|
||||
IWL_RX_HE_PHY_TB_PILOT_TYPE = BIT_ULL(32 + 0),
|
||||
IWL_RX_HE_PHY_TB_LOW_SS_MASK = 0xe00000000ULL
|
||||
/* info type: HE TB/TX-EXT */
|
||||
IWL_RX_PHY_DATA1_HE_TB_PILOT_TYPE = 0x00000001,
|
||||
IWL_RX_PHY_DATA1_HE_TB_LOW_SS_MASK = 0x0000000e,
|
||||
};
|
||||
|
||||
enum iwl_rx_he_sigb_common0 {
|
||||
/* goes into Metadata DW 7 */
|
||||
enum iwl_rx_phy_data2 {
|
||||
/* info type: HE MU-EXT */
|
||||
/* the a1/a2/... is what the PHY/firmware calls the values */
|
||||
IWL_RX_HE_SIGB_COMMON0_CH1_RU0 = 0x000000ff, /* a1 */
|
||||
IWL_RX_HE_SIGB_COMMON0_CH1_RU2 = 0x0000ff00, /* a2 */
|
||||
IWL_RX_HE_SIGB_COMMON0_CH2_RU0 = 0x00ff0000, /* b1 */
|
||||
IWL_RX_HE_SIGB_COMMON0_CH2_RU2 = 0xff000000, /* b2 */
|
||||
IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU0 = 0x000000ff, /* a1 */
|
||||
IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU2 = 0x0000ff00, /* a2 */
|
||||
IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU0 = 0x00ff0000, /* b1 */
|
||||
IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU2 = 0xff000000, /* b2 */
|
||||
|
||||
/* info type: HE TB-EXT */
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1 = 0x0000000f,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2 = 0x000000f0,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3 = 0x00000f00,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4 = 0x0000f000,
|
||||
};
|
||||
|
||||
enum iwl_rx_he_sigb_common1 {
|
||||
IWL_RX_HE_SIGB_COMMON1_CH1_RU1 = 0x000000ff, /* c1 */
|
||||
IWL_RX_HE_SIGB_COMMON1_CH1_RU3 = 0x0000ff00, /* c2 */
|
||||
IWL_RX_HE_SIGB_COMMON1_CH2_RU1 = 0x00ff0000, /* d1 */
|
||||
IWL_RX_HE_SIGB_COMMON1_CH2_RU3 = 0xff000000, /* d2 */
|
||||
/* goes into Metadata DW 8 */
|
||||
enum iwl_rx_phy_data3 {
|
||||
/* info type: HE MU-EXT */
|
||||
IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU1 = 0x000000ff, /* c1 */
|
||||
IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU3 = 0x0000ff00, /* c2 */
|
||||
IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU1 = 0x00ff0000, /* d1 */
|
||||
IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU3 = 0xff000000, /* d2 */
|
||||
};
|
||||
|
||||
enum iwl_rx_he_sigb_common2 {
|
||||
IWL_RX_HE_SIGB_COMMON2_CH1_CTR_RU = 0x0001,
|
||||
IWL_RX_HE_SIGB_COMMON2_CH2_CTR_RU = 0x0002,
|
||||
IWL_RX_HE_SIGB_COMMON2_CH1_CRC_OK = 0x0004,
|
||||
IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK = 0x0008,
|
||||
/* goes into Metadata DW 4 high 16 bits */
|
||||
enum iwl_rx_phy_data4 {
|
||||
/* info type: HE MU-EXT */
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CTR_RU = 0x0001,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CTR_RU = 0x0002,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CRC_OK = 0x0004,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CRC_OK = 0x0008,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_MCS_MASK = 0x00f0,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_DCM = 0x0100,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_PREAMBLE_PUNC_TYPE_MASK = 0x0600,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -419,9 +451,9 @@ struct iwl_rx_mpdu_desc_v1 {
|
||||
__le32 rss_hash;
|
||||
|
||||
/**
|
||||
* @sigb_common0: for HE sniffer, HE-SIG-B common part 0
|
||||
* @phy_data2: depends on info type (see @phy_data1)
|
||||
*/
|
||||
__le32 sigb_common0;
|
||||
__le32 phy_data2;
|
||||
};
|
||||
|
||||
/* DW8 - carries filter_match only when rpa_en == 1 */
|
||||
@ -432,9 +464,9 @@ struct iwl_rx_mpdu_desc_v1 {
|
||||
__le32 filter_match;
|
||||
|
||||
/**
|
||||
* @sigb_common1: for HE sniffer, HE-SIG-B common part 1
|
||||
* @phy_data3: depends on info type (see @phy_data1)
|
||||
*/
|
||||
__le32 sigb_common1;
|
||||
__le32 phy_data3;
|
||||
};
|
||||
|
||||
/* DW9 */
|
||||
@ -472,12 +504,19 @@ struct iwl_rx_mpdu_desc_v1 {
|
||||
* %IWL_RX_MPDU_PHY_TSF_OVERLOAD isn't set
|
||||
*/
|
||||
__le64 tsf_on_air_rise;
|
||||
/**
|
||||
* @he_phy_data:
|
||||
* HE PHY data, see &enum iwl_rx_he_phy, valid
|
||||
* only if %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set
|
||||
*/
|
||||
__le64 he_phy_data;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @phy_data0: depends on info_type, see @phy_data1
|
||||
*/
|
||||
__le32 phy_data0;
|
||||
/**
|
||||
* @phy_data1: valid only if
|
||||
* %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set,
|
||||
* see &enum iwl_rx_phy_data1.
|
||||
*/
|
||||
__le32 phy_data1;
|
||||
};
|
||||
};
|
||||
} __packed;
|
||||
|
||||
@ -493,9 +532,9 @@ struct iwl_rx_mpdu_desc_v3 {
|
||||
__le32 filter_match;
|
||||
|
||||
/**
|
||||
* @sigb_common0: for HE sniffer, HE-SIG-B common part 0
|
||||
* @phy_data2: depends on info type (see @phy_data1)
|
||||
*/
|
||||
__le32 sigb_common0;
|
||||
__le32 phy_data2;
|
||||
};
|
||||
|
||||
/* DW8 - carries rss_hash only when rpa_en == 1 */
|
||||
@ -506,9 +545,9 @@ struct iwl_rx_mpdu_desc_v3 {
|
||||
__le32 rss_hash;
|
||||
|
||||
/**
|
||||
* @sigb_common1: for HE sniffer, HE-SIG-B common part 1
|
||||
* @phy_data3: depends on info type (see @phy_data1)
|
||||
*/
|
||||
__le32 sigb_common1;
|
||||
__le32 phy_data3;
|
||||
};
|
||||
/* DW9 */
|
||||
/**
|
||||
@ -556,12 +595,19 @@ struct iwl_rx_mpdu_desc_v3 {
|
||||
* %IWL_RX_MPDU_PHY_TSF_OVERLOAD isn't set
|
||||
*/
|
||||
__le64 tsf_on_air_rise;
|
||||
/**
|
||||
* @he_phy_data:
|
||||
* HE PHY data, see &enum iwl_rx_he_phy, valid
|
||||
* only if %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set
|
||||
*/
|
||||
__le64 he_phy_data;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @phy_data0: depends on info_type, see @phy_data1
|
||||
*/
|
||||
__le32 phy_data0;
|
||||
/**
|
||||
* @phy_data1: valid only if
|
||||
* %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set,
|
||||
* see &enum iwl_rx_phy_data1.
|
||||
*/
|
||||
__le32 phy_data1;
|
||||
};
|
||||
};
|
||||
/* DW16 & DW17 */
|
||||
/**
|
||||
@ -613,9 +659,9 @@ struct iwl_rx_mpdu_desc {
|
||||
__le16 l3l4_flags;
|
||||
|
||||
/**
|
||||
* @sigb_common2: for HE sniffer, HE-SIG-B common part 2
|
||||
* @phy_data4: depends on info type, see phy_data1
|
||||
*/
|
||||
__le16 sigb_common2;
|
||||
__le16 phy_data4;
|
||||
};
|
||||
/* DW5 */
|
||||
/**
|
||||
@ -651,6 +697,55 @@ struct iwl_rx_mpdu_desc {
|
||||
#define IWL_CD_STTS_WIFI_STATUS_POS 4
|
||||
#define IWL_CD_STTS_WIFI_STATUS_MSK 0xF0
|
||||
|
||||
#define RX_NO_DATA_CHAIN_A_POS 0
|
||||
#define RX_NO_DATA_CHAIN_A_MSK (0xff << RX_NO_DATA_CHAIN_A_POS)
|
||||
#define RX_NO_DATA_CHAIN_B_POS 8
|
||||
#define RX_NO_DATA_CHAIN_B_MSK (0xff << RX_NO_DATA_CHAIN_B_POS)
|
||||
#define RX_NO_DATA_CHANNEL_POS 16
|
||||
#define RX_NO_DATA_CHANNEL_MSK (0xff << RX_NO_DATA_CHANNEL_POS)
|
||||
|
||||
#define RX_NO_DATA_INFO_TYPE_POS 0
|
||||
#define RX_NO_DATA_INFO_TYPE_MSK (0xff << RX_NO_DATA_INFO_TYPE_POS)
|
||||
#define RX_NO_DATA_INFO_TYPE_NONE 0
|
||||
#define RX_NO_DATA_INFO_TYPE_RX_ERR 1
|
||||
#define RX_NO_DATA_INFO_TYPE_NDP 2
|
||||
#define RX_NO_DATA_INFO_TYPE_MU_UNMATCHED 3
|
||||
#define RX_NO_DATA_INFO_TYPE_HE_TB_UNMATCHED 4
|
||||
|
||||
#define RX_NO_DATA_INFO_ERR_POS 8
|
||||
#define RX_NO_DATA_INFO_ERR_MSK (0xff << RX_NO_DATA_INFO_ERR_POS)
|
||||
#define RX_NO_DATA_INFO_ERR_NONE 0
|
||||
#define RX_NO_DATA_INFO_ERR_BAD_PLCP 1
|
||||
#define RX_NO_DATA_INFO_ERR_UNSUPPORTED_RATE 2
|
||||
#define RX_NO_DATA_INFO_ERR_NO_DELIM 3
|
||||
#define RX_NO_DATA_INFO_ERR_BAD_MAC_HDR 4
|
||||
|
||||
#define RX_NO_DATA_FRAME_TIME_POS 0
|
||||
#define RX_NO_DATA_FRAME_TIME_MSK (0xfffff << RX_NO_DATA_FRAME_TIME_POS)
|
||||
|
||||
/**
|
||||
* struct iwl_rx_no_data - RX no data descriptor
|
||||
* @info: 7:0 frame type, 15:8 RX error type
|
||||
* @rssi: 7:0 energy chain-A,
|
||||
* 15:8 chain-B, measured at FINA time (FINA_ENERGY), 16:23 channel
|
||||
* @on_air_rise_time: GP2 during on air rise
|
||||
* @fr_time: frame time
|
||||
* @rate: rate/mcs of frame
|
||||
* @phy_info: &enum iwl_rx_phy_data0 and &enum iwl_rx_phy_info_type
|
||||
* @rx_vec: DW-12:9 raw RX vectors from DSP according to modulation type.
|
||||
* for VHT: OFDM_RX_VECTOR_SIGA1_OUT, OFDM_RX_VECTOR_SIGA2_OUT
|
||||
* for HE: OFDM_RX_VECTOR_HE_SIGA1_OUT, OFDM_RX_VECTOR_HE_SIGA2_OUT
|
||||
*/
|
||||
struct iwl_rx_no_data {
|
||||
__le32 info;
|
||||
__le32 rssi;
|
||||
__le32 on_air_rise_time;
|
||||
__le32 fr_time;
|
||||
__le32 rate;
|
||||
__le32 phy_info[2];
|
||||
__le32 rx_vec[3];
|
||||
} __packed; /* RX_NO_DATA_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_completion_desc_transfer_status - transfer status (bits 1-3)
|
||||
* @IWL_CD_STTS_UNUSED: unused
|
||||
|
@ -605,6 +605,28 @@ static void iwl_fw_dump_mem(struct iwl_fw_runtime *fwrt,
|
||||
IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
|
||||
}
|
||||
|
||||
static void iwl_fw_dump_named_mem(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_error_dump_data **dump_data,
|
||||
u32 len, u32 ofs, u8 *name, u8 name_len)
|
||||
{
|
||||
struct iwl_fw_error_dump_named_mem *dump_mem;
|
||||
|
||||
if (!len)
|
||||
return;
|
||||
|
||||
(*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
|
||||
(*dump_data)->len = cpu_to_le32(len + sizeof(*dump_mem));
|
||||
dump_mem = (void *)(*dump_data)->data;
|
||||
dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_NAMED_MEM);
|
||||
dump_mem->offset = cpu_to_le32(ofs);
|
||||
dump_mem->name_len = name_len;
|
||||
memcpy(dump_mem->name, name, name_len);
|
||||
iwl_trans_read_mem_bytes(fwrt->trans, ofs, dump_mem->data, len);
|
||||
*dump_data = iwl_fw_error_next_data(*dump_data);
|
||||
|
||||
IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
|
||||
}
|
||||
|
||||
#define ADD_LEN(len, item_len, const_len) \
|
||||
do {size_t item = item_len; len += (!!item) * const_len + item; } \
|
||||
while (0)
|
||||
@ -806,6 +828,7 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
|
||||
sizeof(dump_info->dev_human_readable) - 1);
|
||||
strncpy(dump_info->bus_human_readable, fwrt->dev->bus->name,
|
||||
sizeof(dump_info->bus_human_readable) - 1);
|
||||
dump_info->rt_status = cpu_to_le32(fwrt->dump.rt_status);
|
||||
|
||||
dump_data = iwl_fw_error_next_data(dump_data);
|
||||
}
|
||||
@ -928,6 +951,238 @@ out:
|
||||
return dump_file;
|
||||
}
|
||||
|
||||
static void iwl_dump_prph_ini(struct iwl_trans *trans,
|
||||
struct iwl_fw_error_dump_data **data,
|
||||
struct iwl_fw_ini_region_cfg *reg)
|
||||
{
|
||||
struct iwl_fw_error_dump_prph *prph;
|
||||
unsigned long flags;
|
||||
u32 i, size = le32_to_cpu(reg->num_regions);
|
||||
|
||||
IWL_DEBUG_INFO(trans, "WRT PRPH dump\n");
|
||||
|
||||
if (!iwl_trans_grab_nic_access(trans, &flags))
|
||||
return;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH);
|
||||
(*data)->len = cpu_to_le32(le32_to_cpu(reg->size) +
|
||||
sizeof(*prph));
|
||||
prph = (void *)(*data)->data;
|
||||
prph->prph_start = reg->start_addr[i];
|
||||
prph->data[0] = cpu_to_le32(iwl_read_prph_no_grab(trans,
|
||||
le32_to_cpu(prph->prph_start)));
|
||||
*data = iwl_fw_error_next_data(*data);
|
||||
}
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
|
||||
static void iwl_dump_csr_ini(struct iwl_trans *trans,
|
||||
struct iwl_fw_error_dump_data **data,
|
||||
struct iwl_fw_ini_region_cfg *reg)
|
||||
{
|
||||
int i, num = le32_to_cpu(reg->num_regions);
|
||||
u32 size = le32_to_cpu(reg->size);
|
||||
|
||||
IWL_DEBUG_INFO(trans, "WRT CSR dump\n");
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
u32 add = le32_to_cpu(reg->start_addr[i]);
|
||||
__le32 *val;
|
||||
int j;
|
||||
|
||||
(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_CSR);
|
||||
(*data)->len = cpu_to_le32(size);
|
||||
val = (void *)(*data)->data;
|
||||
|
||||
for (j = 0; j < size; j += 4)
|
||||
*val++ = cpu_to_le32(iwl_trans_read32(trans, j + add));
|
||||
|
||||
*data = iwl_fw_error_next_data(*data);
|
||||
}
|
||||
}
|
||||
|
||||
static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_ini_trigger *trigger)
|
||||
{
|
||||
int i, num, size = 0, hdr_len = sizeof(struct iwl_fw_error_dump_data);
|
||||
|
||||
if (!trigger || !trigger->num_regions)
|
||||
return 0;
|
||||
|
||||
num = le32_to_cpu(trigger->num_regions);
|
||||
for (i = 0; i < num; i++) {
|
||||
u32 reg_id = le32_to_cpu(trigger->data[i]);
|
||||
struct iwl_fw_ini_region_cfg *reg;
|
||||
enum iwl_fw_ini_region_type type;
|
||||
u32 num_entries;
|
||||
|
||||
if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt->dump.active_regs)))
|
||||
continue;
|
||||
|
||||
reg = fwrt->dump.active_regs[reg_id].reg;
|
||||
if (WARN(!reg, "Unassigned region %d\n", reg_id))
|
||||
continue;
|
||||
|
||||
type = le32_to_cpu(reg->region_type);
|
||||
num_entries = le32_to_cpu(reg->num_regions);
|
||||
|
||||
switch (type) {
|
||||
case IWL_FW_INI_REGION_DEVICE_MEMORY:
|
||||
size += hdr_len +
|
||||
sizeof(struct iwl_fw_error_dump_named_mem) +
|
||||
le32_to_cpu(reg->size);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_PERIPHERY_MAC:
|
||||
case IWL_FW_INI_REGION_PERIPHERY_PHY:
|
||||
case IWL_FW_INI_REGION_PERIPHERY_AUX:
|
||||
size += num_entries *
|
||||
(hdr_len +
|
||||
sizeof(struct iwl_fw_error_dump_prph) +
|
||||
sizeof(u32));
|
||||
break;
|
||||
case IWL_FW_INI_REGION_TXF:
|
||||
size += iwl_fw_txf_len(fwrt, &fwrt->smem_cfg);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_RXF:
|
||||
size += iwl_fw_rxf_len(fwrt, &fwrt->smem_cfg);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_PAGING:
|
||||
if (!iwl_fw_dbg_is_paging_enabled(fwrt))
|
||||
break;
|
||||
size += fwrt->num_of_paging_blk *
|
||||
(hdr_len +
|
||||
sizeof(struct iwl_fw_error_dump_paging) +
|
||||
PAGING_BLOCK_SIZE);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_CSR:
|
||||
size += num_entries *
|
||||
(hdr_len + le32_to_cpu(reg->size));
|
||||
break;
|
||||
case IWL_FW_INI_REGION_DRAM_BUFFER:
|
||||
/* Transport takes care of DRAM dumping */
|
||||
case IWL_FW_INI_REGION_INTERNAL_BUFFER:
|
||||
case IWL_FW_INI_REGION_DRAM_IMR:
|
||||
/* Undefined yet */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_ini_trigger *trigger,
|
||||
struct iwl_fw_error_dump_data **data,
|
||||
u32 *dump_mask)
|
||||
{
|
||||
int i, num = le32_to_cpu(trigger->num_regions);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
u32 reg_id = le32_to_cpu(trigger->data[i]);
|
||||
enum iwl_fw_ini_region_type type;
|
||||
struct iwl_fw_ini_region_cfg *reg;
|
||||
|
||||
if (reg_id >= ARRAY_SIZE(fwrt->dump.active_regs))
|
||||
continue;
|
||||
|
||||
reg = fwrt->dump.active_regs[reg_id].reg;
|
||||
/* Don't warn, get_trigger_len already warned */
|
||||
if (!reg)
|
||||
continue;
|
||||
|
||||
type = le32_to_cpu(reg->region_type);
|
||||
switch (type) {
|
||||
case IWL_FW_INI_REGION_DEVICE_MEMORY:
|
||||
if (WARN_ON(le32_to_cpu(reg->num_regions) > 1))
|
||||
continue;
|
||||
iwl_fw_dump_named_mem(fwrt, data,
|
||||
le32_to_cpu(reg->size),
|
||||
le32_to_cpu(reg->start_addr[0]),
|
||||
reg->name,
|
||||
le32_to_cpu(reg->name_len));
|
||||
break;
|
||||
case IWL_FW_INI_REGION_PERIPHERY_MAC:
|
||||
case IWL_FW_INI_REGION_PERIPHERY_PHY:
|
||||
case IWL_FW_INI_REGION_PERIPHERY_AUX:
|
||||
iwl_dump_prph_ini(fwrt->trans, data, reg);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_DRAM_BUFFER:
|
||||
*dump_mask |= IWL_FW_ERROR_DUMP_FW_MONITOR;
|
||||
break;
|
||||
case IWL_FW_INI_REGION_PAGING:
|
||||
if (iwl_fw_dbg_is_paging_enabled(fwrt))
|
||||
iwl_dump_paging(fwrt, data);
|
||||
else
|
||||
*dump_mask |= IWL_FW_ERROR_DUMP_PAGING;
|
||||
break;
|
||||
case IWL_FW_INI_REGION_TXF:
|
||||
iwl_fw_dump_txf(fwrt, data);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_RXF:
|
||||
iwl_fw_dump_rxf(fwrt, data);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_CSR:
|
||||
iwl_dump_csr_ini(fwrt->trans, data, reg);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_DRAM_IMR:
|
||||
case IWL_FW_INI_REGION_INTERNAL_BUFFER:
|
||||
/* This is undefined yet */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct iwl_fw_error_dump_file *
|
||||
_iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dump_ptrs *fw_error_dump,
|
||||
u32 *dump_mask)
|
||||
{
|
||||
int size, id = le32_to_cpu(fwrt->dump.desc->trig_desc.type);
|
||||
struct iwl_fw_error_dump_data *dump_data;
|
||||
struct iwl_fw_error_dump_file *dump_file;
|
||||
struct iwl_fw_ini_trigger *trigger, *ext;
|
||||
|
||||
if (id == FW_DBG_TRIGGER_FW_ASSERT)
|
||||
id = IWL_FW_TRIGGER_ID_FW_ASSERT;
|
||||
else if (id == FW_DBG_TRIGGER_USER)
|
||||
id = IWL_FW_TRIGGER_ID_USER_TRIGGER;
|
||||
else if (id < FW_DBG_TRIGGER_MAX)
|
||||
return NULL;
|
||||
|
||||
if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_trigs)))
|
||||
return NULL;
|
||||
|
||||
trigger = fwrt->dump.active_trigs[id].conf;
|
||||
ext = fwrt->dump.active_trigs[id].conf_ext;
|
||||
|
||||
size = sizeof(*dump_file);
|
||||
size += iwl_fw_ini_get_trigger_len(fwrt, trigger);
|
||||
size += iwl_fw_ini_get_trigger_len(fwrt, ext);
|
||||
|
||||
if (!size)
|
||||
return NULL;
|
||||
|
||||
dump_file = vzalloc(size);
|
||||
if (!dump_file)
|
||||
return NULL;
|
||||
|
||||
fw_error_dump->fwrt_ptr = dump_file;
|
||||
|
||||
dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
|
||||
dump_data = (void *)dump_file->data;
|
||||
dump_file->file_len = cpu_to_le32(size);
|
||||
|
||||
*dump_mask = 0;
|
||||
if (trigger)
|
||||
iwl_fw_ini_dump_trigger(fwrt, trigger, &dump_data, dump_mask);
|
||||
if (ext)
|
||||
iwl_fw_ini_dump_trigger(fwrt, ext, &dump_data, dump_mask);
|
||||
|
||||
return dump_file;
|
||||
}
|
||||
|
||||
void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
struct iwl_fw_dump_ptrs *fw_error_dump;
|
||||
@ -948,13 +1203,18 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
if (!fw_error_dump)
|
||||
goto out;
|
||||
|
||||
dump_file = _iwl_fw_error_dump(fwrt, fw_error_dump);
|
||||
if (fwrt->trans->ini_valid)
|
||||
dump_file = _iwl_fw_error_ini_dump(fwrt, fw_error_dump,
|
||||
&dump_mask);
|
||||
else
|
||||
dump_file = _iwl_fw_error_dump(fwrt, fw_error_dump);
|
||||
|
||||
if (!dump_file) {
|
||||
kfree(fw_error_dump);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fwrt->dump.monitor_only)
|
||||
if (!fwrt->trans->ini_valid && fwrt->dump.monitor_only)
|
||||
dump_mask &= IWL_FW_ERROR_DUMP_FW_MONITOR;
|
||||
|
||||
fw_error_dump->trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask);
|
||||
@ -1070,10 +1330,10 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_desc);
|
||||
|
||||
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig,
|
||||
const char *str, size_t len,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger)
|
||||
int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig,
|
||||
const char *str, size_t len,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger)
|
||||
{
|
||||
struct iwl_fw_dump_desc *desc;
|
||||
unsigned int delay = 0;
|
||||
@ -1108,6 +1368,47 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
|
||||
return iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(_iwl_fw_dbg_collect);
|
||||
|
||||
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
u32 id, const char *str, size_t len)
|
||||
{
|
||||
struct iwl_fw_dump_desc *desc;
|
||||
u32 occur, delay;
|
||||
|
||||
if (!fwrt->trans->ini_valid)
|
||||
return _iwl_fw_dbg_collect(fwrt, id, str, len, NULL);
|
||||
|
||||
if (id == FW_DBG_TRIGGER_USER)
|
||||
id = IWL_FW_TRIGGER_ID_USER_TRIGGER;
|
||||
|
||||
if (WARN_ON(!fwrt->dump.active_trigs[id].active))
|
||||
return -EINVAL;
|
||||
|
||||
delay = le32_to_cpu(fwrt->dump.active_trigs[id].conf->ignore_consec);
|
||||
occur = le32_to_cpu(fwrt->dump.active_trigs[id].conf->occurrences);
|
||||
if (!occur)
|
||||
return 0;
|
||||
|
||||
if (le32_to_cpu(fwrt->dump.active_trigs[id].conf->force_restart)) {
|
||||
IWL_WARN(fwrt, "Force restart: trigger %d fired.\n", id);
|
||||
iwl_force_nmi(fwrt->trans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC);
|
||||
if (!desc)
|
||||
return -ENOMEM;
|
||||
|
||||
occur--;
|
||||
fwrt->dump.active_trigs[id].conf->occurrences = cpu_to_le32(occur);
|
||||
|
||||
desc->len = len;
|
||||
desc->trig_desc.type = cpu_to_le32(id);
|
||||
memcpy(desc->trig_desc.data, str, len);
|
||||
|
||||
return iwl_fw_dbg_collect_desc(fwrt, desc, true, delay);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect);
|
||||
|
||||
int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
|
||||
@ -1136,8 +1437,8 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
|
||||
len = strlen(buf) + 1;
|
||||
}
|
||||
|
||||
ret = iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
|
||||
trigger);
|
||||
ret = _iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
|
||||
trigger);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -1346,7 +1647,8 @@ static void iwl_fw_dbg_update_regions(struct iwl_fw_runtime *fwrt,
|
||||
int id = le32_to_cpu(reg->region_id);
|
||||
struct iwl_fw_ini_active_regs *active;
|
||||
|
||||
if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_regs)))
|
||||
if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs),
|
||||
"Invalid region id %d for apply point %d\n", id, pnt))
|
||||
break;
|
||||
|
||||
active = &fwrt->dump.active_regs[id];
|
||||
@ -1409,6 +1711,12 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
|
||||
active->conf = trig;
|
||||
}
|
||||
|
||||
/* Since zero means infinity - just set to -1 */
|
||||
if (!le32_to_cpu(trig->occurrences))
|
||||
trig->occurrences = cpu_to_le32(-1);
|
||||
if (!le32_to_cpu(trig->ignore_consec))
|
||||
trig->ignore_consec = cpu_to_le32(-1);
|
||||
|
||||
iter += sizeof(*trig) +
|
||||
le32_to_cpu(trig->num_regions) * sizeof(__le32);
|
||||
|
||||
|
@ -102,16 +102,19 @@ static inline void iwl_fw_free_dump_desc(struct iwl_fw_runtime *fwrt)
|
||||
if (fwrt->dump.desc != &iwl_dump_desc_assert)
|
||||
kfree(fwrt->dump.desc);
|
||||
fwrt->dump.desc = NULL;
|
||||
fwrt->dump.rt_status = 0;
|
||||
}
|
||||
|
||||
void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt);
|
||||
int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
|
||||
const struct iwl_fw_dump_desc *desc,
|
||||
bool monitor_only, unsigned int delay);
|
||||
int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig,
|
||||
const char *str, size_t len,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger);
|
||||
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig,
|
||||
const char *str, size_t len,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger);
|
||||
u32 id, const char *str, size_t len);
|
||||
int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger,
|
||||
const char *fmt, ...) __printf(3, 4);
|
||||
@ -213,6 +216,37 @@ _iwl_fw_dbg_trigger_on(struct iwl_fw_runtime *fwrt,
|
||||
_iwl_fw_dbg_trigger_on((fwrt), (wdev), (id)); \
|
||||
})
|
||||
|
||||
static inline bool
|
||||
_iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt,
|
||||
const enum iwl_fw_dbg_trigger id)
|
||||
{
|
||||
struct iwl_fw_ini_active_triggers *trig = &fwrt->dump.active_trigs[id];
|
||||
u32 ms;
|
||||
|
||||
if (!fwrt->trans->ini_valid)
|
||||
return false;
|
||||
|
||||
if (!trig || !trig->active)
|
||||
return false;
|
||||
|
||||
ms = le32_to_cpu(trig->conf->ignore_consec);
|
||||
if (ms)
|
||||
ms /= USEC_PER_MSEC;
|
||||
|
||||
if (iwl_fw_dbg_no_trig_window(fwrt, id, ms)) {
|
||||
IWL_WARN(fwrt, "Trigger %d fired in no-collect window\n", id);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define iwl_fw_ini_trigger_on(fwrt, wdev, id) ({ \
|
||||
BUILD_BUG_ON(!__builtin_constant_p(id)); \
|
||||
BUILD_BUG_ON((id) >= IWL_FW_TRIGGER_ID_NUM); \
|
||||
_iwl_fw_ini_trigger_on((fwrt), (wdev), (id)); \
|
||||
})
|
||||
|
||||
static inline void
|
||||
_iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt,
|
||||
struct wireless_dev *wdev,
|
||||
@ -329,7 +363,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work);
|
||||
|
||||
static inline bool iwl_fw_dbg_type_on(struct iwl_fw_runtime *fwrt, u32 type)
|
||||
{
|
||||
return (fwrt->fw->dbg.dump_mask & BIT(type));
|
||||
return (fwrt->fw->dbg.dump_mask & BIT(type) || fwrt->trans->ini_valid);
|
||||
}
|
||||
|
||||
static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt)
|
||||
|
@ -187,6 +187,8 @@ enum iwl_fw_error_dump_family {
|
||||
* @fw_human_readable: human readable FW version
|
||||
* @dev_human_readable: name of the device
|
||||
* @bus_human_readable: name of the bus used
|
||||
* @rt_status: the error_id/rt_status that that triggered the latest dump
|
||||
* if the dump collection was not initiated by an assert, the value is 0
|
||||
*/
|
||||
struct iwl_fw_error_dump_info {
|
||||
__le32 device_family;
|
||||
@ -194,6 +196,7 @@ struct iwl_fw_error_dump_info {
|
||||
u8 fw_human_readable[FW_VER_HUMAN_READABLE_SZ];
|
||||
u8 dev_human_readable[64];
|
||||
u8 bus_human_readable[8];
|
||||
__le32 rt_status;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
@ -249,6 +252,7 @@ struct iwl_fw_error_dump_prph {
|
||||
enum iwl_fw_error_dump_mem_type {
|
||||
IWL_FW_ERROR_DUMP_MEM_SRAM,
|
||||
IWL_FW_ERROR_DUMP_MEM_SMEM,
|
||||
IWL_FW_ERROR_DUMP_MEM_NAMED_MEM = 10,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -263,6 +267,22 @@ struct iwl_fw_error_dump_mem {
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_error_dump_named_mem - chunk of memory
|
||||
* @type: &enum iwl_fw_error_dump_mem_type
|
||||
* @offset: the offset from which the memory was read
|
||||
* @name_len: name length
|
||||
* @name: file name
|
||||
* @data: the content of the memory
|
||||
*/
|
||||
struct iwl_fw_error_dump_named_mem {
|
||||
__le32 type;
|
||||
__le32 offset;
|
||||
u8 name_len;
|
||||
u8 name[32];
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_error_dump_rb - content of an Receive Buffer
|
||||
* @index: the index of the Receive Buffer in the Rx queue
|
||||
|
@ -138,10 +138,11 @@ struct iwl_fw_runtime {
|
||||
u8 conf;
|
||||
|
||||
/* ts of the beginning of a non-collect fw dbg data period */
|
||||
unsigned long non_collect_ts_start[FW_DBG_TRIGGER_MAX - 1];
|
||||
unsigned long non_collect_ts_start[IWL_FW_TRIGGER_ID_NUM - 1];
|
||||
u32 *d3_debug_data;
|
||||
struct iwl_fw_ini_active_regs active_regs[IWL_FW_INI_MAX_REGION_ID];
|
||||
struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM];
|
||||
u32 rt_status;
|
||||
} dump;
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
struct {
|
||||
|
@ -265,11 +265,9 @@ struct iwl_tt_params {
|
||||
#define EEPROM_REGULATORY_BAND_NO_HT40 0
|
||||
|
||||
/* lower blocks contain EEPROM image and calibration data */
|
||||
#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_FAMILY_7000 (16 * 512 * sizeof(u16)) /* 16 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(u16)) /* 32 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_FAMILY_9000 OTP_LOW_IMAGE_SIZE_FAMILY_8000
|
||||
#define OTP_LOW_IMAGE_SIZE_FAMILY_22000 OTP_LOW_IMAGE_SIZE_FAMILY_9000
|
||||
#define OTP_LOW_IMAGE_SIZE_2K (2 * 512 * sizeof(u16)) /* 2 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_16K (16 * 512 * sizeof(u16)) /* 16 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_32K (32 * 512 * sizeof(u16)) /* 32 KB */
|
||||
|
||||
struct iwl_eeprom_params {
|
||||
const u8 regulatory_bands[7];
|
||||
|
@ -201,6 +201,7 @@ static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
|
||||
case IWL_UCODE_TLV_TYPE_TRIGGERS:
|
||||
case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
|
||||
iwl_fw_dbg_copy_tlv(trans, tlv, true);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "Invalid TLV %x\n", tlv_type);
|
||||
break;
|
||||
|
@ -1097,6 +1097,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
|
||||
if (iwlwifi_mod_params.enable_ini)
|
||||
iwl_fw_dbg_copy_tlv(drv->trans, tlv, false);
|
||||
break;
|
||||
default:
|
||||
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
|
||||
break;
|
||||
|
@ -927,22 +927,3 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
return NULL;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_parse_eeprom_data);
|
||||
|
||||
/* helper functions */
|
||||
int iwl_nvm_check_version(struct iwl_nvm_data *data,
|
||||
struct iwl_trans *trans)
|
||||
{
|
||||
if (data->nvm_version >= trans->cfg->nvm_ver ||
|
||||
data->calib_version >= trans->cfg->nvm_calib_ver) {
|
||||
IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n",
|
||||
data->nvm_version, data->calib_version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWL_ERR(trans,
|
||||
"Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
|
||||
data->nvm_version, trans->cfg->nvm_ver,
|
||||
data->calib_version, trans->cfg->nvm_calib_ver);
|
||||
return -EINVAL;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_nvm_check_version);
|
||||
|
@ -7,6 +7,7 @@
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -28,6 +29,7 @@
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -117,9 +119,6 @@ struct iwl_nvm_data *
|
||||
iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
const u8 *eeprom, size_t eeprom_size);
|
||||
|
||||
int iwl_nvm_check_version(struct iwl_nvm_data *data,
|
||||
struct iwl_trans *trans);
|
||||
|
||||
int iwl_init_sband_channels(struct iwl_nvm_data *data,
|
||||
struct ieee80211_supported_band *sband,
|
||||
int n_channels, enum nl80211_band band);
|
||||
|
@ -465,101 +465,185 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
|
||||
vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
|
||||
}
|
||||
|
||||
static struct ieee80211_sband_iftype_data iwl_he_capa = {
|
||||
.types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP),
|
||||
.he_cap = {
|
||||
.has_he = true,
|
||||
.he_cap_elem = {
|
||||
.mac_cap_info[0] =
|
||||
IEEE80211_HE_MAC_CAP0_HTC_HE |
|
||||
IEEE80211_HE_MAC_CAP0_TWT_REQ,
|
||||
.mac_cap_info[1] =
|
||||
IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
|
||||
IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
|
||||
.mac_cap_info[2] =
|
||||
IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP |
|
||||
IEEE80211_HE_MAC_CAP2_MU_CASCADING |
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
.mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU |
|
||||
IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
|
||||
.mac_cap_info[5] =
|
||||
IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 |
|
||||
IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B41 |
|
||||
IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
|
||||
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
|
||||
IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
|
||||
.phy_cap_info[2] =
|
||||
IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
|
||||
IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
|
||||
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
|
||||
IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
|
||||
IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
|
||||
.phy_cap_info[3] =
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_BPSK |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_BPSK |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1,
|
||||
.phy_cap_info[4] =
|
||||
IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
|
||||
IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_8 |
|
||||
IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8,
|
||||
.phy_cap_info[5] =
|
||||
IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2 |
|
||||
IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2 |
|
||||
IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK |
|
||||
IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK,
|
||||
.phy_cap_info[6] =
|
||||
IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
|
||||
IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO |
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
|
||||
.phy_cap_info[7] =
|
||||
IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
|
||||
IEEE80211_HE_PHY_CAP7_MAX_NC_1,
|
||||
.phy_cap_info[8] =
|
||||
IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
|
||||
IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
|
||||
IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
|
||||
IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU |
|
||||
IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_160_OR_80P80_MHZ,
|
||||
.phy_cap_info[9] =
|
||||
IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |
|
||||
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
|
||||
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB,
|
||||
static struct ieee80211_sband_iftype_data iwl_he_capa[] = {
|
||||
{
|
||||
.types_mask = BIT(NL80211_IFTYPE_STATION),
|
||||
.he_cap = {
|
||||
.has_he = true,
|
||||
.he_cap_elem = {
|
||||
.mac_cap_info[0] =
|
||||
IEEE80211_HE_MAC_CAP0_HTC_HE |
|
||||
IEEE80211_HE_MAC_CAP0_TWT_REQ,
|
||||
.mac_cap_info[1] =
|
||||
IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
|
||||
IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
|
||||
.mac_cap_info[2] =
|
||||
IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP |
|
||||
IEEE80211_HE_MAC_CAP2_MU_CASCADING |
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
.mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU |
|
||||
IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
|
||||
.mac_cap_info[5] =
|
||||
IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 |
|
||||
IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B41 |
|
||||
IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
|
||||
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
|
||||
IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
|
||||
.phy_cap_info[2] =
|
||||
IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
|
||||
IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
|
||||
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
|
||||
IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
|
||||
IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
|
||||
.phy_cap_info[3] =
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_BPSK |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_BPSK |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1,
|
||||
.phy_cap_info[4] =
|
||||
IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
|
||||
IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_8 |
|
||||
IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8,
|
||||
.phy_cap_info[5] =
|
||||
IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2 |
|
||||
IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2 |
|
||||
IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK |
|
||||
IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK,
|
||||
.phy_cap_info[6] =
|
||||
IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
|
||||
IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO |
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
|
||||
.phy_cap_info[7] =
|
||||
IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
|
||||
IEEE80211_HE_PHY_CAP7_MAX_NC_1,
|
||||
.phy_cap_info[8] =
|
||||
IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
|
||||
IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
|
||||
IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
|
||||
IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU |
|
||||
IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_160_OR_80P80_MHZ,
|
||||
.phy_cap_info[9] =
|
||||
IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |
|
||||
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
|
||||
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB,
|
||||
},
|
||||
/*
|
||||
* Set default Tx/Rx HE MCS NSS Support field.
|
||||
* Indicate support for up to 2 spatial streams and all
|
||||
* MCS, without any special cases
|
||||
*/
|
||||
.he_mcs_nss_supp = {
|
||||
.rx_mcs_80 = cpu_to_le16(0xfffa),
|
||||
.tx_mcs_80 = cpu_to_le16(0xfffa),
|
||||
.rx_mcs_160 = cpu_to_le16(0xfffa),
|
||||
.tx_mcs_160 = cpu_to_le16(0xfffa),
|
||||
.rx_mcs_80p80 = cpu_to_le16(0xffff),
|
||||
.tx_mcs_80p80 = cpu_to_le16(0xffff),
|
||||
},
|
||||
/*
|
||||
* Set default PPE thresholds, with PPET16 set to 0,
|
||||
* PPET8 set to 7
|
||||
*/
|
||||
.ppe_thres = {0x61, 0x1c, 0xc7, 0x71},
|
||||
},
|
||||
/*
|
||||
* Set default Tx/Rx HE MCS NSS Support field. Indicate support
|
||||
* for up to 2 spatial streams and all MCS, without any special
|
||||
* cases
|
||||
*/
|
||||
.he_mcs_nss_supp = {
|
||||
.rx_mcs_80 = cpu_to_le16(0xfffa),
|
||||
.tx_mcs_80 = cpu_to_le16(0xfffa),
|
||||
.rx_mcs_160 = cpu_to_le16(0xfffa),
|
||||
.tx_mcs_160 = cpu_to_le16(0xfffa),
|
||||
.rx_mcs_80p80 = cpu_to_le16(0xffff),
|
||||
.tx_mcs_80p80 = cpu_to_le16(0xffff),
|
||||
},
|
||||
{
|
||||
.types_mask = BIT(NL80211_IFTYPE_AP),
|
||||
.he_cap = {
|
||||
.has_he = true,
|
||||
.he_cap_elem = {
|
||||
.mac_cap_info[0] =
|
||||
IEEE80211_HE_MAC_CAP0_HTC_HE |
|
||||
IEEE80211_HE_MAC_CAP0_TWT_RES,
|
||||
.mac_cap_info[1] =
|
||||
IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
|
||||
IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
|
||||
.mac_cap_info[2] =
|
||||
IEEE80211_HE_MAC_CAP2_BSR |
|
||||
IEEE80211_HE_MAC_CAP2_MU_CASCADING |
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
.mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
|
||||
IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
|
||||
.phy_cap_info[2] =
|
||||
IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
|
||||
IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
|
||||
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ,
|
||||
.phy_cap_info[3] =
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_BPSK |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_BPSK |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1,
|
||||
.phy_cap_info[4] =
|
||||
IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
|
||||
IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_8 |
|
||||
IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8,
|
||||
.phy_cap_info[5] =
|
||||
IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2 |
|
||||
IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2 |
|
||||
IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK |
|
||||
IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK,
|
||||
.phy_cap_info[6] =
|
||||
IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
|
||||
IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
|
||||
.phy_cap_info[7] =
|
||||
IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
|
||||
IEEE80211_HE_PHY_CAP7_MAX_NC_1,
|
||||
.phy_cap_info[8] =
|
||||
IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
|
||||
IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
|
||||
IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
|
||||
IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU |
|
||||
IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_160_OR_80P80_MHZ,
|
||||
.phy_cap_info[9] =
|
||||
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
|
||||
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB,
|
||||
},
|
||||
/*
|
||||
* Set default Tx/Rx HE MCS NSS Support field.
|
||||
* Indicate support for up to 2 spatial streams and all
|
||||
* MCS, without any special cases
|
||||
*/
|
||||
.he_mcs_nss_supp = {
|
||||
.rx_mcs_80 = cpu_to_le16(0xfffa),
|
||||
.tx_mcs_80 = cpu_to_le16(0xfffa),
|
||||
.rx_mcs_160 = cpu_to_le16(0xfffa),
|
||||
.tx_mcs_160 = cpu_to_le16(0xfffa),
|
||||
.rx_mcs_80p80 = cpu_to_le16(0xffff),
|
||||
.tx_mcs_80p80 = cpu_to_le16(0xffff),
|
||||
},
|
||||
/*
|
||||
* Set default PPE thresholds, with PPET16 set to 0,
|
||||
* PPET8 set to 7
|
||||
*/
|
||||
.ppe_thres = {0x61, 0x1c, 0xc7, 0x71},
|
||||
},
|
||||
/*
|
||||
* Set default PPE thresholds, with PPET16 set to 0, PPET8 set
|
||||
* to 7
|
||||
*/
|
||||
.ppe_thres = {0x61, 0x1c, 0xc7, 0x71},
|
||||
},
|
||||
};
|
||||
|
||||
@ -568,20 +652,24 @@ static void iwl_init_he_hw_capab(struct ieee80211_supported_band *sband,
|
||||
{
|
||||
if (sband->band == NL80211_BAND_2GHZ ||
|
||||
sband->band == NL80211_BAND_5GHZ)
|
||||
sband->iftype_data = &iwl_he_capa;
|
||||
sband->iftype_data = iwl_he_capa;
|
||||
else
|
||||
return;
|
||||
|
||||
sband->n_iftype_data = 1;
|
||||
sband->n_iftype_data = ARRAY_SIZE(iwl_he_capa);
|
||||
|
||||
/* If not 2x2, we need to indicate 1x1 in the Midamble RX Max NSTS */
|
||||
if ((tx_chains & rx_chains) != ANT_AB) {
|
||||
iwl_he_capa.he_cap.he_cap_elem.phy_cap_info[1] &=
|
||||
~IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS;
|
||||
iwl_he_capa.he_cap.he_cap_elem.phy_cap_info[2] &=
|
||||
~IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS;
|
||||
iwl_he_capa.he_cap.he_cap_elem.phy_cap_info[7] &=
|
||||
~IEEE80211_HE_PHY_CAP7_MAX_NC_MASK;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sband->n_iftype_data; i++) {
|
||||
iwl_he_capa[i].he_cap.he_cap_elem.phy_cap_info[1] &=
|
||||
~IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS;
|
||||
iwl_he_capa[i].he_cap.he_cap_elem.phy_cap_info[2] &=
|
||||
~IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS;
|
||||
iwl_he_capa[i].he_cap.he_cap_elem.phy_cap_info[7] &=
|
||||
~IEEE80211_HE_PHY_CAP7_MAX_NC_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,6 +362,12 @@
|
||||
#define MON_BUFF_END_ADDR (0xa03c40)
|
||||
#define MON_BUFF_WRPTR (0xa03c44)
|
||||
#define MON_BUFF_CYCLE_CNT (0xa03c48)
|
||||
/* FW monitor family 8000 and on */
|
||||
#define MON_BUFF_BASE_ADDR_VER2 (0xa03c3c)
|
||||
#define MON_BUFF_END_ADDR_VER2 (0xa03c20)
|
||||
#define MON_BUFF_WRPTR_VER2 (0xa03c24)
|
||||
#define MON_BUFF_CYCLE_CNT_VER2 (0xa03c28)
|
||||
#define MON_BUFF_SHIFT_VER2 (0x8)
|
||||
|
||||
#define MON_DMARB_RD_CTL_ADDR (0xa03c60)
|
||||
#define MON_DMARB_RD_DATA_ADDR (0xa03c5c)
|
||||
|
@ -1811,8 +1811,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
|
||||
n_matches = 0;
|
||||
}
|
||||
|
||||
net_detect = kzalloc(sizeof(*net_detect) +
|
||||
(n_matches * sizeof(net_detect->matches[0])),
|
||||
net_detect = kzalloc(struct_size(net_detect, matches, n_matches),
|
||||
GFP_KERNEL);
|
||||
if (!net_detect || !n_matches)
|
||||
goto out_report_nd;
|
||||
@ -1827,8 +1826,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
|
||||
for (j = 0; j < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; j++)
|
||||
n_channels += hweight8(fw_match->matching_channels[j]);
|
||||
|
||||
match = kzalloc(sizeof(*match) +
|
||||
(n_channels * sizeof(*match->channels)),
|
||||
match = kzalloc(struct_size(match, channels, n_channels),
|
||||
GFP_KERNEL);
|
||||
if (!match)
|
||||
goto out_report_nd;
|
||||
|
@ -1284,7 +1284,7 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
|
||||
return 0;
|
||||
|
||||
iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf,
|
||||
(count - 1), NULL);
|
||||
(count - 1));
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
|
||||
|
||||
|
@ -547,7 +547,9 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||
if (mvm->nvm_file_name)
|
||||
iwl_mvm_load_nvm_to_nic(mvm);
|
||||
|
||||
WARN_ON(iwl_nvm_check_version(mvm->nvm_data, mvm->trans));
|
||||
WARN_ONCE(mvm->nvm_data->nvm_version < mvm->trans->cfg->nvm_ver,
|
||||
"Too old NVM version (0x%0x, required = 0x%0x)",
|
||||
mvm->nvm_data->nvm_version, mvm->trans->cfg->nvm_ver);
|
||||
|
||||
/*
|
||||
* abort after reading the nvm in case RF Kill is on, we will complete
|
||||
@ -1027,10 +1029,14 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY);
|
||||
|
||||
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE);
|
||||
|
||||
return iwl_init_paging(&mvm->fwrt, mvm->fwrt.cur_fw_img);
|
||||
}
|
||||
|
||||
@ -1059,11 +1065,13 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
|
||||
|
||||
mvm->fwrt.dump.conf = FW_DBG_INVALID;
|
||||
/* if we have a destination, assume EARLY START */
|
||||
if (mvm->fw->dbg.dest_tlv)
|
||||
mvm->fwrt.dump.conf = FW_DBG_START_FROM_ALIVE;
|
||||
iwl_fw_start_dbg_conf(&mvm->fwrt, FW_DBG_START_FROM_ALIVE);
|
||||
if (!mvm->trans->ini_valid) {
|
||||
mvm->fwrt.dump.conf = FW_DBG_INVALID;
|
||||
/* if we have a destination, assume EARLY START */
|
||||
if (mvm->fw->dbg.dest_tlv)
|
||||
mvm->fwrt.dump.conf = FW_DBG_START_FROM_ALIVE;
|
||||
iwl_fw_start_dbg_conf(&mvm->fwrt, FW_DBG_START_FROM_ALIVE);
|
||||
}
|
||||
|
||||
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
|
||||
if (ret)
|
||||
|
@ -1532,6 +1532,8 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_beacon_loss_iterator,
|
||||
mb);
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_MISSED_BEACONS);
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
|
||||
|
@ -1129,6 +1129,8 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
|
||||
}
|
||||
ret = iwl_mvm_up(mvm);
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_POST_INIT);
|
||||
|
||||
if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
|
||||
/* Something went wrong - we need to finish some cleanup
|
||||
* that normally iwl_mvm_mac_restart_complete() below
|
||||
@ -2021,7 +2023,13 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
|
||||
if (sta->he_cap.he_cap_elem.mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
|
||||
sta_ctxt_cmd.htc_flags |= cpu_to_le32(IWL_HE_HTC_BQR_SUPP);
|
||||
|
||||
/* If PPE Thresholds exist, parse them into a FW-familiar format */
|
||||
/*
|
||||
* Initialize the PPE thresholds to "None" (7), as described in Table
|
||||
* 9-262ac of 80211.ax/D3.0.
|
||||
*/
|
||||
memset(&sta_ctxt_cmd.pkt_ext, 7, sizeof(sta_ctxt_cmd.pkt_ext));
|
||||
|
||||
/* If PPE Thresholds exist, parse them into a FW-familiar format. */
|
||||
if (sta->he_cap.he_cap_elem.phy_cap_info[6] &
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
|
||||
u8 nss = (sta->he_cap.ppe_thres[0] &
|
||||
@ -3386,7 +3394,7 @@ static bool iwl_mvm_rx_aux_roc(struct iwl_notif_wait_data *notif_wait,
|
||||
resp = (void *)pkt->data;
|
||||
|
||||
IWL_DEBUG_TE(mvm,
|
||||
"Aux ROC: Recieved response from ucode: status=%d uid=%d\n",
|
||||
"Aux ROC: Received response from ucode: status=%d uid=%d\n",
|
||||
resp->status, resp->event_unique_id);
|
||||
|
||||
te_data->uid = le32_to_cpu(resp->event_unique_id);
|
||||
|
@ -1556,6 +1556,8 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
void iwl_mvm_rx_monitor_ndp(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
|
||||
|
@ -1073,6 +1073,8 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode,
|
||||
iwl_mvm_rx_queue_notif(mvm, rxb, 0);
|
||||
else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE))
|
||||
iwl_mvm_rx_frame_release(mvm, napi, rxb, 0);
|
||||
else if (cmd == WIDE_ID(DATA_PATH_GROUP, RX_NO_DATA_NOTIF))
|
||||
iwl_mvm_rx_monitor_ndp(mvm, napi, rxb, 0);
|
||||
else
|
||||
iwl_mvm_rx_common(mvm, rxb, pkt);
|
||||
}
|
||||
|
@ -593,31 +593,28 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
|
||||
int hyst = vif->bss_conf.cqm_rssi_hyst;
|
||||
u16 id = le32_to_cpu(data->mac_id);
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
u16 vif_id = mvmvif->id;
|
||||
|
||||
/* This doesn't need the MAC ID check since it's not taking the
|
||||
* data copied into the "data" struct, but rather the data from
|
||||
* the notification directly.
|
||||
*/
|
||||
if (data->general) {
|
||||
u16 vif_id = mvmvif->id;
|
||||
if (iwl_mvm_is_cdb_supported(mvm)) {
|
||||
struct mvm_statistics_general_cdb *general =
|
||||
data->general;
|
||||
|
||||
if (iwl_mvm_is_cdb_supported(mvm)) {
|
||||
struct mvm_statistics_general_cdb *general =
|
||||
data->general;
|
||||
mvmvif->beacon_stats.num_beacons =
|
||||
le32_to_cpu(general->beacon_counter[vif_id]);
|
||||
mvmvif->beacon_stats.avg_signal =
|
||||
-general->beacon_average_energy[vif_id];
|
||||
} else {
|
||||
struct mvm_statistics_general_v8 *general =
|
||||
data->general;
|
||||
|
||||
mvmvif->beacon_stats.num_beacons =
|
||||
le32_to_cpu(general->beacon_counter[vif_id]);
|
||||
mvmvif->beacon_stats.avg_signal =
|
||||
-general->beacon_average_energy[vif_id];
|
||||
} else {
|
||||
struct mvm_statistics_general_v8 *general =
|
||||
data->general;
|
||||
|
||||
mvmvif->beacon_stats.num_beacons =
|
||||
le32_to_cpu(general->beacon_counter[vif_id]);
|
||||
mvmvif->beacon_stats.avg_signal =
|
||||
-general->beacon_average_energy[vif_id];
|
||||
}
|
||||
mvmvif->beacon_stats.num_beacons =
|
||||
le32_to_cpu(general->beacon_counter[vif_id]);
|
||||
mvmvif->beacon_stats.avg_signal =
|
||||
-general->beacon_average_energy[vif_id];
|
||||
}
|
||||
|
||||
if (mvmvif->id != id)
|
||||
|
@ -200,7 +200,8 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
|
||||
{
|
||||
struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
|
||||
|
||||
if (iwl_mvm_check_pn(mvm, skb, queue, sta)) {
|
||||
if (!(rx_status->flag & RX_FLAG_NO_PSDU) &&
|
||||
iwl_mvm_check_pn(mvm, skb, queue, sta)) {
|
||||
kfree_skb(skb);
|
||||
} else {
|
||||
unsigned int radiotap_len = 0;
|
||||
@ -863,68 +864,66 @@ static void iwl_mvm_flip_address(u8 *addr)
|
||||
ether_addr_copy(addr, mac_addr);
|
||||
}
|
||||
|
||||
static void iwl_mvm_decode_he_sigb(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_mpdu_desc *desc,
|
||||
u32 rate_n_flags,
|
||||
struct ieee80211_radiotap_he_mu *he_mu)
|
||||
struct iwl_mvm_rx_phy_data {
|
||||
enum iwl_rx_phy_info_type info_type;
|
||||
__le32 d0, d1, d2, d3;
|
||||
__le16 d4;
|
||||
};
|
||||
|
||||
static void iwl_mvm_decode_he_mu_ext(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_rx_phy_data *phy_data,
|
||||
u32 rate_n_flags,
|
||||
struct ieee80211_radiotap_he_mu *he_mu)
|
||||
{
|
||||
u32 sigb0, sigb1;
|
||||
u16 sigb2;
|
||||
u32 phy_data2 = le32_to_cpu(phy_data->d2);
|
||||
u32 phy_data3 = le32_to_cpu(phy_data->d3);
|
||||
u16 phy_data4 = le16_to_cpu(phy_data->d4);
|
||||
|
||||
if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
sigb0 = le32_to_cpu(desc->v3.sigb_common0);
|
||||
sigb1 = le32_to_cpu(desc->v3.sigb_common1);
|
||||
} else {
|
||||
sigb0 = le32_to_cpu(desc->v1.sigb_common0);
|
||||
sigb1 = le32_to_cpu(desc->v1.sigb_common1);
|
||||
}
|
||||
|
||||
sigb2 = le16_to_cpu(desc->sigb_common2);
|
||||
|
||||
if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH1_CRC_OK, sigb2)) {
|
||||
if (FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CRC_OK, phy_data4)) {
|
||||
he_mu->flags1 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU_KNOWN);
|
||||
|
||||
he_mu->flags1 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH1_CTR_RU,
|
||||
sigb2),
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CTR_RU,
|
||||
phy_data4),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU);
|
||||
|
||||
he_mu->ru_ch1[0] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH1_RU0,
|
||||
sigb0);
|
||||
he_mu->ru_ch1[1] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH1_RU1,
|
||||
sigb1);
|
||||
he_mu->ru_ch1[2] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH1_RU2,
|
||||
sigb0);
|
||||
he_mu->ru_ch1[3] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH1_RU3,
|
||||
sigb1);
|
||||
he_mu->ru_ch1[0] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU0,
|
||||
phy_data2);
|
||||
he_mu->ru_ch1[1] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU1,
|
||||
phy_data3);
|
||||
he_mu->ru_ch1[2] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU2,
|
||||
phy_data2);
|
||||
he_mu->ru_ch1[3] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU3,
|
||||
phy_data3);
|
||||
}
|
||||
|
||||
if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK, sigb2) &&
|
||||
if (FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CRC_OK, phy_data4) &&
|
||||
(rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) != RATE_MCS_CHAN_WIDTH_20) {
|
||||
he_mu->flags1 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN);
|
||||
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CTR_RU,
|
||||
sigb2),
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CTR_RU,
|
||||
phy_data4),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_CH2_CTR_26T_RU);
|
||||
|
||||
he_mu->ru_ch2[0] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH2_RU0,
|
||||
sigb0);
|
||||
he_mu->ru_ch2[1] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH2_RU1,
|
||||
sigb1);
|
||||
he_mu->ru_ch2[2] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH2_RU2,
|
||||
sigb0);
|
||||
he_mu->ru_ch2[3] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH2_RU3,
|
||||
sigb1);
|
||||
he_mu->ru_ch2[0] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU0,
|
||||
phy_data2);
|
||||
he_mu->ru_ch2[1] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU1,
|
||||
phy_data3);
|
||||
he_mu->ru_ch2[2] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU2,
|
||||
phy_data2);
|
||||
he_mu->ru_ch2[3] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU3,
|
||||
phy_data3);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mvm_decode_he_phy_ru_alloc(u64 he_phy_data, u32 rate_n_flags,
|
||||
iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data,
|
||||
u32 rate_n_flags,
|
||||
struct ieee80211_radiotap_he *he,
|
||||
struct ieee80211_radiotap_he_mu *he_mu,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
@ -937,7 +936,7 @@ iwl_mvm_decode_he_phy_ru_alloc(u64 he_phy_data, u32 rate_n_flags,
|
||||
* happen though as management frames where we need
|
||||
* the TSF/timers are not be transmitted in HE-MU.
|
||||
*/
|
||||
u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data);
|
||||
u8 ru = le32_get_bits(phy_data->d1, IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK);
|
||||
u8 offs = 0;
|
||||
|
||||
rx_status->bw = RATE_INFO_BW_HE_RU;
|
||||
@ -976,7 +975,7 @@ iwl_mvm_decode_he_phy_ru_alloc(u64 he_phy_data, u32 rate_n_flags,
|
||||
IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
|
||||
he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET_KNOWN);
|
||||
if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80)
|
||||
if (phy_data->d1 & cpu_to_le32(IWL_RX_PHY_DATA1_HE_RU_ALLOC_SEC80))
|
||||
he->data2 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC);
|
||||
|
||||
@ -996,106 +995,122 @@ iwl_mvm_decode_he_phy_ru_alloc(u64 he_phy_data, u32 rate_n_flags,
|
||||
}
|
||||
|
||||
static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_mpdu_desc *desc,
|
||||
struct iwl_mvm_rx_phy_data *phy_data,
|
||||
struct ieee80211_radiotap_he *he,
|
||||
struct ieee80211_radiotap_he_mu *he_mu,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u64 he_phy_data, u32 rate_n_flags,
|
||||
int queue)
|
||||
u32 rate_n_flags, int queue)
|
||||
{
|
||||
u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
|
||||
bool sigb_data;
|
||||
u16 d1known = IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN;
|
||||
u16 d2known = IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN;
|
||||
|
||||
he->data1 |= cpu_to_le16(d1known);
|
||||
he->data2 |= cpu_to_le16(d2known);
|
||||
he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR);
|
||||
he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_UPLINK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
|
||||
he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_LDPC_EXT_SYM,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG);
|
||||
he->data4 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SPATIAL_REUSE_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE);
|
||||
he->data5 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PRE_FEC_PAD_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD);
|
||||
he->data5 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PE_DISAMBIG,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG);
|
||||
he->data6 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_TXOP_DUR_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA6_TXOP);
|
||||
he->data6 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_DOPPLER,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA6_DOPPLER);
|
||||
|
||||
switch (he_type) {
|
||||
case RATE_MCS_HE_TYPE_MU:
|
||||
he_mu->flags1 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_DCM,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM);
|
||||
he_mu->flags1 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_MCS_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS);
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIBG_SYM_OR_USER_NUM_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS);
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_COMPRESSION,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP);
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_PREAMBLE_PUNC_TYPE_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW);
|
||||
|
||||
sigb_data = FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK,
|
||||
he_phy_data) ==
|
||||
IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO;
|
||||
if (sigb_data)
|
||||
iwl_mvm_decode_he_sigb(mvm, desc, rate_n_flags, he_mu);
|
||||
switch (phy_data->info_type) {
|
||||
case IWL_RX_PHY_INFO_TYPE_NONE:
|
||||
case IWL_RX_PHY_INFO_TYPE_CCK:
|
||||
case IWL_RX_PHY_INFO_TYPE_OFDM_LGCY:
|
||||
case IWL_RX_PHY_INFO_TYPE_HT:
|
||||
case IWL_RX_PHY_INFO_TYPE_VHT_SU:
|
||||
case IWL_RX_PHY_INFO_TYPE_VHT_MU:
|
||||
return;
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT:
|
||||
he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN);
|
||||
he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1);
|
||||
he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2);
|
||||
he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3);
|
||||
he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4);
|
||||
/* fall through */
|
||||
case RATE_MCS_HE_TYPE_TRIG:
|
||||
he->data2 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
|
||||
he->data5 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_HE_LTF_NUM_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS);
|
||||
break;
|
||||
case RATE_MCS_HE_TYPE_SU:
|
||||
case RATE_MCS_HE_TYPE_EXT_SU:
|
||||
he->data1 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN);
|
||||
he->data3 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BEAM_CHNG,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE);
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_SU:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB:
|
||||
/* HE common */
|
||||
he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN);
|
||||
he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
|
||||
he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_BSS_COLOR_MASK),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR);
|
||||
if (phy_data->info_type != IWL_RX_PHY_INFO_TYPE_HE_TB &&
|
||||
phy_data->info_type != IWL_RX_PHY_INFO_TYPE_HE_TB_EXT) {
|
||||
he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN);
|
||||
he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_UPLINK),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
|
||||
}
|
||||
he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG);
|
||||
he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE);
|
||||
he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD);
|
||||
he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_PE_DISAMBIG),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG);
|
||||
he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d1,
|
||||
IWL_RX_PHY_DATA1_HE_LTF_NUM_MASK),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS);
|
||||
he->data6 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_TXOP_DUR_MASK),
|
||||
IEEE80211_RADIOTAP_HE_DATA6_TXOP);
|
||||
he->data6 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_DOPPLER),
|
||||
IEEE80211_RADIOTAP_HE_DATA6_DOPPLER);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK, he_phy_data)) {
|
||||
case IWL_RX_HE_PHY_INFO_TYPE_MU:
|
||||
case IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO:
|
||||
case IWL_RX_HE_PHY_INFO_TYPE_TB:
|
||||
iwl_mvm_decode_he_phy_ru_alloc(he_phy_data, rate_n_flags,
|
||||
switch (phy_data->info_type) {
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT:
|
||||
he_mu->flags1 |=
|
||||
le16_encode_bits(le16_get_bits(phy_data->d4,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_DCM),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM);
|
||||
he_mu->flags1 |=
|
||||
le16_encode_bits(le16_get_bits(phy_data->d4,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_MCS_MASK),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS);
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(le16_get_bits(phy_data->d4,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_PREAMBLE_PUNC_TYPE_MASK),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW);
|
||||
iwl_mvm_decode_he_mu_ext(mvm, phy_data, rate_n_flags, he_mu);
|
||||
/* fall through */
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU:
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(le32_get_bits(phy_data->d1,
|
||||
IWL_RX_PHY_DATA1_HE_MU_SIBG_SYM_OR_USER_NUM_MASK),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS);
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(le32_get_bits(phy_data->d1,
|
||||
IWL_RX_PHY_DATA1_HE_MU_SIGB_COMPRESSION),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP);
|
||||
/* fall through */
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT:
|
||||
iwl_mvm_decode_he_phy_ru_alloc(phy_data, rate_n_flags,
|
||||
he, he_mu, rx_status);
|
||||
break;
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_SU:
|
||||
he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN);
|
||||
he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_BEAM_CHNG),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE);
|
||||
break;
|
||||
default:
|
||||
/* nothing */
|
||||
break;
|
||||
@ -1103,13 +1118,10 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct iwl_rx_mpdu_desc *desc,
|
||||
struct iwl_mvm_rx_phy_data *phy_data,
|
||||
u32 rate_n_flags, u16 phy_info, int queue)
|
||||
{
|
||||
struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
|
||||
/* this is invalid e.g. because puncture type doesn't allow 0b11 */
|
||||
#define HE_PHY_DATA_INVAL ((u64)-1)
|
||||
u64 he_phy_data = HE_PHY_DATA_INVAL;
|
||||
struct ieee80211_radiotap_he *he = NULL;
|
||||
struct ieee80211_radiotap_he_mu *he_mu = NULL;
|
||||
u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
|
||||
@ -1136,49 +1148,41 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
radiotap_len += sizeof(known);
|
||||
rx_status->flag |= RX_FLAG_RADIOTAP_HE;
|
||||
|
||||
if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) {
|
||||
if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
he_phy_data = le64_to_cpu(desc->v3.he_phy_data);
|
||||
else
|
||||
he_phy_data = le64_to_cpu(desc->v1.he_phy_data);
|
||||
|
||||
if (he_type == RATE_MCS_HE_TYPE_MU) {
|
||||
he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known));
|
||||
radiotap_len += sizeof(mu_known);
|
||||
rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU;
|
||||
}
|
||||
if (phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU ||
|
||||
phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU_EXT) {
|
||||
he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known));
|
||||
radiotap_len += sizeof(mu_known);
|
||||
rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU;
|
||||
}
|
||||
|
||||
/* temporarily hide the radiotap data */
|
||||
__skb_pull(skb, radiotap_len);
|
||||
|
||||
if (he_phy_data != HE_PHY_DATA_INVAL &&
|
||||
he_type == RATE_MCS_HE_TYPE_SU) {
|
||||
if (phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_SU) {
|
||||
/* report the AMPDU-EOF bit on single frames */
|
||||
if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
|
||||
rx_status->flag |= RX_FLAG_AMPDU_DETAILS;
|
||||
rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
|
||||
if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF, he_phy_data))
|
||||
if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_HE_DELIM_EOF))
|
||||
rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
if (he_phy_data != HE_PHY_DATA_INVAL)
|
||||
iwl_mvm_decode_he_phy_data(mvm, desc, he, he_mu, rx_status,
|
||||
he_phy_data, rate_n_flags, queue);
|
||||
if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD)
|
||||
iwl_mvm_decode_he_phy_data(mvm, phy_data, he, he_mu, rx_status,
|
||||
rate_n_flags, queue);
|
||||
|
||||
/* update aggregation data for monitor sake on default queue */
|
||||
if (!queue && (phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
|
||||
if (!queue && (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) &&
|
||||
(phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
|
||||
bool toggle_bit = phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE;
|
||||
|
||||
/* toggle is switched whenever new aggregation starts */
|
||||
if (toggle_bit != mvm->ampdu_toggle &&
|
||||
he_phy_data != HE_PHY_DATA_INVAL &&
|
||||
(he_type == RATE_MCS_HE_TYPE_MU ||
|
||||
he_type == RATE_MCS_HE_TYPE_SU)) {
|
||||
rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
|
||||
if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF,
|
||||
he_phy_data))
|
||||
if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_HE_DELIM_EOF))
|
||||
rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
|
||||
}
|
||||
}
|
||||
@ -1261,43 +1265,34 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
break;
|
||||
}
|
||||
|
||||
he->data5 |= le16_encode_bits(ltf, IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
|
||||
he->data5 |= le16_encode_bits(ltf,
|
||||
IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
|
||||
}
|
||||
|
||||
if (he_type == RATE_MCS_HE_TYPE_SU ||
|
||||
he_type == RATE_MCS_HE_TYPE_EXT_SU) {
|
||||
u16 val;
|
||||
static void iwl_mvm_decode_lsig(struct sk_buff *skb,
|
||||
struct iwl_mvm_rx_phy_data *phy_data)
|
||||
{
|
||||
struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
|
||||
struct ieee80211_radiotap_lsig *lsig;
|
||||
|
||||
/* LTF syms correspond to streams */
|
||||
he->data2 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
|
||||
switch (rx_status->nss) {
|
||||
case 1:
|
||||
val = 0;
|
||||
break;
|
||||
case 2:
|
||||
val = 1;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
val = 2;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
val = 3;
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
val = 4;
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "invalid nss: %d\n",
|
||||
rx_status->nss);
|
||||
val = 0;
|
||||
}
|
||||
|
||||
he->data5 |=
|
||||
le16_encode_bits(val,
|
||||
IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS);
|
||||
switch (phy_data->info_type) {
|
||||
case IWL_RX_PHY_INFO_TYPE_HT:
|
||||
case IWL_RX_PHY_INFO_TYPE_VHT_SU:
|
||||
case IWL_RX_PHY_INFO_TYPE_VHT_MU:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_SU:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB:
|
||||
lsig = skb_put(skb, sizeof(*lsig));
|
||||
lsig->data1 = cpu_to_le16(IEEE80211_RADIOTAP_LSIG_DATA1_LENGTH_KNOWN);
|
||||
lsig->data2 = le16_encode_bits(le32_get_bits(phy_data->d1,
|
||||
IWL_RX_PHY_DATA1_LSIG_LEN_MASK),
|
||||
IEEE80211_RADIOTAP_LSIG_DATA2_LENGTH);
|
||||
rx_status->flag |= RX_FLAG_RADIOTAP_LSIG;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1315,6 +1310,10 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct sk_buff *skb;
|
||||
u8 crypt_len = 0, channel, energy_a, energy_b;
|
||||
size_t desc_size;
|
||||
struct iwl_mvm_rx_phy_data phy_data = {
|
||||
.d4 = desc->phy_data4,
|
||||
.info_type = IWL_RX_PHY_INFO_TYPE_NONE,
|
||||
};
|
||||
|
||||
if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)))
|
||||
return;
|
||||
@ -1326,6 +1325,11 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
energy_a = desc->v3.energy_a;
|
||||
energy_b = desc->v3.energy_b;
|
||||
desc_size = sizeof(*desc);
|
||||
|
||||
phy_data.d0 = desc->v3.phy_data0;
|
||||
phy_data.d1 = desc->v3.phy_data1;
|
||||
phy_data.d2 = desc->v3.phy_data2;
|
||||
phy_data.d3 = desc->v3.phy_data3;
|
||||
} else {
|
||||
rate_n_flags = le32_to_cpu(desc->v1.rate_n_flags);
|
||||
channel = desc->v1.channel;
|
||||
@ -1333,8 +1337,18 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
energy_a = desc->v1.energy_a;
|
||||
energy_b = desc->v1.energy_b;
|
||||
desc_size = IWL_RX_DESC_SIZE_V1;
|
||||
|
||||
phy_data.d0 = desc->v1.phy_data0;
|
||||
phy_data.d1 = desc->v1.phy_data1;
|
||||
phy_data.d2 = desc->v1.phy_data2;
|
||||
phy_data.d3 = desc->v1.phy_data3;
|
||||
}
|
||||
|
||||
if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD)
|
||||
phy_data.info_type =
|
||||
le32_get_bits(phy_data.d1,
|
||||
IWL_RX_PHY_DATA1_INFO_TYPE_MASK);
|
||||
|
||||
hdr = (void *)(pkt->data + desc_size);
|
||||
/* Dont use dev_alloc_skb(), we'll have enough headroom once
|
||||
* ieee80211_hdr pulled.
|
||||
@ -1373,7 +1387,10 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
}
|
||||
|
||||
if (rate_n_flags & RATE_MCS_HE_MSK)
|
||||
iwl_mvm_rx_he(mvm, skb, desc, rate_n_flags, phy_info, queue);
|
||||
iwl_mvm_rx_he(mvm, skb, &phy_data, rate_n_flags,
|
||||
phy_info, queue);
|
||||
|
||||
iwl_mvm_decode_lsig(skb, &phy_data);
|
||||
|
||||
rx_status = IEEE80211_SKB_RXCB(skb);
|
||||
|
||||
@ -1590,6 +1607,129 @@ out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_monitor_ndp(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue)
|
||||
{
|
||||
struct ieee80211_rx_status *rx_status;
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_rx_no_data *desc = (void *)pkt->data;
|
||||
u32 rate_n_flags = le32_to_cpu(desc->rate);
|
||||
u32 gp2_on_air_rise = le32_to_cpu(desc->on_air_rise_time);
|
||||
u32 rssi = le32_to_cpu(desc->rssi);
|
||||
u32 info_type = le32_to_cpu(desc->info) & RX_NO_DATA_INFO_TYPE_MSK;
|
||||
u16 phy_info = IWL_RX_MPDU_PHY_TSF_OVERLOAD;
|
||||
struct ieee80211_sta *sta = NULL;
|
||||
struct sk_buff *skb;
|
||||
u8 channel, energy_a, energy_b;
|
||||
struct iwl_mvm_rx_phy_data phy_data = {
|
||||
.d0 = desc->phy_info[0],
|
||||
.info_type = IWL_RX_PHY_INFO_TYPE_NONE,
|
||||
};
|
||||
|
||||
if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)))
|
||||
return;
|
||||
|
||||
/* Currently only NDP type is supported */
|
||||
if (info_type != RX_NO_DATA_INFO_TYPE_NDP)
|
||||
return;
|
||||
|
||||
energy_a = (rssi & RX_NO_DATA_CHAIN_A_MSK) >> RX_NO_DATA_CHAIN_A_POS;
|
||||
energy_b = (rssi & RX_NO_DATA_CHAIN_B_MSK) >> RX_NO_DATA_CHAIN_B_POS;
|
||||
channel = (rssi & RX_NO_DATA_CHANNEL_MSK) >> RX_NO_DATA_CHANNEL_POS;
|
||||
|
||||
phy_data.info_type =
|
||||
le32_get_bits(desc->phy_info[1],
|
||||
IWL_RX_PHY_DATA1_INFO_TYPE_MASK);
|
||||
|
||||
/* Dont use dev_alloc_skb(), we'll have enough headroom once
|
||||
* ieee80211_hdr pulled.
|
||||
*/
|
||||
skb = alloc_skb(128, GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
IWL_ERR(mvm, "alloc_skb failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rx_status = IEEE80211_SKB_RXCB(skb);
|
||||
|
||||
/* 0-length PSDU */
|
||||
rx_status->flag |= RX_FLAG_NO_PSDU;
|
||||
/* currently this is the only type for which we get this notif */
|
||||
rx_status->zero_length_psdu_type =
|
||||
IEEE80211_RADIOTAP_ZERO_LEN_PSDU_SOUNDING;
|
||||
|
||||
/* This may be overridden by iwl_mvm_rx_he() to HE_RU */
|
||||
switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
|
||||
case RATE_MCS_CHAN_WIDTH_20:
|
||||
break;
|
||||
case RATE_MCS_CHAN_WIDTH_40:
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
break;
|
||||
case RATE_MCS_CHAN_WIDTH_80:
|
||||
rx_status->bw = RATE_INFO_BW_80;
|
||||
break;
|
||||
case RATE_MCS_CHAN_WIDTH_160:
|
||||
rx_status->bw = RATE_INFO_BW_160;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rate_n_flags & RATE_MCS_HE_MSK)
|
||||
iwl_mvm_rx_he(mvm, skb, &phy_data, rate_n_flags,
|
||||
phy_info, queue);
|
||||
|
||||
iwl_mvm_decode_lsig(skb, &phy_data);
|
||||
|
||||
rx_status->device_timestamp = gp2_on_air_rise;
|
||||
rx_status->band = channel > 14 ? NL80211_BAND_5GHZ :
|
||||
NL80211_BAND_2GHZ;
|
||||
rx_status->freq = ieee80211_channel_to_frequency(channel,
|
||||
rx_status->band);
|
||||
iwl_mvm_get_signal_strength(mvm, rx_status, rate_n_flags, energy_a,
|
||||
energy_b);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
if (!(rate_n_flags & RATE_MCS_CCK_MSK) &&
|
||||
rate_n_flags & RATE_MCS_SGI_MSK)
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
if (rate_n_flags & RATE_HT_MCS_GF_MSK)
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_HT_GF;
|
||||
if (rate_n_flags & RATE_MCS_LDPC_MSK)
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_LDPC;
|
||||
if (rate_n_flags & RATE_MCS_HT_MSK) {
|
||||
u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
|
||||
RATE_MCS_STBC_POS;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
|
||||
rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
|
||||
} else if (rate_n_flags & RATE_MCS_VHT_MSK) {
|
||||
u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
|
||||
RATE_MCS_STBC_POS;
|
||||
rx_status->nss =
|
||||
((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
|
||||
RATE_VHT_MCS_NSS_POS) + 1;
|
||||
rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
|
||||
rx_status->encoding = RX_ENC_VHT;
|
||||
rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
|
||||
if (rate_n_flags & RATE_MCS_BF_MSK)
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_BF;
|
||||
} else if (!(rate_n_flags & RATE_MCS_HE_MSK)) {
|
||||
int rate = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
|
||||
rx_status->band);
|
||||
|
||||
if (WARN(rate < 0 || rate > 0xFF,
|
||||
"Invalid rate flags 0x%x, band %d,\n",
|
||||
rate_n_flags, rx_status->band)) {
|
||||
kfree_skb(skb);
|
||||
goto out;
|
||||
}
|
||||
rx_status->rate_idx = rate;
|
||||
}
|
||||
|
||||
iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue, sta);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue)
|
||||
{
|
||||
|
@ -1893,6 +1893,8 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
|
||||
mvm->last_ebs_successful = false;
|
||||
|
||||
mvm->scan_uid_status[uid] = 0;
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_SCAN_COMPLETE);
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
|
||||
|
@ -1254,6 +1254,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
|
||||
|
||||
spin_lock_bh(&mvmsta->lock);
|
||||
tfd_queue_mask = mvmsta->tfd_queue_msk;
|
||||
ssn = IEEE80211_SEQ_TO_SN(mvmsta->tid_data[tid].seq_number);
|
||||
spin_unlock_bh(&mvmsta->lock);
|
||||
|
||||
/*
|
||||
@ -1340,13 +1341,8 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
|
||||
}
|
||||
}
|
||||
|
||||
ssn = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
|
||||
inc_ssn = iwl_mvm_enable_txq(mvm, queue, mac_queue,
|
||||
ssn, &cfg, wdg_timeout);
|
||||
if (inc_ssn) {
|
||||
ssn = (ssn + 1) & IEEE80211_SCTL_SEQ;
|
||||
le16_add_cpu(&hdr->seq_ctrl, 0x10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark queue as shared in transport if shared
|
||||
@ -1363,8 +1359,10 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
|
||||
* this ra/tid in our Tx path since we stop the Qdisc when we
|
||||
* need to allocate a new TFD queue.
|
||||
*/
|
||||
if (inc_ssn)
|
||||
if (inc_ssn) {
|
||||
mvmsta->tid_data[tid].seq_number += 0x10;
|
||||
ssn = (ssn + 1) & IEEE80211_SCTL_SEQ;
|
||||
}
|
||||
mvmsta->tid_data[tid].txq_id = queue;
|
||||
mvmsta->tfd_queue_msk |= BIT(queue);
|
||||
queue_state = mvmsta->tid_data[tid].state;
|
||||
|
@ -708,22 +708,12 @@ out:
|
||||
int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_tx_info info;
|
||||
struct iwl_device_cmd *dev_cmd;
|
||||
u8 sta_id;
|
||||
int hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
__le16 fc = hdr->frame_control;
|
||||
int queue;
|
||||
|
||||
/* IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used
|
||||
* in 2 different types of vifs, P2P & STATION. P2P uses the offchannel
|
||||
* queue. STATION (HS2.0) uses the auxiliary context of the FW,
|
||||
* and hence needs to be sent on the aux queue
|
||||
*/
|
||||
if (skb_info->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
|
||||
skb_info->control.vif->type == NL80211_IFTYPE_STATION)
|
||||
skb_info->hw_queue = mvm->aux_queue;
|
||||
int queue = -1;
|
||||
|
||||
memcpy(&info, skb->cb, sizeof(info));
|
||||
|
||||
@ -735,18 +725,6 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
|
||||
info.hw_queue != info.control.vif->cab_queue)))
|
||||
return -1;
|
||||
|
||||
queue = info.hw_queue;
|
||||
|
||||
/*
|
||||
* If the interface on which the frame is sent is the P2P_DEVICE
|
||||
* or an AP/GO interface use the broadcast station associated
|
||||
* with it; otherwise if the interface is a managed interface
|
||||
* use the AP station associated with it for multicast traffic
|
||||
* (this is not possible for unicast packets as a TLDS discovery
|
||||
* response are sent without a station entry); otherwise use the
|
||||
* AUX station.
|
||||
*/
|
||||
sta_id = mvm->aux_sta.sta_id;
|
||||
if (info.control.vif) {
|
||||
struct iwl_mvm_vif *mvmvif =
|
||||
iwl_mvm_vif_from_mac80211(info.control.vif);
|
||||
@ -761,20 +739,28 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
|
||||
|
||||
queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info,
|
||||
hdr->frame_control);
|
||||
if (queue < 0)
|
||||
return -1;
|
||||
} else if (info.control.vif->type == NL80211_IFTYPE_STATION &&
|
||||
is_multicast_ether_addr(hdr->addr1)) {
|
||||
u8 ap_sta_id = READ_ONCE(mvmvif->ap_sta_id);
|
||||
|
||||
if (ap_sta_id != IWL_MVM_INVALID_STA)
|
||||
sta_id = ap_sta_id;
|
||||
} else if (info.control.vif->type == NL80211_IFTYPE_MONITOR) {
|
||||
queue = mvm->snif_queue;
|
||||
sta_id = mvm->snif_sta.sta_id;
|
||||
} else if (info.control.vif->type == NL80211_IFTYPE_STATION &&
|
||||
info.hw_queue == IWL_MVM_OFFCHANNEL_QUEUE) {
|
||||
/*
|
||||
* IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets
|
||||
* that can be used in 2 different types of vifs, P2P &
|
||||
* STATION.
|
||||
* P2P uses the offchannel queue.
|
||||
* STATION (HS2.0) uses the auxiliary context of the FW,
|
||||
* and hence needs to be sent on the aux queue.
|
||||
*/
|
||||
sta_id = mvm->aux_sta.sta_id;
|
||||
queue = mvm->aux_queue;
|
||||
}
|
||||
}
|
||||
|
||||
if (queue < 0)
|
||||
return -1;
|
||||
|
||||
if (unlikely(ieee80211_is_probe_resp(fc)))
|
||||
iwl_mvm_probe_resp_set_noa(mvm, skb);
|
||||
|
||||
@ -1478,7 +1464,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
||||
iwl_mvm_get_agg_status(mvm, tx_resp);
|
||||
u32 status = le16_to_cpu(agg_status->status);
|
||||
u16 ssn = iwl_mvm_get_scd_ssn(mvm, tx_resp);
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
struct sk_buff_head skbs;
|
||||
u8 skb_freed = 0;
|
||||
u8 lq_color;
|
||||
@ -1626,7 +1611,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
||||
goto out;
|
||||
|
||||
if (!IS_ERR(sta)) {
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
iwl_mvm_tx_airtime(mvm, mvmsta,
|
||||
le16_to_cpu(tx_resp->wireless_media_time));
|
||||
@ -1689,10 +1674,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
||||
mvmsta->next_status_eosp = false;
|
||||
ieee80211_sta_eosp(sta);
|
||||
}
|
||||
} else {
|
||||
mvmsta = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
@ -1835,8 +1817,6 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_bh(&mvmsta->lock);
|
||||
|
||||
__skb_queue_head_init(&reclaimed_skbs);
|
||||
|
||||
/*
|
||||
@ -1846,6 +1826,8 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,
|
||||
*/
|
||||
iwl_trans_reclaim(mvm->trans, txq, index, &reclaimed_skbs);
|
||||
|
||||
spin_lock_bh(&mvmsta->lock);
|
||||
|
||||
tid_data->next_reclaimed = index;
|
||||
|
||||
iwl_mvm_check_ratid_empty(mvm, sta, tid);
|
||||
|
@ -540,6 +540,9 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u32 base)
|
||||
|
||||
iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
|
||||
|
||||
if (table.valid)
|
||||
mvm->fwrt.dump.rt_status = table.error_id;
|
||||
|
||||
if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
|
||||
IWL_ERR(trans, "Start IWL Error Log Dump:\n");
|
||||
IWL_ERR(trans, "Status: 0x%08lX, count: %d\n",
|
||||
@ -1378,6 +1381,7 @@ void iwl_mvm_pause_tcm(struct iwl_mvm *mvm, bool with_cancel)
|
||||
void iwl_mvm_resume_tcm(struct iwl_mvm *mvm)
|
||||
{
|
||||
int mac;
|
||||
bool low_latency = false;
|
||||
|
||||
spin_lock_bh(&mvm->tcm.lock);
|
||||
mvm->tcm.ts = jiffies;
|
||||
@ -1389,10 +1393,23 @@ void iwl_mvm_resume_tcm(struct iwl_mvm *mvm)
|
||||
memset(&mdata->tx.pkts, 0, sizeof(mdata->tx.pkts));
|
||||
memset(&mdata->rx.airtime, 0, sizeof(mdata->rx.airtime));
|
||||
memset(&mdata->tx.airtime, 0, sizeof(mdata->tx.airtime));
|
||||
|
||||
if (mvm->tcm.result.low_latency[mac])
|
||||
low_latency = true;
|
||||
}
|
||||
/* The TCM data needs to be reset before "paused" flag changes */
|
||||
smp_mb();
|
||||
mvm->tcm.paused = false;
|
||||
|
||||
/*
|
||||
* if the current load is not low or low latency is active, force
|
||||
* re-evaluation to cover the case of no traffic.
|
||||
*/
|
||||
if (mvm->tcm.result.global_load > IWL_MVM_TRAFFIC_LOW)
|
||||
schedule_delayed_work(&mvm->tcm.work, MVM_TCM_PERIOD);
|
||||
else if (low_latency)
|
||||
schedule_delayed_work(&mvm->tcm.work, MVM_LL_PERIOD);
|
||||
|
||||
spin_unlock_bh(&mvm->tcm.lock);
|
||||
}
|
||||
|
||||
|
@ -94,11 +94,14 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
|
||||
cpu_to_le64(trans_pcie->rxq->bd_dma);
|
||||
|
||||
/* Configure debug, for integration */
|
||||
iwl_pcie_alloc_fw_monitor(trans, 0);
|
||||
prph_sc_ctrl->hwm_cfg.hwm_base_addr =
|
||||
cpu_to_le64(trans->fw_mon[0].physical);
|
||||
prph_sc_ctrl->hwm_cfg.hwm_size =
|
||||
cpu_to_le32(trans->fw_mon[0].size);
|
||||
if (!trans->ini_valid)
|
||||
iwl_pcie_alloc_fw_monitor(trans, 0);
|
||||
if (trans->num_blocks) {
|
||||
prph_sc_ctrl->hwm_cfg.hwm_base_addr =
|
||||
cpu_to_le64(trans->fw_mon[0].physical);
|
||||
prph_sc_ctrl->hwm_cfg.hwm_size =
|
||||
cpu_to_le32(trans->fw_mon[0].size);
|
||||
}
|
||||
|
||||
/* allocate ucode sections in dram and set addresses */
|
||||
ret = iwl_pcie_init_fw_sec(trans, fw, &prph_scratch->dram);
|
||||
|
@ -227,7 +227,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans,
|
||||
iwl_enable_interrupts(trans);
|
||||
|
||||
/* Configure debug, if exists */
|
||||
if (trans->dbg_dest_tlv)
|
||||
if (iwl_pcie_dbg_on(trans))
|
||||
iwl_pcie_apply_destination(trans);
|
||||
|
||||
/* kick FW self load */
|
||||
|
@ -1009,6 +1009,11 @@ static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
|
||||
__iwl_trans_pcie_set_bits_mask(trans, reg, mask, mask);
|
||||
}
|
||||
|
||||
static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans)
|
||||
{
|
||||
return (trans->dbg_dest_tlv || trans->ini_valid);
|
||||
}
|
||||
|
||||
void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state);
|
||||
void iwl_trans_pcie_dump_regs(struct iwl_trans *trans);
|
||||
|
||||
|
@ -924,6 +924,20 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans)
|
||||
const struct iwl_fw_dbg_dest_tlv_v1 *dest = trans->dbg_dest_tlv;
|
||||
int i;
|
||||
|
||||
if (trans->ini_valid) {
|
||||
if (!trans->num_blocks)
|
||||
return;
|
||||
|
||||
iwl_write_prph(trans, MON_BUFF_BASE_ADDR_VER2,
|
||||
trans->fw_mon[0].physical >>
|
||||
MON_BUFF_SHIFT_VER2);
|
||||
iwl_write_prph(trans, MON_BUFF_END_ADDR_VER2,
|
||||
(trans->fw_mon[0].physical +
|
||||
trans->fw_mon[0].size - 256) >>
|
||||
MON_BUFF_SHIFT_VER2);
|
||||
return;
|
||||
}
|
||||
|
||||
IWL_INFO(trans, "Applying debug destination %s\n",
|
||||
get_fw_dbg_mode_string(dest->monitor_mode));
|
||||
|
||||
@ -1026,7 +1040,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
|
||||
(trans->fw_mon[0].physical +
|
||||
trans->fw_mon[0].size) >> 4);
|
||||
}
|
||||
} else if (trans->dbg_dest_tlv) {
|
||||
} else if (iwl_pcie_dbg_on(trans)) {
|
||||
iwl_pcie_apply_destination(trans);
|
||||
}
|
||||
|
||||
@ -1047,7 +1061,7 @@ static int iwl_pcie_load_given_ucode_8000(struct iwl_trans *trans,
|
||||
IWL_DEBUG_FW(trans, "working with %s CPU\n",
|
||||
image->is_dual_cpus ? "Dual" : "Single");
|
||||
|
||||
if (trans->dbg_dest_tlv)
|
||||
if (iwl_pcie_dbg_on(trans))
|
||||
iwl_pcie_apply_destination(trans);
|
||||
|
||||
IWL_DEBUG_POWER(trans, "Original WFPM value = 0x%08X\n",
|
||||
@ -3015,6 +3029,34 @@ iwl_trans_pci_dump_marbh_monitor(struct iwl_trans *trans,
|
||||
return monitor_len;
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_trans_pcie_dump_pointers(struct iwl_trans *trans,
|
||||
struct iwl_fw_error_dump_fw_mon *fw_mon_data)
|
||||
{
|
||||
u32 base, write_ptr, wrap_cnt;
|
||||
|
||||
/* If there was a dest TLV - use the values from there */
|
||||
if (trans->ini_valid) {
|
||||
base = MON_BUFF_BASE_ADDR_VER2;
|
||||
write_ptr = MON_BUFF_WRPTR_VER2;
|
||||
wrap_cnt = MON_BUFF_CYCLE_CNT_VER2;
|
||||
} else if (trans->dbg_dest_tlv) {
|
||||
write_ptr = le32_to_cpu(trans->dbg_dest_tlv->write_ptr_reg);
|
||||
wrap_cnt = le32_to_cpu(trans->dbg_dest_tlv->wrap_count);
|
||||
base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
|
||||
} else {
|
||||
base = MON_BUFF_BASE_ADDR;
|
||||
write_ptr = MON_BUFF_WRPTR;
|
||||
wrap_cnt = MON_BUFF_CYCLE_CNT;
|
||||
}
|
||||
fw_mon_data->fw_mon_wr_ptr =
|
||||
cpu_to_le32(iwl_read_prph(trans, write_ptr));
|
||||
fw_mon_data->fw_mon_cycle_cnt =
|
||||
cpu_to_le32(iwl_read_prph(trans, wrap_cnt));
|
||||
fw_mon_data->fw_mon_base_ptr =
|
||||
cpu_to_le32(iwl_read_prph(trans, base));
|
||||
}
|
||||
|
||||
static u32
|
||||
iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
|
||||
struct iwl_fw_error_dump_data **data,
|
||||
@ -3024,30 +3066,14 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
|
||||
|
||||
if ((trans->num_blocks &&
|
||||
trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) ||
|
||||
trans->dbg_dest_tlv) {
|
||||
(trans->dbg_dest_tlv && !trans->ini_valid) ||
|
||||
(trans->ini_valid && trans->num_blocks)) {
|
||||
struct iwl_fw_error_dump_fw_mon *fw_mon_data;
|
||||
u32 base, write_ptr, wrap_cnt;
|
||||
|
||||
/* If there was a dest TLV - use the values from there */
|
||||
if (trans->dbg_dest_tlv) {
|
||||
write_ptr =
|
||||
le32_to_cpu(trans->dbg_dest_tlv->write_ptr_reg);
|
||||
wrap_cnt = le32_to_cpu(trans->dbg_dest_tlv->wrap_count);
|
||||
base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
|
||||
} else {
|
||||
base = MON_BUFF_BASE_ADDR;
|
||||
write_ptr = MON_BUFF_WRPTR;
|
||||
wrap_cnt = MON_BUFF_CYCLE_CNT;
|
||||
}
|
||||
|
||||
(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR);
|
||||
fw_mon_data = (void *)(*data)->data;
|
||||
fw_mon_data->fw_mon_wr_ptr =
|
||||
cpu_to_le32(iwl_read_prph(trans, write_ptr));
|
||||
fw_mon_data->fw_mon_cycle_cnt =
|
||||
cpu_to_le32(iwl_read_prph(trans, wrap_cnt));
|
||||
fw_mon_data->fw_mon_base_ptr =
|
||||
cpu_to_le32(iwl_read_prph(trans, base));
|
||||
|
||||
iwl_trans_pcie_dump_pointers(trans, fw_mon_data);
|
||||
|
||||
len += sizeof(**data) + sizeof(*fw_mon_data);
|
||||
if (trans->num_blocks) {
|
||||
@ -3057,6 +3083,7 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
|
||||
|
||||
monitor_len = trans->fw_mon[0].size;
|
||||
} else if (trans->dbg_dest_tlv->monitor_mode == SMEM_MODE) {
|
||||
u32 base = le32_to_cpu(fw_mon_data->fw_mon_base_ptr);
|
||||
/*
|
||||
* Update pointers to reflect actual values after
|
||||
* shifting
|
||||
|
@ -238,7 +238,7 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans *trans,
|
||||
{
|
||||
#ifdef CONFIG_INET
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload;
|
||||
struct iwl_tx_cmd_gen2 *tx_cmd = (void *)dev_cmd->payload;
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room;
|
||||
unsigned int mss = skb_shinfo(skb)->gso_size;
|
||||
@ -583,18 +583,6 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
|
||||
spin_lock(&txq->lock);
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
struct iwl_tx_cmd_gen3 *tx_cmd_gen3 =
|
||||
(void *)dev_cmd->payload;
|
||||
|
||||
cmd_len = le16_to_cpu(tx_cmd_gen3->len);
|
||||
} else {
|
||||
struct iwl_tx_cmd_gen2 *tx_cmd_gen2 =
|
||||
(void *)dev_cmd->payload;
|
||||
|
||||
cmd_len = le16_to_cpu(tx_cmd_gen2->len);
|
||||
}
|
||||
|
||||
if (iwl_queue_space(trans, txq) < txq->high_mark) {
|
||||
iwl_stop_queue(trans, txq);
|
||||
|
||||
@ -632,6 +620,18 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
struct iwl_tx_cmd_gen3 *tx_cmd_gen3 =
|
||||
(void *)dev_cmd->payload;
|
||||
|
||||
cmd_len = le16_to_cpu(tx_cmd_gen3->len);
|
||||
} else {
|
||||
struct iwl_tx_cmd_gen2 *tx_cmd_gen2 =
|
||||
(void *)dev_cmd->payload;
|
||||
|
||||
cmd_len = le16_to_cpu(tx_cmd_gen2->len);
|
||||
}
|
||||
|
||||
/* Set up entry for this TFD in Tx byte-count array */
|
||||
iwl_pcie_gen2_update_byte_tbl(trans_pcie, txq, cmd_len,
|
||||
iwl_pcie_gen2_get_num_tbs(trans, tfd));
|
||||
|
@ -1160,10 +1160,11 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
|
||||
*/
|
||||
iwl_trans_tx(trans, skb, dev_cmd_ptr, txq_id);
|
||||
}
|
||||
spin_lock_bh(&txq->lock);
|
||||
|
||||
if (iwl_queue_space(trans, txq) > txq->low_mark)
|
||||
iwl_wake_queue(trans, txq);
|
||||
|
||||
spin_lock_bh(&txq->lock);
|
||||
}
|
||||
|
||||
if (txq->read_ptr == txq->write_ptr) {
|
||||
@ -1245,11 +1246,11 @@ void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
|
||||
|
||||
if (idx >= trans->cfg->base_params->max_tfd_queue_size ||
|
||||
(!iwl_queue_used(txq, idx))) {
|
||||
IWL_ERR(trans,
|
||||
"%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n",
|
||||
__func__, txq_id, idx,
|
||||
trans->cfg->base_params->max_tfd_queue_size,
|
||||
txq->write_ptr, txq->read_ptr);
|
||||
WARN_ONCE(test_bit(txq_id, trans_pcie->queue_used),
|
||||
"%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n",
|
||||
__func__, txq_id, idx,
|
||||
trans->cfg->base_params->max_tfd_queue_size,
|
||||
txq->write_ptr, txq->read_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1275,27 +1275,27 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
static void
|
||||
mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
|
||||
mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 rateinfo, u8 htinfo,
|
||||
struct rate_info *rate)
|
||||
{
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
|
||||
if (adapter->is_hw_11ac_capable) {
|
||||
/* bit[1-0]: 00=LG 01=HT 10=VHT */
|
||||
if (tx_htinfo & BIT(0)) {
|
||||
if (htinfo & BIT(0)) {
|
||||
/* HT */
|
||||
rate->mcs = priv->tx_rate;
|
||||
rate->mcs = rateinfo;
|
||||
rate->flags |= RATE_INFO_FLAGS_MCS;
|
||||
}
|
||||
if (tx_htinfo & BIT(1)) {
|
||||
if (htinfo & BIT(1)) {
|
||||
/* VHT */
|
||||
rate->mcs = priv->tx_rate & 0x0F;
|
||||
rate->mcs = rateinfo & 0x0F;
|
||||
rate->flags |= RATE_INFO_FLAGS_VHT_MCS;
|
||||
}
|
||||
|
||||
if (tx_htinfo & (BIT(1) | BIT(0))) {
|
||||
if (htinfo & (BIT(1) | BIT(0))) {
|
||||
/* HT or VHT */
|
||||
switch (tx_htinfo & (BIT(3) | BIT(2))) {
|
||||
switch (htinfo & (BIT(3) | BIT(2))) {
|
||||
case 0:
|
||||
rate->bw = RATE_INFO_BW_20;
|
||||
break;
|
||||
@ -1310,29 +1310,51 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
|
||||
break;
|
||||
}
|
||||
|
||||
if (tx_htinfo & BIT(4))
|
||||
if (htinfo & BIT(4))
|
||||
rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
|
||||
if ((priv->tx_rate >> 4) == 1)
|
||||
if ((rateinfo >> 4) == 1)
|
||||
rate->nss = 2;
|
||||
else
|
||||
rate->nss = 1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Bit 0 in tx_htinfo indicates that current Tx rate
|
||||
* is 11n rate. Valid MCS index values for us are 0 to 15.
|
||||
* Bit 0 in htinfo indicates that current rate is 11n. Valid
|
||||
* MCS index values for us are 0 to 15.
|
||||
*/
|
||||
if ((tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) {
|
||||
rate->mcs = priv->tx_rate;
|
||||
if ((htinfo & BIT(0)) && (rateinfo < 16)) {
|
||||
rate->mcs = rateinfo;
|
||||
rate->flags |= RATE_INFO_FLAGS_MCS;
|
||||
rate->bw = RATE_INFO_BW_20;
|
||||
if (tx_htinfo & BIT(1))
|
||||
if (htinfo & BIT(1))
|
||||
rate->bw = RATE_INFO_BW_40;
|
||||
if (tx_htinfo & BIT(2))
|
||||
if (htinfo & BIT(2))
|
||||
rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decode legacy rates for non-HT. */
|
||||
if (!(htinfo & (BIT(0) | BIT(1)))) {
|
||||
/* Bitrates in multiples of 100kb/s. */
|
||||
static const int legacy_rates[] = {
|
||||
[0] = 10,
|
||||
[1] = 20,
|
||||
[2] = 55,
|
||||
[3] = 110,
|
||||
[4] = 60, /* MWIFIEX_RATE_INDEX_OFDM0 */
|
||||
[5] = 60,
|
||||
[6] = 90,
|
||||
[7] = 120,
|
||||
[8] = 180,
|
||||
[9] = 240,
|
||||
[10] = 360,
|
||||
[11] = 480,
|
||||
[12] = 540,
|
||||
};
|
||||
if (rateinfo < ARRAY_SIZE(legacy_rates))
|
||||
rate->legacy = legacy_rates[rateinfo];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1375,7 +1397,8 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
|
||||
sinfo->tx_packets = node->stats.tx_packets;
|
||||
sinfo->tx_failed = node->stats.tx_failed;
|
||||
|
||||
mwifiex_parse_htinfo(priv, node->stats.last_tx_htinfo,
|
||||
mwifiex_parse_htinfo(priv, priv->tx_rate,
|
||||
node->stats.last_tx_htinfo,
|
||||
&sinfo->txrate);
|
||||
sinfo->txrate.legacy = node->stats.last_tx_rate * 5;
|
||||
|
||||
@ -1401,7 +1424,8 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
|
||||
HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
|
||||
&priv->dtim_period, true);
|
||||
|
||||
mwifiex_parse_htinfo(priv, priv->tx_htinfo, &sinfo->txrate);
|
||||
mwifiex_parse_htinfo(priv, priv->tx_rate, priv->tx_htinfo,
|
||||
&sinfo->txrate);
|
||||
|
||||
sinfo->signal_avg = priv->bcn_rssi_avg;
|
||||
sinfo->rx_bytes = priv->stats.rx_bytes;
|
||||
@ -1412,6 +1436,10 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
|
||||
/* bit rate is in 500 kb/s units. Convert it to 100kb/s units */
|
||||
sinfo->txrate.legacy = rate * 5;
|
||||
|
||||
sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
|
||||
mwifiex_parse_htinfo(priv, priv->rxpd_rate, priv->rxpd_htinfo,
|
||||
&sinfo->rxrate);
|
||||
|
||||
if (priv->bss_mode == NL80211_IFTYPE_STATION) {
|
||||
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
|
||||
sinfo->bss_param.flags = 0;
|
||||
|
@ -273,15 +273,13 @@ mwifiex_histogram_read(struct file *file, char __user *ubuf,
|
||||
"total samples = %d\n",
|
||||
atomic_read(&phist_data->num_samples));
|
||||
|
||||
p += sprintf(p, "rx rates (in Mbps): 0=1M 1=2M");
|
||||
p += sprintf(p, "2=5.5M 3=11M 4=6M 5=9M 6=12M\n");
|
||||
p += sprintf(p, "7=18M 8=24M 9=36M 10=48M 11=54M");
|
||||
p += sprintf(p, "12-27=MCS0-15(BW20) 28-43=MCS0-15(BW40)\n");
|
||||
p += sprintf(p,
|
||||
"rx rates (in Mbps): 0=1M 1=2M 2=5.5M 3=11M 4=6M 5=9M 6=12M\n"
|
||||
"7=18M 8=24M 9=36M 10=48M 11=54M 12-27=MCS0-15(BW20) 28-43=MCS0-15(BW40)\n");
|
||||
|
||||
if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info)) {
|
||||
p += sprintf(p, "44-53=MCS0-9(VHT:BW20)");
|
||||
p += sprintf(p, "54-63=MCS0-9(VHT:BW40)");
|
||||
p += sprintf(p, "64-73=MCS0-9(VHT:BW80)\n\n");
|
||||
p += sprintf(p,
|
||||
"44-53=MCS0-9(VHT:BW20) 54-63=MCS0-9(VHT:BW40) 64-73=MCS0-9(VHT:BW80)\n\n");
|
||||
} else {
|
||||
p += sprintf(p, "\n");
|
||||
}
|
||||
@ -310,7 +308,7 @@ mwifiex_histogram_read(struct file *file, char __user *ubuf,
|
||||
for (i = 0; i < MWIFIEX_MAX_NOISE_FLR; i++) {
|
||||
value = atomic_read(&phist_data->noise_flr[i]);
|
||||
if (value)
|
||||
p += sprintf(p, "noise_flr[-%02ddBm] = %d\n",
|
||||
p += sprintf(p, "noise_flr[%02ddBm] = %d\n",
|
||||
(int)(i-128), value);
|
||||
}
|
||||
for (i = 0; i < MWIFIEX_MAX_SIG_STRENGTH; i++) {
|
||||
|
@ -1882,15 +1882,17 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
|
||||
ETH_ALEN))
|
||||
mwifiex_update_curr_bss_params(priv,
|
||||
bss);
|
||||
cfg80211_put_bss(priv->wdev.wiphy, bss);
|
||||
}
|
||||
|
||||
if ((chan->flags & IEEE80211_CHAN_RADAR) ||
|
||||
(chan->flags & IEEE80211_CHAN_NO_IR)) {
|
||||
mwifiex_dbg(adapter, INFO,
|
||||
"radar or passive channel %d\n",
|
||||
channel);
|
||||
mwifiex_save_hidden_ssid_channels(priv, bss);
|
||||
if ((chan->flags & IEEE80211_CHAN_RADAR) ||
|
||||
(chan->flags & IEEE80211_CHAN_NO_IR)) {
|
||||
mwifiex_dbg(adapter, INFO,
|
||||
"radar or passive channel %d\n",
|
||||
channel);
|
||||
mwifiex_save_hidden_ssid_channels(priv,
|
||||
bss);
|
||||
}
|
||||
|
||||
cfg80211_put_bss(priv->wdev.wiphy, bss);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -152,14 +152,17 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
|
||||
mwifiex_process_tdls_action_frame(priv, offset, rx_pkt_len);
|
||||
}
|
||||
|
||||
priv->rxpd_rate = local_rx_pd->rx_rate;
|
||||
|
||||
priv->rxpd_htinfo = local_rx_pd->ht_info;
|
||||
/* Only stash RX bitrate for unicast packets. */
|
||||
if (likely(!is_multicast_ether_addr(rx_pkt_hdr->eth803_hdr.h_dest))) {
|
||||
priv->rxpd_rate = local_rx_pd->rx_rate;
|
||||
priv->rxpd_htinfo = local_rx_pd->ht_info;
|
||||
}
|
||||
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
|
||||
GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
|
||||
adj_rx_rate = mwifiex_adjust_data_rate(priv, priv->rxpd_rate,
|
||||
priv->rxpd_htinfo);
|
||||
adj_rx_rate = mwifiex_adjust_data_rate(priv,
|
||||
local_rx_pd->rx_rate,
|
||||
local_rx_pd->ht_info);
|
||||
mwifiex_hist_data_add(priv, adj_rx_rate, local_rx_pd->snr,
|
||||
local_rx_pd->nf);
|
||||
}
|
||||
|
@ -14,7 +14,8 @@ CFLAGS_mt76x02_trace.o := -I$(src)
|
||||
|
||||
mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \
|
||||
mt76x02_eeprom.o mt76x02_phy.o mt76x02_mmio.o \
|
||||
mt76x02_txrx.o mt76x02_trace.o
|
||||
mt76x02_txrx.o mt76x02_trace.o mt76x02_debugfs.o \
|
||||
mt76x02_dfs.o
|
||||
|
||||
mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
|
||||
|
||||
|
@ -157,17 +157,20 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
|
||||
if (entry.schedule)
|
||||
q->swq_queued--;
|
||||
|
||||
if (entry.skb)
|
||||
q->tail = (q->tail + 1) % q->ndesc;
|
||||
q->queued--;
|
||||
|
||||
if (entry.skb) {
|
||||
spin_unlock_bh(&q->lock);
|
||||
dev->drv->tx_complete_skb(dev, q, &entry, flush);
|
||||
spin_lock_bh(&q->lock);
|
||||
}
|
||||
|
||||
if (entry.txwi) {
|
||||
mt76_put_txwi(dev, entry.txwi);
|
||||
wake = true;
|
||||
wake = !flush;
|
||||
}
|
||||
|
||||
q->tail = (q->tail + 1) % q->ndesc;
|
||||
q->queued--;
|
||||
|
||||
if (!flush && q->tail == last)
|
||||
last = ioread32(&q->regs->dma_idx);
|
||||
}
|
||||
@ -258,6 +261,7 @@ int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
skb->prev = skb->next = NULL;
|
||||
dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi),
|
||||
DMA_TO_DEVICE);
|
||||
ret = dev->drv->tx_prepare_skb(dev, &t->txwi, skb, q, wcid, sta,
|
||||
|
@ -285,6 +285,7 @@ mt76_alloc_device(unsigned int size, const struct ieee80211_ops *ops)
|
||||
spin_lock_init(&dev->cc_lock);
|
||||
mutex_init(&dev->mutex);
|
||||
init_waitqueue_head(&dev->tx_wait);
|
||||
skb_queue_head_init(&dev->status_list);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@ -326,6 +327,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
|
||||
ieee80211_hw_set(hw, TX_FRAG_LIST);
|
||||
ieee80211_hw_set(hw, MFP_CAPABLE);
|
||||
ieee80211_hw_set(hw, AP_LINK_PS);
|
||||
ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
|
||||
|
||||
wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||
|
||||
@ -359,6 +361,7 @@ void mt76_unregister_device(struct mt76_dev *dev)
|
||||
{
|
||||
struct ieee80211_hw *hw = dev->hw;
|
||||
|
||||
mt76_tx_status_check(dev, NULL, true);
|
||||
ieee80211_unregister_hw(hw);
|
||||
mt76_tx_free(dev);
|
||||
}
|
||||
@ -629,3 +632,80 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
|
||||
mt76_rx_complete(dev, &frames, napi);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_rx_poll_complete);
|
||||
|
||||
static int
|
||||
mt76_sta_add(struct mt76_dev *dev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
|
||||
ret = dev->drv->sta_add(dev, vif, sta);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
|
||||
struct mt76_txq *mtxq;
|
||||
|
||||
if (!sta->txq[i])
|
||||
continue;
|
||||
|
||||
mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv;
|
||||
mtxq->wcid = wcid;
|
||||
|
||||
mt76_txq_init(dev, sta->txq[i]);
|
||||
}
|
||||
|
||||
rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
|
||||
|
||||
out:
|
||||
mutex_unlock(&dev->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
|
||||
int idx = wcid->idx;
|
||||
int i;
|
||||
|
||||
rcu_assign_pointer(dev->wcid[idx], NULL);
|
||||
synchronize_rcu();
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
|
||||
if (dev->drv->sta_remove)
|
||||
dev->drv->sta_remove(dev, vif, sta);
|
||||
|
||||
mt76_tx_status_check(dev, wcid, true);
|
||||
for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
|
||||
mt76_txq_remove(dev, sta->txq[i]);
|
||||
mt76_wcid_free(dev->wcid_mask, idx);
|
||||
|
||||
mutex_unlock(&dev->mutex);
|
||||
}
|
||||
|
||||
int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
enum ieee80211_sta_state old_state,
|
||||
enum ieee80211_sta_state new_state)
|
||||
{
|
||||
struct mt76_dev *dev = hw->priv;
|
||||
|
||||
if (old_state == IEEE80211_STA_NOTEXIST &&
|
||||
new_state == IEEE80211_STA_NONE)
|
||||
return mt76_sta_add(dev, vif, sta);
|
||||
|
||||
if (old_state == IEEE80211_STA_NONE &&
|
||||
new_state == IEEE80211_STA_NOTEXIST)
|
||||
mt76_sta_remove(dev, vif, sta);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_sta_state);
|
||||
|
@ -135,9 +135,8 @@ struct mt76_queue {
|
||||
};
|
||||
|
||||
struct mt76_mcu_ops {
|
||||
struct sk_buff *(*mcu_msg_alloc)(const void *data, int len);
|
||||
int (*mcu_send_msg)(struct mt76_dev *dev, struct sk_buff *skb,
|
||||
int cmd, bool wait_resp);
|
||||
int (*mcu_send_msg)(struct mt76_dev *dev, int cmd, const void *data,
|
||||
int len, bool wait_resp);
|
||||
int (*mcu_wr_rp)(struct mt76_dev *dev, u32 base,
|
||||
const struct mt76_reg_pair *rp, int len);
|
||||
int (*mcu_rd_rp)(struct mt76_dev *dev, u32 base,
|
||||
@ -195,6 +194,8 @@ struct mt76_wcid {
|
||||
u8 tx_rate_nss;
|
||||
s8 max_txpwr_adj;
|
||||
bool sw_iv;
|
||||
|
||||
u8 packet_id;
|
||||
};
|
||||
|
||||
struct mt76_txq {
|
||||
@ -233,6 +234,22 @@ struct mt76_rx_tid {
|
||||
struct sk_buff *reorder_buf[];
|
||||
};
|
||||
|
||||
#define MT_TX_CB_DMA_DONE BIT(0)
|
||||
#define MT_TX_CB_TXS_DONE BIT(1)
|
||||
#define MT_TX_CB_TXS_FAILED BIT(2)
|
||||
|
||||
#define MT_PACKET_ID_MASK GENMASK(7, 0)
|
||||
#define MT_PACKET_ID_NO_ACK MT_PACKET_ID_MASK
|
||||
|
||||
#define MT_TX_STATUS_SKB_TIMEOUT HZ
|
||||
|
||||
struct mt76_tx_cb {
|
||||
unsigned long jiffies;
|
||||
u8 wcid;
|
||||
u8 pktid;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
enum {
|
||||
MT76_STATE_INITIALIZED,
|
||||
MT76_STATE_RUNNING,
|
||||
@ -271,6 +288,12 @@ struct mt76_driver_ops {
|
||||
|
||||
void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta,
|
||||
bool ps);
|
||||
|
||||
int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
|
||||
void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
};
|
||||
|
||||
struct mt76_channel_state {
|
||||
@ -400,6 +423,7 @@ struct mt76_dev {
|
||||
const struct mt76_queue_ops *queue_ops;
|
||||
|
||||
wait_queue_head_t tx_wait;
|
||||
struct sk_buff_head status_list;
|
||||
|
||||
unsigned long wcid_mask[MT76_N_WCIDS / BITS_PER_LONG];
|
||||
|
||||
@ -484,7 +508,6 @@ struct mt76_rx_status {
|
||||
#define mt76_wr_rp(dev, ...) (dev)->mt76.bus->wr_rp(&((dev)->mt76), __VA_ARGS__)
|
||||
#define mt76_rd_rp(dev, ...) (dev)->mt76.bus->rd_rp(&((dev)->mt76), __VA_ARGS__)
|
||||
|
||||
#define mt76_mcu_msg_alloc(dev, ...) (dev)->mt76.mcu_ops->mcu_msg_alloc(__VA_ARGS__)
|
||||
#define mt76_mcu_send_msg(dev, ...) (dev)->mt76.mcu_ops->mcu_send_msg(&((dev)->mt76), __VA_ARGS__)
|
||||
|
||||
#define mt76_set(dev, offset, val) mt76_rmw(dev, offset, 0, val)
|
||||
@ -594,6 +617,13 @@ wcid_to_sta(struct mt76_wcid *wcid)
|
||||
return container_of(ptr, struct ieee80211_sta, drv_priv);
|
||||
}
|
||||
|
||||
static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb)
|
||||
{
|
||||
BUILD_BUG_ON(sizeof(struct mt76_tx_cb) >
|
||||
sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data));
|
||||
return ((void *) IEEE80211_SKB_CB(skb)->status.status_driver_data);
|
||||
}
|
||||
|
||||
int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
|
||||
struct sk_buff *skb, struct mt76_wcid *wcid,
|
||||
struct ieee80211_sta *sta);
|
||||
@ -625,6 +655,26 @@ void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid);
|
||||
void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
|
||||
struct ieee80211_key_conf *key);
|
||||
|
||||
void mt76_tx_status_lock(struct mt76_dev *dev, struct sk_buff_head *list)
|
||||
__acquires(&dev->status_list.lock);
|
||||
void mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list)
|
||||
__releases(&dev->status_list.lock);
|
||||
|
||||
int mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
|
||||
struct sk_buff *skb);
|
||||
struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev,
|
||||
struct mt76_wcid *wcid, int pktid,
|
||||
struct sk_buff_head *list);
|
||||
void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb,
|
||||
struct sk_buff_head *list);
|
||||
void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb);
|
||||
void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid,
|
||||
bool flush);
|
||||
int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
enum ieee80211_sta_state old_state,
|
||||
enum ieee80211_sta_state new_state);
|
||||
|
||||
struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb);
|
||||
|
||||
/* internal */
|
||||
@ -668,8 +718,6 @@ int mt76u_vendor_request(struct mt76_dev *dev, u8 req,
|
||||
void *buf, size_t len);
|
||||
void mt76u_single_wr(struct mt76_dev *dev, const u8 req,
|
||||
const u16 offset, const u32 val);
|
||||
u32 mt76u_rr(struct mt76_dev *dev, u32 addr);
|
||||
void mt76u_wr(struct mt76_dev *dev, u32 addr, u32 val);
|
||||
int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf);
|
||||
void mt76u_deinit(struct mt76_dev *dev);
|
||||
int mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf,
|
||||
|
@ -2,11 +2,9 @@ obj-$(CONFIG_MT76x0U) += mt76x0u.o
|
||||
obj-$(CONFIG_MT76x0E) += mt76x0e.o
|
||||
obj-$(CONFIG_MT76x0_COMMON) += mt76x0-common.o
|
||||
|
||||
mt76x0-common-y := \
|
||||
init.o main.o trace.o eeprom.o phy.o \
|
||||
mac.o debugfs.o
|
||||
mt76x0-common-y := init.o main.o eeprom.o phy.o
|
||||
|
||||
mt76x0u-y := usb.o usb_mcu.o
|
||||
mt76x0e-y := pci.o pci_mcu.o
|
||||
|
||||
# ccflags-y := -DDEBUG
|
||||
CFLAGS_trace.o := -I$(src)
|
||||
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
|
||||
* Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
|
||||
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
#include "mt76x0.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
static int
|
||||
mt76x0_ampdu_stat_read(struct seq_file *file, void *data)
|
||||
{
|
||||
struct mt76x02_dev *dev = file->private;
|
||||
int i, j;
|
||||
|
||||
#define stat_printf(grp, off, name) \
|
||||
seq_printf(file, #name ":\t%llu\n", dev->stats.grp[off])
|
||||
|
||||
stat_printf(rx_stat, 0, rx_crc_err);
|
||||
stat_printf(rx_stat, 1, rx_phy_err);
|
||||
stat_printf(rx_stat, 2, rx_false_cca);
|
||||
stat_printf(rx_stat, 3, rx_plcp_err);
|
||||
stat_printf(rx_stat, 4, rx_fifo_overflow);
|
||||
stat_printf(rx_stat, 5, rx_duplicate);
|
||||
|
||||
stat_printf(tx_stat, 0, tx_fail_cnt);
|
||||
stat_printf(tx_stat, 1, tx_bcn_cnt);
|
||||
stat_printf(tx_stat, 2, tx_success);
|
||||
stat_printf(tx_stat, 3, tx_retransmit);
|
||||
stat_printf(tx_stat, 4, tx_zero_len);
|
||||
stat_printf(tx_stat, 5, tx_underflow);
|
||||
|
||||
stat_printf(aggr_stat, 0, non_aggr_tx);
|
||||
stat_printf(aggr_stat, 1, aggr_tx);
|
||||
|
||||
stat_printf(zero_len_del, 0, tx_zero_len_del);
|
||||
stat_printf(zero_len_del, 1, rx_zero_len_del);
|
||||
#undef stat_printf
|
||||
|
||||
seq_puts(file, "Aggregations stats:\n");
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
seq_printf(file, "%08llx ",
|
||||
dev->stats.aggr_n[i * 8 + j]);
|
||||
seq_putc(file, '\n');
|
||||
}
|
||||
|
||||
seq_printf(file, "recent average AMPDU len: %d\n",
|
||||
atomic_read(&dev->avg_ampdu_len));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt76x0_ampdu_stat_open(struct inode *inode, struct file *f)
|
||||
{
|
||||
return single_open(f, mt76x0_ampdu_stat_read, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_ampdu_stat = {
|
||||
.open = mt76x0_ampdu_stat_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
void mt76x0_init_debugfs(struct mt76x02_dev *dev)
|
||||
{
|
||||
struct dentry *dir;
|
||||
|
||||
dir = mt76_register_debugfs(&dev->mt76);
|
||||
if (!dir)
|
||||
return;
|
||||
|
||||
debugfs_create_file("ampdu_stat", S_IRUSR, dir, dev, &fops_ampdu_stat);
|
||||
}
|
@ -135,9 +135,6 @@ static s8 mt76x0_get_delta(struct mt76x02_dev *dev)
|
||||
struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
|
||||
u8 val;
|
||||
|
||||
if (mt76x0_tssi_enabled(dev))
|
||||
return 0;
|
||||
|
||||
if (chandef->width == NL80211_CHAN_WIDTH_80) {
|
||||
val = mt76x02_eeprom_get(dev, MT_EE_5G_TARGET_POWER) >> 8;
|
||||
} else if (chandef->width == NL80211_CHAN_WIDTH_40) {
|
||||
@ -160,8 +157,8 @@ void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev)
|
||||
struct ieee80211_channel *chan = dev->mt76.chandef.chan;
|
||||
bool is_2ghz = chan->band == NL80211_BAND_2GHZ;
|
||||
struct mt76_rate_power *t = &dev->mt76.rate_power;
|
||||
s8 delta = mt76x0_get_delta(dev);
|
||||
u16 val, addr;
|
||||
s8 delta;
|
||||
|
||||
memset(t, 0, sizeof(*t));
|
||||
|
||||
@ -211,6 +208,7 @@ void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev)
|
||||
t->vht[7] = s6_to_s8(val);
|
||||
t->vht[8] = s6_to_s8(val >> 8);
|
||||
|
||||
delta = mt76x0_tssi_enabled(dev) ? 0 : mt76x0_get_delta(dev);
|
||||
mt76x02_add_rate_power_offset(t, delta);
|
||||
}
|
||||
|
||||
@ -233,6 +231,20 @@ void mt76x0_get_power_info(struct mt76x02_dev *dev, u8 *info)
|
||||
u16 data;
|
||||
int i;
|
||||
|
||||
if (mt76x0_tssi_enabled(dev)) {
|
||||
s8 target_power;
|
||||
|
||||
if (chan->band == NL80211_BAND_5GHZ)
|
||||
data = mt76x02_eeprom_get(dev, MT_EE_5G_TARGET_POWER);
|
||||
else
|
||||
data = mt76x02_eeprom_get(dev, MT_EE_2G_TARGET_POWER);
|
||||
target_power = (data & 0xff) - dev->mt76.rate_power.ofdm[7];
|
||||
info[0] = target_power + mt76x0_get_delta(dev);
|
||||
info[1] = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(chan_map); i++) {
|
||||
if (chan_map[i].chan <= chan->hw_value) {
|
||||
offset = chan_map[i].offset;
|
||||
@ -340,8 +352,6 @@ int mt76x0_eeprom_init(struct mt76x02_dev *dev)
|
||||
mt76x0_set_freq_offset(dev);
|
||||
mt76x0_set_temp_offset(dev);
|
||||
|
||||
dev->mt76.chainmask = 0x0101;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include "mt76x0.h"
|
||||
#include "eeprom.h"
|
||||
#include "trace.h"
|
||||
#include "mcu.h"
|
||||
#include "initvals.h"
|
||||
|
||||
@ -113,7 +112,7 @@ static int mt76x0_init_bbp(struct mt76x02_dev *dev)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
ret = mt76x0_wait_bbp_ready(dev);
|
||||
ret = mt76x0_phy_wait_bbp_ready(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -134,80 +133,28 @@ static int mt76x0_init_bbp(struct mt76x02_dev *dev)
|
||||
|
||||
static void mt76x0_init_mac_registers(struct mt76x02_dev *dev)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
RANDOM_WRITE(dev, common_mac_reg_table);
|
||||
|
||||
mt76x02_set_beacon_offsets(dev);
|
||||
|
||||
/* Enable PBF and MAC clock SYS_CTRL[11:10] = 0x3 */
|
||||
RANDOM_WRITE(dev, mt76x0_mac_reg_table);
|
||||
|
||||
/* Release BBP and MAC reset MAC_SYS_CTRL[1:0] = 0x0 */
|
||||
reg = mt76_rr(dev, MT_MAC_SYS_CTRL);
|
||||
reg &= ~0x3;
|
||||
mt76_wr(dev, MT_MAC_SYS_CTRL, reg);
|
||||
mt76_clear(dev, MT_MAC_SYS_CTRL, 0x3);
|
||||
|
||||
/* Set 0x141C[15:12]=0xF */
|
||||
reg = mt76_rr(dev, MT_EXT_CCA_CFG);
|
||||
reg |= 0x0000F000;
|
||||
mt76_wr(dev, MT_EXT_CCA_CFG, reg);
|
||||
mt76_set(dev, MT_EXT_CCA_CFG, 0xf000);
|
||||
|
||||
mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN);
|
||||
|
||||
/*
|
||||
TxRing 9 is for Mgmt frame.
|
||||
TxRing 8 is for In-band command frame.
|
||||
WMM_RG0_TXQMA: This register setting is for FCE to define the rule of TxRing 9.
|
||||
WMM_RG1_TXQMA: This register setting is for FCE to define the rule of TxRing 8.
|
||||
*/
|
||||
reg = mt76_rr(dev, MT_WMM_CTRL);
|
||||
reg &= ~0x000003FF;
|
||||
reg |= 0x00000201;
|
||||
mt76_wr(dev, MT_WMM_CTRL, reg);
|
||||
}
|
||||
|
||||
static int mt76x0_init_wcid_mem(struct mt76x02_dev *dev)
|
||||
{
|
||||
u32 *vals;
|
||||
int i;
|
||||
|
||||
vals = kmalloc(sizeof(*vals) * MT76_N_WCIDS * 2, GFP_KERNEL);
|
||||
if (!vals)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < MT76_N_WCIDS; i++) {
|
||||
vals[i * 2] = 0xffffffff;
|
||||
vals[i * 2 + 1] = 0x00ffffff;
|
||||
}
|
||||
|
||||
mt76_wr_copy(dev, MT_WCID_ADDR_BASE, vals, MT76_N_WCIDS * 2);
|
||||
kfree(vals);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt76x0_init_key_mem(struct mt76x02_dev *dev)
|
||||
{
|
||||
u32 vals[4] = {};
|
||||
|
||||
mt76_wr_copy(dev, MT_SKEY_MODE_BASE_0, vals, ARRAY_SIZE(vals));
|
||||
}
|
||||
|
||||
static int mt76x0_init_wcid_attr_mem(struct mt76x02_dev *dev)
|
||||
{
|
||||
u32 *vals;
|
||||
int i;
|
||||
|
||||
vals = kmalloc(sizeof(*vals) * MT76_N_WCIDS * 2, GFP_KERNEL);
|
||||
if (!vals)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < MT76_N_WCIDS * 2; i++)
|
||||
vals[i] = 1;
|
||||
|
||||
mt76_wr_copy(dev, MT_WCID_ATTR_BASE, vals, MT76_N_WCIDS * 2);
|
||||
kfree(vals);
|
||||
return 0;
|
||||
* tx_ring 9 is for mgmt frame
|
||||
* tx_ring 8 is for in-band command frame.
|
||||
* WMM_RG0_TXQMA: this register setting is for FCE to
|
||||
* define the rule of tx_ring 9
|
||||
* WMM_RG1_TXQMA: this register setting is for FCE to
|
||||
* define the rule of tx_ring 8
|
||||
*/
|
||||
mt76_rmw(dev, MT_WMM_CTRL, 0x3ff, 0x201);
|
||||
}
|
||||
|
||||
static void mt76x0_reset_counters(struct mt76x02_dev *dev)
|
||||
@ -270,7 +217,7 @@ EXPORT_SYMBOL_GPL(mt76x0_mac_stop);
|
||||
|
||||
int mt76x0_init_hardware(struct mt76x02_dev *dev)
|
||||
{
|
||||
int ret;
|
||||
int ret, i, k;
|
||||
|
||||
if (!mt76x02_wait_for_wpdma(&dev->mt76, 1000))
|
||||
return -EIO;
|
||||
@ -280,7 +227,7 @@ int mt76x0_init_hardware(struct mt76x02_dev *dev)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
mt76x0_reset_csr_bbp(dev);
|
||||
ret = mt76x02_mcu_function_select(dev, Q_SELECT, 1, false);
|
||||
ret = mt76x02_mcu_function_select(dev, Q_SELECT, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -295,20 +242,12 @@ int mt76x0_init_hardware(struct mt76x02_dev *dev)
|
||||
|
||||
dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG);
|
||||
|
||||
ret = mt76x0_init_wcid_mem(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (i = 0; i < 16; i++)
|
||||
for (k = 0; k < 4; k++)
|
||||
mt76x02_mac_shared_key_setup(dev, i, k, NULL);
|
||||
|
||||
mt76x0_init_key_mem(dev);
|
||||
|
||||
ret = mt76x0_init_wcid_attr_mem(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mt76_clear(dev, MT_BEACON_TIME_CFG, (MT_BEACON_TIME_CFG_TIMER_EN |
|
||||
MT_BEACON_TIME_CFG_SYNC_MODE |
|
||||
MT_BEACON_TIME_CFG_TBTT_EN |
|
||||
MT_BEACON_TIME_CFG_BEACON_TX));
|
||||
for (i = 0; i < 256; i++)
|
||||
mt76x02_mac_wcid_setup(dev, i, 0, NULL);
|
||||
|
||||
mt76x0_reset_counters(dev);
|
||||
|
||||
@ -317,6 +256,7 @@ int mt76x0_init_hardware(struct mt76x02_dev *dev)
|
||||
return ret;
|
||||
|
||||
mt76x0_phy_init(dev);
|
||||
mt76x02_init_beacon_config(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -339,7 +279,6 @@ mt76x0_alloc_device(struct device *pdev,
|
||||
|
||||
dev = container_of(mdev, struct mt76x02_dev, mt76);
|
||||
mutex_init(&dev->phy_mutex);
|
||||
atomic_set(&dev->avg_ampdu_len, 1);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@ -347,49 +286,21 @@ EXPORT_SYMBOL_GPL(mt76x0_alloc_device);
|
||||
|
||||
int mt76x0_register_device(struct mt76x02_dev *dev)
|
||||
{
|
||||
struct mt76_dev *mdev = &dev->mt76;
|
||||
struct ieee80211_hw *hw = mdev->hw;
|
||||
struct wiphy *wiphy = hw->wiphy;
|
||||
int ret;
|
||||
|
||||
/* Reserve WCID 0 for mcast - thanks to this APs WCID will go to
|
||||
* entry no. 1 like it does in the vendor driver.
|
||||
*/
|
||||
mdev->wcid_mask[0] |= 1;
|
||||
mt76x02_init_device(dev);
|
||||
mt76x02_config_mac_addr_list(dev);
|
||||
|
||||
/* init fake wcid for monitor interfaces */
|
||||
mdev->global_wcid.idx = 0xff;
|
||||
mdev->global_wcid.hw_key_idx = -1;
|
||||
|
||||
/* init antenna configuration */
|
||||
mdev->antenna_mask = 1;
|
||||
|
||||
hw->queues = 4;
|
||||
hw->max_rates = 1;
|
||||
hw->max_report_rates = 7;
|
||||
hw->max_rate_tries = 1;
|
||||
hw->extra_tx_headroom = 2;
|
||||
if (mt76_is_usb(dev))
|
||||
hw->extra_tx_headroom += sizeof(struct mt76x02_txwi) +
|
||||
MT_DMA_HDR_LEN;
|
||||
|
||||
hw->sta_data_size = sizeof(struct mt76x02_sta);
|
||||
hw->vif_data_size = sizeof(struct mt76x02_vif);
|
||||
|
||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
|
||||
|
||||
INIT_DELAYED_WORK(&dev->mac_work, mt76x0_mac_work);
|
||||
|
||||
ret = mt76_register_device(mdev, true, mt76x02_rates,
|
||||
ret = mt76_register_device(&dev->mt76, true, mt76x02_rates,
|
||||
ARRAY_SIZE(mt76x02_rates));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* overwrite unsupported features */
|
||||
if (mdev->cap.has_5ghz)
|
||||
if (dev->mt76.cap.has_5ghz)
|
||||
mt76x0_vht_cap_mask(&dev->mt76.sband_5g.sband);
|
||||
|
||||
mt76x0_init_debugfs(dev);
|
||||
mt76x02_init_debugfs(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -37,14 +37,14 @@ static const struct mt76_reg_pair common_mac_reg_table[] = {
|
||||
{ MT_PBF_RX_MAX_PCNT, 0x0000fe9f },
|
||||
{ MT_TX_RETRY_CFG, 0x47d01f0f },
|
||||
{ MT_AUTO_RSP_CFG, 0x00000013 },
|
||||
{ MT_CCK_PROT_CFG, 0x05740003 },
|
||||
{ MT_OFDM_PROT_CFG, 0x05740003 },
|
||||
{ MT_CCK_PROT_CFG, 0x07f40003 },
|
||||
{ MT_OFDM_PROT_CFG, 0x07f42004 },
|
||||
{ MT_PBF_CFG, 0x00f40006 },
|
||||
{ MT_WPDMA_GLO_CFG, 0x00000030 },
|
||||
{ MT_GF20_PROT_CFG, 0x01744004 },
|
||||
{ MT_GF40_PROT_CFG, 0x03f44084 },
|
||||
{ MT_MM20_PROT_CFG, 0x01744004 },
|
||||
{ MT_MM40_PROT_CFG, 0x03f54084 },
|
||||
{ MT_GF20_PROT_CFG, 0x01742004 },
|
||||
{ MT_GF40_PROT_CFG, 0x03f42084 },
|
||||
{ MT_MM20_PROT_CFG, 0x01742004 },
|
||||
{ MT_MM40_PROT_CFG, 0x03f42084 },
|
||||
{ MT_TXOP_CTRL_CFG, 0x0000583f },
|
||||
{ MT_TX_RTS_CFG, 0x00092b20 },
|
||||
{ MT_EXP_ACK_TIME, 0x002400ca },
|
||||
@ -85,6 +85,9 @@ static const struct mt76_reg_pair mt76x0_mac_reg_table[] = {
|
||||
{ MT_HT_CTRL_CFG, 0x000001FF },
|
||||
{ MT_TXOP_HLDR_ET, 0x00000000 },
|
||||
{ MT_PN_PAD_MODE, 0x00000003 },
|
||||
{ MT_TX_PROT_CFG6, 0xe3f42004 },
|
||||
{ MT_TX_PROT_CFG7, 0xe3f42084 },
|
||||
{ MT_TX_PROT_CFG8, 0xe3f42104 },
|
||||
};
|
||||
|
||||
static const struct mt76_reg_pair mt76x0_bbp_init_tab[] = {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,197 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
|
||||
* Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
|
||||
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
#include "mt76x0.h"
|
||||
#include "trace.h"
|
||||
|
||||
void mt76x0_mac_set_protection(struct mt76x02_dev *dev, bool legacy_prot,
|
||||
int ht_mode)
|
||||
{
|
||||
int mode = ht_mode & IEEE80211_HT_OP_MODE_PROTECTION;
|
||||
bool non_gf = !!(ht_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
|
||||
u32 prot[6];
|
||||
bool ht_rts[4] = {};
|
||||
int i;
|
||||
|
||||
prot[0] = MT_PROT_NAV_SHORT |
|
||||
MT_PROT_TXOP_ALLOW_ALL |
|
||||
MT_PROT_RTS_THR_EN;
|
||||
prot[1] = prot[0];
|
||||
if (legacy_prot)
|
||||
prot[1] |= MT_PROT_CTRL_CTS2SELF;
|
||||
|
||||
prot[2] = prot[4] = MT_PROT_NAV_SHORT | MT_PROT_TXOP_ALLOW_BW20;
|
||||
prot[3] = prot[5] = MT_PROT_NAV_SHORT | MT_PROT_TXOP_ALLOW_ALL;
|
||||
|
||||
if (legacy_prot) {
|
||||
prot[2] |= MT_PROT_RATE_CCK_11;
|
||||
prot[3] |= MT_PROT_RATE_CCK_11;
|
||||
prot[4] |= MT_PROT_RATE_CCK_11;
|
||||
prot[5] |= MT_PROT_RATE_CCK_11;
|
||||
} else {
|
||||
prot[2] |= MT_PROT_RATE_OFDM_24;
|
||||
prot[3] |= MT_PROT_RATE_DUP_OFDM_24;
|
||||
prot[4] |= MT_PROT_RATE_OFDM_24;
|
||||
prot[5] |= MT_PROT_RATE_DUP_OFDM_24;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
|
||||
break;
|
||||
|
||||
case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
|
||||
ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true;
|
||||
break;
|
||||
|
||||
case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
|
||||
ht_rts[1] = ht_rts[3] = true;
|
||||
break;
|
||||
|
||||
case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
|
||||
ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (non_gf)
|
||||
ht_rts[2] = ht_rts[3] = true;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
if (ht_rts[i])
|
||||
prot[i + 2] |= MT_PROT_CTRL_RTS_CTS;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
mt76_wr(dev, MT_CCK_PROT_CFG + i * 4, prot[i]);
|
||||
}
|
||||
|
||||
void mt76x0_mac_set_short_preamble(struct mt76x02_dev *dev, bool short_preamb)
|
||||
{
|
||||
if (short_preamb)
|
||||
mt76_set(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT);
|
||||
else
|
||||
mt76_clear(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT);
|
||||
}
|
||||
|
||||
void mt76x0_mac_config_tsf(struct mt76x02_dev *dev, bool enable, int interval)
|
||||
{
|
||||
u32 val = mt76_rr(dev, MT_BEACON_TIME_CFG);
|
||||
|
||||
val &= ~(MT_BEACON_TIME_CFG_TIMER_EN |
|
||||
MT_BEACON_TIME_CFG_SYNC_MODE |
|
||||
MT_BEACON_TIME_CFG_TBTT_EN);
|
||||
|
||||
if (!enable) {
|
||||
mt76_wr(dev, MT_BEACON_TIME_CFG, val);
|
||||
return;
|
||||
}
|
||||
|
||||
val &= ~MT_BEACON_TIME_CFG_INTVAL;
|
||||
val |= FIELD_PREP(MT_BEACON_TIME_CFG_INTVAL, interval << 4) |
|
||||
MT_BEACON_TIME_CFG_TIMER_EN |
|
||||
MT_BEACON_TIME_CFG_SYNC_MODE |
|
||||
MT_BEACON_TIME_CFG_TBTT_EN;
|
||||
}
|
||||
|
||||
static void mt76x0_check_mac_err(struct mt76x02_dev *dev)
|
||||
{
|
||||
u32 val = mt76_rr(dev, 0x10f4);
|
||||
|
||||
if (!(val & BIT(29)) || !(val & (BIT(7) | BIT(5))))
|
||||
return;
|
||||
|
||||
dev_err(dev->mt76.dev, "Error: MAC specific condition occurred\n");
|
||||
|
||||
mt76_set(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_RESET_CSR);
|
||||
udelay(10);
|
||||
mt76_clear(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_RESET_CSR);
|
||||
}
|
||||
void mt76x0_mac_work(struct work_struct *work)
|
||||
{
|
||||
struct mt76x02_dev *dev = container_of(work, struct mt76x02_dev,
|
||||
mac_work.work);
|
||||
struct {
|
||||
u32 addr_base;
|
||||
u32 span;
|
||||
u64 *stat_base;
|
||||
} spans[] = {
|
||||
{ MT_RX_STAT_0, 3, dev->stats.rx_stat },
|
||||
{ MT_TX_STA_0, 3, dev->stats.tx_stat },
|
||||
{ MT_TX_AGG_STAT, 1, dev->stats.aggr_stat },
|
||||
{ MT_MPDU_DENSITY_CNT, 1, dev->stats.zero_len_del },
|
||||
{ MT_TX_AGG_CNT_BASE0, 8, &dev->stats.aggr_n[0] },
|
||||
{ MT_TX_AGG_CNT_BASE1, 8, &dev->stats.aggr_n[16] },
|
||||
};
|
||||
u32 sum, n;
|
||||
int i, j, k;
|
||||
|
||||
/* Note: using MCU_RANDOM_READ is actually slower then reading all the
|
||||
* registers by hand. MCU takes ca. 20ms to complete read of 24
|
||||
* registers while reading them one by one will takes roughly
|
||||
* 24*200us =~ 5ms.
|
||||
*/
|
||||
|
||||
k = 0;
|
||||
n = 0;
|
||||
sum = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(spans); i++)
|
||||
for (j = 0; j < spans[i].span; j++) {
|
||||
u32 val = mt76_rr(dev, spans[i].addr_base + j * 4);
|
||||
|
||||
spans[i].stat_base[j * 2] += val & 0xffff;
|
||||
spans[i].stat_base[j * 2 + 1] += val >> 16;
|
||||
|
||||
/* Calculate average AMPDU length */
|
||||
if (spans[i].addr_base != MT_TX_AGG_CNT_BASE0 &&
|
||||
spans[i].addr_base != MT_TX_AGG_CNT_BASE1)
|
||||
continue;
|
||||
|
||||
n += (val >> 16) + (val & 0xffff);
|
||||
sum += (val & 0xffff) * (1 + k * 2) +
|
||||
(val >> 16) * (2 + k * 2);
|
||||
k++;
|
||||
}
|
||||
|
||||
atomic_set(&dev->avg_ampdu_len, n ? DIV_ROUND_CLOSEST(sum, n) : 1);
|
||||
|
||||
mt76x0_check_mac_err(dev);
|
||||
|
||||
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work, 10 * HZ);
|
||||
}
|
||||
|
||||
void mt76x0_mac_set_ampdu_factor(struct mt76x02_dev *dev)
|
||||
{
|
||||
struct ieee80211_sta *sta;
|
||||
struct mt76_wcid *wcid;
|
||||
void *msta;
|
||||
u8 min_factor = 3;
|
||||
int i;
|
||||
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < ARRAY_SIZE(dev->mt76.wcid); i++) {
|
||||
wcid = rcu_dereference(dev->mt76.wcid[i]);
|
||||
if (!wcid)
|
||||
continue;
|
||||
|
||||
msta = container_of(wcid, struct mt76x02_sta, wcid);
|
||||
sta = container_of(msta, struct ieee80211_sta, drv_priv);
|
||||
|
||||
min_factor = min(min_factor, sta->ht_cap.ampdu_factor);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
mt76_wr(dev, MT_MAX_LEN_CFG, 0xa0fff |
|
||||
FIELD_PREP(MT_MAX_LEN_CFG_AMPDU, min_factor));
|
||||
}
|
@ -22,9 +22,23 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
|
||||
int ret;
|
||||
|
||||
cancel_delayed_work_sync(&dev->cal_work);
|
||||
if (mt76_is_mmio(dev)) {
|
||||
tasklet_disable(&dev->pre_tbtt_tasklet);
|
||||
tasklet_disable(&dev->dfs_pd.dfs_tasklet);
|
||||
}
|
||||
|
||||
mt76_set_channel(&dev->mt76);
|
||||
ret = mt76x0_phy_set_channel(dev, chandef);
|
||||
|
||||
/* channel cycle counters read-and-clear */
|
||||
mt76_rr(dev, MT_CH_IDLE);
|
||||
mt76_rr(dev, MT_CH_BUSY);
|
||||
|
||||
if (mt76_is_mmio(dev)) {
|
||||
mt76x02_dfs_init_params(dev);
|
||||
tasklet_enable(&dev->pre_tbtt_tasklet);
|
||||
tasklet_enable(&dev->dfs_pd.dfs_tasklet);
|
||||
}
|
||||
mt76_txq_schedule_all(&dev->mt76);
|
||||
|
||||
return ret;
|
||||
@ -64,89 +78,3 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x0_config);
|
||||
|
||||
static void
|
||||
mt76x0_addr_wr(struct mt76x02_dev *dev, const u32 offset, const u8 *addr)
|
||||
{
|
||||
mt76_wr(dev, offset, get_unaligned_le32(addr));
|
||||
mt76_wr(dev, offset + 4, addr[4] | addr[5] << 8);
|
||||
}
|
||||
|
||||
void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *info, u32 changed)
|
||||
{
|
||||
struct mt76x02_dev *dev = hw->priv;
|
||||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
||||
if (changed & BSS_CHANGED_BSSID) {
|
||||
mt76x0_addr_wr(dev, MT_MAC_BSSID_DW0, info->bssid);
|
||||
|
||||
/* Note: this is a hack because beacon_int is not changed
|
||||
* on leave nor is any more appropriate event generated.
|
||||
* rt2x00 doesn't seem to be bothered though.
|
||||
*/
|
||||
if (is_zero_ether_addr(info->bssid))
|
||||
mt76x0_mac_config_tsf(dev, false, 0);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_BASIC_RATES) {
|
||||
mt76_wr(dev, MT_LEGACY_BASIC_RATE, info->basic_rates);
|
||||
mt76_wr(dev, MT_VHT_HT_FBK_CFG0, 0x65432100);
|
||||
mt76_wr(dev, MT_VHT_HT_FBK_CFG1, 0xedcba980);
|
||||
mt76_wr(dev, MT_LG_FBK_CFG0, 0xedcba988);
|
||||
mt76_wr(dev, MT_LG_FBK_CFG1, 0x00002100);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_BEACON_INT)
|
||||
mt76x0_mac_config_tsf(dev, true, info->beacon_int);
|
||||
|
||||
if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
|
||||
mt76x0_mac_set_protection(dev, info->use_cts_prot,
|
||||
info->ht_operation_mode);
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_PREAMBLE)
|
||||
mt76x0_mac_set_short_preamble(dev, info->use_short_preamble);
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_SLOT) {
|
||||
int slottime = info->use_short_slot ? 9 : 20;
|
||||
|
||||
mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG,
|
||||
MT_BKOFF_SLOT_CFG_SLOTTIME, slottime);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ASSOC)
|
||||
mt76x0_phy_recalibrate_after_assoc(dev);
|
||||
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x0_bss_info_changed);
|
||||
|
||||
void mt76x0_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
const u8 *mac_addr)
|
||||
{
|
||||
struct mt76x02_dev *dev = hw->priv;
|
||||
|
||||
set_bit(MT76_SCANNING, &dev->mt76.state);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x0_sw_scan);
|
||||
|
||||
void mt76x0_sw_scan_complete(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct mt76x02_dev *dev = hw->priv;
|
||||
|
||||
clear_bit(MT76_SCANNING, &dev->mt76.state);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x0_sw_scan_complete);
|
||||
|
||||
int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
{
|
||||
struct mt76x02_dev *dev = hw->priv;
|
||||
|
||||
mt76_rmw_field(dev, MT_TX_RTS_CFG, MT_TX_RTS_CFG_THRESH, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x0_set_rts_threshold);
|
||||
|
@ -28,18 +28,26 @@
|
||||
#include "../mt76x02.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
#define MT_CALIBRATE_INTERVAL (4 * HZ)
|
||||
#define MT7610E_FIRMWARE "mediatek/mt7610e.bin"
|
||||
#define MT7650E_FIRMWARE "mediatek/mt7650e.bin"
|
||||
|
||||
#define MT7610U_FIRMWARE "mediatek/mt7610u.bin"
|
||||
|
||||
#define MT_USB_AGGR_SIZE_LIMIT 21 /* * 1024B */
|
||||
#define MT_USB_AGGR_TIMEOUT 0x80 /* * 33ns */
|
||||
|
||||
static inline bool is_mt7610e(struct mt76x02_dev *dev)
|
||||
{
|
||||
/* TODO */
|
||||
return false;
|
||||
if (!mt76_is_mmio(dev))
|
||||
return false;
|
||||
|
||||
return mt76_chip(&dev->mt76) == 0x7610;
|
||||
}
|
||||
|
||||
void mt76x0_init_debugfs(struct mt76x02_dev *dev);
|
||||
static inline bool is_mt7630(struct mt76x02_dev *dev)
|
||||
{
|
||||
return mt76_chip(&dev->mt76) == 0x7630;
|
||||
}
|
||||
|
||||
/* Init */
|
||||
struct mt76x02_dev *
|
||||
@ -54,30 +62,12 @@ int mt76x0_mac_start(struct mt76x02_dev *dev);
|
||||
void mt76x0_mac_stop(struct mt76x02_dev *dev);
|
||||
|
||||
int mt76x0_config(struct ieee80211_hw *hw, u32 changed);
|
||||
void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *info, u32 changed);
|
||||
void mt76x0_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
const u8 *mac_addr);
|
||||
void mt76x0_sw_scan_complete(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif);
|
||||
int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
|
||||
|
||||
/* PHY */
|
||||
void mt76x0_phy_init(struct mt76x02_dev *dev);
|
||||
int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev);
|
||||
int mt76x0_phy_wait_bbp_ready(struct mt76x02_dev *dev);
|
||||
int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
void mt76x0_phy_recalibrate_after_assoc(struct mt76x02_dev *dev);
|
||||
void mt76x0_phy_set_txpower(struct mt76x02_dev *dev);
|
||||
void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on);
|
||||
|
||||
/* MAC */
|
||||
void mt76x0_mac_work(struct work_struct *work);
|
||||
void mt76x0_mac_set_protection(struct mt76x02_dev *dev, bool legacy_prot,
|
||||
int ht_mode);
|
||||
void mt76x0_mac_set_short_preamble(struct mt76x02_dev *dev, bool short_preamb);
|
||||
void mt76x0_mac_config_tsf(struct mt76x02_dev *dev, bool enable, int interval);
|
||||
void mt76x0_mac_set_ampdu_factor(struct mt76x02_dev *dev);
|
||||
|
||||
#endif
|
||||
|
@ -68,6 +68,19 @@ static void mt76x0e_stop(struct ieee80211_hw *hw)
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
mt76x0e_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
u32 queues, bool drop)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
mt76x0e_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
|
||||
bool set)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ieee80211_ops mt76x0e_ops = {
|
||||
.tx = mt76x02_tx,
|
||||
.start = mt76x0e_start,
|
||||
@ -76,15 +89,22 @@ static const struct ieee80211_ops mt76x0e_ops = {
|
||||
.remove_interface = mt76x02_remove_interface,
|
||||
.config = mt76x0_config,
|
||||
.configure_filter = mt76x02_configure_filter,
|
||||
.sta_add = mt76x02_sta_add,
|
||||
.sta_remove = mt76x02_sta_remove,
|
||||
.bss_info_changed = mt76x02_bss_info_changed,
|
||||
.sta_state = mt76_sta_state,
|
||||
.set_key = mt76x02_set_key,
|
||||
.conf_tx = mt76x02_conf_tx,
|
||||
.sw_scan_start = mt76x0_sw_scan,
|
||||
.sw_scan_complete = mt76x0_sw_scan_complete,
|
||||
.sw_scan_start = mt76x02_sw_scan,
|
||||
.sw_scan_complete = mt76x02_sw_scan_complete,
|
||||
.ampdu_action = mt76x02_ampdu_action,
|
||||
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
|
||||
.wake_tx_queue = mt76_wake_tx_queue,
|
||||
.get_survey = mt76_get_survey,
|
||||
.get_txpower = mt76x02_get_txpower,
|
||||
.flush = mt76x0e_flush,
|
||||
.set_tim = mt76x0e_set_tim,
|
||||
.release_buffered_frames = mt76_release_buffered_frames,
|
||||
.set_coverage_class = mt76x02_set_coverage_class,
|
||||
.set_rts_threshold = mt76x02_set_rts_threshold,
|
||||
};
|
||||
|
||||
static int mt76x0e_register_device(struct mt76x02_dev *dev)
|
||||
@ -135,10 +155,14 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
static const struct mt76_driver_ops drv_ops = {
|
||||
.txwi_size = sizeof(struct mt76x02_txwi),
|
||||
.update_survey = mt76x02_update_channel,
|
||||
.tx_prepare_skb = mt76x02_tx_prepare_skb,
|
||||
.tx_complete_skb = mt76x02_tx_complete_skb,
|
||||
.rx_skb = mt76x02_queue_rx_skb,
|
||||
.rx_poll_complete = mt76x02_rx_poll_complete,
|
||||
.sta_ps = mt76x02_sta_ps,
|
||||
.sta_add = mt76x02_sta_add,
|
||||
.sta_remove = mt76x02_sta_remove,
|
||||
};
|
||||
struct mt76x02_dev *dev;
|
||||
int ret;
|
||||
@ -185,6 +209,7 @@ error:
|
||||
static void mt76x0e_cleanup(struct mt76x02_dev *dev)
|
||||
{
|
||||
clear_bit(MT76_STATE_INITIALIZED, &dev->mt76.state);
|
||||
tasklet_disable(&dev->pre_tbtt_tasklet);
|
||||
mt76x0_chip_onoff(dev, false, false);
|
||||
mt76x0e_stop_hw(dev);
|
||||
mt76x02_dma_cleanup(dev);
|
||||
@ -209,6 +234,8 @@ static const struct pci_device_id mt76x0e_device_table[] = {
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, mt76x0e_device_table);
|
||||
MODULE_FIRMWARE(MT7610E_FIRMWARE);
|
||||
MODULE_FIRMWARE(MT7650E_FIRMWARE);
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
static struct pci_driver mt76x0e_driver = {
|
||||
|
@ -19,9 +19,6 @@
|
||||
#include "mt76x0.h"
|
||||
#include "mcu.h"
|
||||
|
||||
#define MT7610E_FIRMWARE "mediatek/mt7610e.bin"
|
||||
#define MT7650E_FIRMWARE "mediatek/mt7650e.bin"
|
||||
|
||||
#define MT_MCU_IVB_ADDR (MT_MCU_ILM_ADDR + 0x54000 - MT_MCU_IVB_SIZE)
|
||||
|
||||
static int mt76x0e_load_firmware(struct mt76x02_dev *dev)
|
||||
@ -130,7 +127,6 @@ out:
|
||||
int mt76x0e_mcu_init(struct mt76x02_dev *dev)
|
||||
{
|
||||
static const struct mt76_mcu_ops mt76x0e_mcu_ops = {
|
||||
.mcu_msg_alloc = mt76x02_mcu_msg_alloc,
|
||||
.mcu_send_msg = mt76x02_mcu_msg_send,
|
||||
};
|
||||
int err;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,23 @@
|
||||
#define MT_RF_BANK(offset) (offset >> 16)
|
||||
#define MT_RF_REG(offset) (offset & 0xff)
|
||||
|
||||
#define MT_RF_VCO_BP_CLOSE_LOOP BIT(3)
|
||||
#define MT_RF_VCO_BP_CLOSE_LOOP_MASK GENMASK(3, 0)
|
||||
#define MT_RF_VCO_CAL_MASK GENMASK(2, 0)
|
||||
#define MT_RF_START_TIME 0x3
|
||||
#define MT_RF_START_TIME_MASK GENMASK(2, 0)
|
||||
#define MT_RF_SETTLE_TIME_MASK GENMASK(6, 4)
|
||||
|
||||
#define MT_RF_PLL_DEN_MASK GENMASK(4, 0)
|
||||
#define MT_RF_PLL_K_MASK GENMASK(4, 0)
|
||||
#define MT_RF_SDM_RESET_MASK BIT(7)
|
||||
#define MT_RF_SDM_MASH_PRBS_MASK GENMASK(6, 2)
|
||||
#define MT_RF_SDM_BP_MASK BIT(1)
|
||||
#define MT_RF_ISI_ISO_MASK GENMASK(7, 6)
|
||||
#define MT_RF_PFD_DLY_MASK GENMASK(5, 4)
|
||||
#define MT_RF_CLK_SEL_MASK GENMASK(3, 2)
|
||||
#define MT_RF_XO_DIV_MASK GENMASK(1, 0)
|
||||
|
||||
struct mt76x0_bbp_switch_item {
|
||||
u16 bw_band;
|
||||
struct mt76_reg_pair reg_pair;
|
||||
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
|
||||
* Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#ifndef __CHECKER__
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "trace.h"
|
||||
|
||||
#endif
|
@ -1,312 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
|
||||
* Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#if !defined(__MT76X0U_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define __MT76X0U_TRACE_H
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
#include "mt76x0.h"
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM mt76x0
|
||||
|
||||
#define MAXNAME 32
|
||||
#define DEV_ENTRY __array(char, wiphy_name, 32)
|
||||
#define DEV_ASSIGN strlcpy(__entry->wiphy_name, \
|
||||
wiphy_name(dev->hw->wiphy), MAXNAME)
|
||||
#define DEV_PR_FMT "%s "
|
||||
#define DEV_PR_ARG __entry->wiphy_name
|
||||
|
||||
#define REG_ENTRY __field(u32, reg) __field(u32, val)
|
||||
#define REG_ASSIGN __entry->reg = reg; __entry->val = val
|
||||
#define REG_PR_FMT "%04x=%08x"
|
||||
#define REG_PR_ARG __entry->reg, __entry->val
|
||||
|
||||
DECLARE_EVENT_CLASS(dev_reg_evt,
|
||||
TP_PROTO(struct mt76_dev *dev, u32 reg, u32 val),
|
||||
TP_ARGS(dev, reg, val),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
REG_ENTRY
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
REG_ASSIGN;
|
||||
),
|
||||
TP_printk(
|
||||
DEV_PR_FMT REG_PR_FMT,
|
||||
DEV_PR_ARG, REG_PR_ARG
|
||||
)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dev_reg_evt, mt76x0_reg_read,
|
||||
TP_PROTO(struct mt76_dev *dev, u32 reg, u32 val),
|
||||
TP_ARGS(dev, reg, val)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dev_reg_evt, mt76x0_reg_write,
|
||||
TP_PROTO(struct mt76_dev *dev, u32 reg, u32 val),
|
||||
TP_ARGS(dev, reg, val)
|
||||
);
|
||||
|
||||
TRACE_EVENT(mt76x0_submit_urb,
|
||||
TP_PROTO(struct mt76_dev *dev, struct urb *u),
|
||||
TP_ARGS(dev, u),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY __field(unsigned, pipe) __field(u32, len)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->pipe = u->pipe;
|
||||
__entry->len = u->transfer_buffer_length;
|
||||
),
|
||||
TP_printk(DEV_PR_FMT "p:%08x len:%u",
|
||||
DEV_PR_ARG, __entry->pipe, __entry->len)
|
||||
);
|
||||
|
||||
#define trace_mt76x0_submit_urb_sync(__dev, __pipe, __len) ({ \
|
||||
struct urb u; \
|
||||
u.pipe = __pipe; \
|
||||
u.transfer_buffer_length = __len; \
|
||||
trace_mt76x0_submit_urb(__dev, &u); \
|
||||
})
|
||||
|
||||
TRACE_EVENT(mt76x0_mcu_msg_send,
|
||||
TP_PROTO(struct mt76_dev *dev,
|
||||
struct sk_buff *skb, u32 csum, bool resp),
|
||||
TP_ARGS(dev, skb, csum, resp),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field(u32, info)
|
||||
__field(u32, csum)
|
||||
__field(bool, resp)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->info = *(u32 *)skb->data;
|
||||
__entry->csum = csum;
|
||||
__entry->resp = resp;
|
||||
),
|
||||
TP_printk(DEV_PR_FMT "i:%08x c:%08x r:%d",
|
||||
DEV_PR_ARG, __entry->info, __entry->csum, __entry->resp)
|
||||
);
|
||||
|
||||
TRACE_EVENT(mt76x0_vend_req,
|
||||
TP_PROTO(struct mt76_dev *dev, unsigned pipe, u8 req, u8 req_type,
|
||||
u16 val, u16 offset, void *buf, size_t buflen, int ret),
|
||||
TP_ARGS(dev, pipe, req, req_type, val, offset, buf, buflen, ret),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field(unsigned, pipe) __field(u8, req) __field(u8, req_type)
|
||||
__field(u16, val) __field(u16, offset) __field(void*, buf)
|
||||
__field(int, buflen) __field(int, ret)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->pipe = pipe;
|
||||
__entry->req = req;
|
||||
__entry->req_type = req_type;
|
||||
__entry->val = val;
|
||||
__entry->offset = offset;
|
||||
__entry->buf = buf;
|
||||
__entry->buflen = buflen;
|
||||
__entry->ret = ret;
|
||||
),
|
||||
TP_printk(DEV_PR_FMT
|
||||
"%d p:%08x req:%02hhx %02hhx val:%04hx %04hx buf:%d %d",
|
||||
DEV_PR_ARG, __entry->ret, __entry->pipe, __entry->req,
|
||||
__entry->req_type, __entry->val, __entry->offset,
|
||||
!!__entry->buf, __entry->buflen)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(dev_rf_reg_evt,
|
||||
TP_PROTO(struct mt76_dev *dev, u8 bank, u8 reg, u8 val),
|
||||
TP_ARGS(dev, bank, reg, val),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field(u8, bank)
|
||||
__field(u8, reg)
|
||||
__field(u8, val)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
REG_ASSIGN;
|
||||
__entry->bank = bank;
|
||||
),
|
||||
TP_printk(
|
||||
DEV_PR_FMT "%02hhx:%02hhx=%02hhx",
|
||||
DEV_PR_ARG, __entry->bank, __entry->reg, __entry->val
|
||||
)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dev_rf_reg_evt, mt76x0_rf_read,
|
||||
TP_PROTO(struct mt76_dev *dev, u8 bank, u8 reg, u8 val),
|
||||
TP_ARGS(dev, bank, reg, val)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dev_rf_reg_evt, mt76x0_rf_write,
|
||||
TP_PROTO(struct mt76_dev *dev, u8 bank, u8 reg, u8 val),
|
||||
TP_ARGS(dev, bank, reg, val)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(dev_simple_evt,
|
||||
TP_PROTO(struct mt76_dev *dev, u8 val),
|
||||
TP_ARGS(dev, val),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field(u8, val)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->val = val;
|
||||
),
|
||||
TP_printk(
|
||||
DEV_PR_FMT "%02hhx", DEV_PR_ARG, __entry->val
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(mt76x0_rx,
|
||||
TP_PROTO(struct mt76_dev *dev, struct mt76x02_rxwi *rxwi, u32 f),
|
||||
TP_ARGS(dev, rxwi, f),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field_struct(struct mt76x02_rxwi, rxwi)
|
||||
__field(u32, fce_info)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->rxwi = *rxwi;
|
||||
__entry->fce_info = f;
|
||||
),
|
||||
TP_printk(DEV_PR_FMT "rxi:%08x ctl:%08x", DEV_PR_ARG,
|
||||
le32_to_cpu(__entry->rxwi.rxinfo),
|
||||
le32_to_cpu(__entry->rxwi.ctl))
|
||||
);
|
||||
|
||||
TRACE_EVENT(mt76x0_tx,
|
||||
TP_PROTO(struct mt76_dev *dev, struct sk_buff *skb,
|
||||
struct mt76x02_sta *sta, struct mt76x02_txwi *h),
|
||||
TP_ARGS(dev, skb, sta, h),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field_struct(struct mt76x02_txwi, h)
|
||||
__field(struct sk_buff *, skb)
|
||||
__field(struct mt76x02_sta *, sta)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->h = *h;
|
||||
__entry->skb = skb;
|
||||
__entry->sta = sta;
|
||||
),
|
||||
TP_printk(DEV_PR_FMT "skb:%p sta:%p flg:%04hx rate:%04hx "
|
||||
"ack:%02hhx wcid:%02hhx len_ctl:%05hx", DEV_PR_ARG,
|
||||
__entry->skb, __entry->sta,
|
||||
le16_to_cpu(__entry->h.flags),
|
||||
le16_to_cpu(__entry->h.rate),
|
||||
__entry->h.ack_ctl, __entry->h.wcid,
|
||||
le16_to_cpu(__entry->h.len_ctl))
|
||||
);
|
||||
|
||||
TRACE_EVENT(mt76x0_tx_dma_done,
|
||||
TP_PROTO(struct mt76_dev *dev, struct sk_buff *skb),
|
||||
TP_ARGS(dev, skb),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field(struct sk_buff *, skb)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->skb = skb;
|
||||
),
|
||||
TP_printk(DEV_PR_FMT "%p", DEV_PR_ARG, __entry->skb)
|
||||
);
|
||||
|
||||
TRACE_EVENT(mt76x0_tx_status_cleaned,
|
||||
TP_PROTO(struct mt76_dev *dev, int cleaned),
|
||||
TP_ARGS(dev, cleaned),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field(int, cleaned)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->cleaned = cleaned;
|
||||
),
|
||||
TP_printk(DEV_PR_FMT "%d", DEV_PR_ARG, __entry->cleaned)
|
||||
);
|
||||
|
||||
TRACE_EVENT(mt76x0_tx_status,
|
||||
TP_PROTO(struct mt76_dev *dev, u32 stat1, u32 stat2),
|
||||
TP_ARGS(dev, stat1, stat2),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field(u32, stat1) __field(u32, stat2)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->stat1 = stat1;
|
||||
__entry->stat2 = stat2;
|
||||
),
|
||||
TP_printk(DEV_PR_FMT "%08x %08x",
|
||||
DEV_PR_ARG, __entry->stat1, __entry->stat2)
|
||||
);
|
||||
|
||||
TRACE_EVENT(mt76x0_rx_dma_aggr,
|
||||
TP_PROTO(struct mt76_dev *dev, int cnt, bool paged),
|
||||
TP_ARGS(dev, cnt, paged),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field(u8, cnt)
|
||||
__field(bool, paged)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->cnt = cnt;
|
||||
__entry->paged = paged;
|
||||
),
|
||||
TP_printk(DEV_PR_FMT "cnt:%d paged:%d",
|
||||
DEV_PR_ARG, __entry->cnt, __entry->paged)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dev_simple_evt, mt76x0_set_key,
|
||||
TP_PROTO(struct mt76_dev *dev, u8 val),
|
||||
TP_ARGS(dev, val)
|
||||
);
|
||||
|
||||
TRACE_EVENT(mt76x0_set_shared_key,
|
||||
TP_PROTO(struct mt76_dev *dev, u8 vid, u8 key),
|
||||
TP_ARGS(dev, vid, key),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field(u8, vid)
|
||||
__field(u8, key)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->vid = vid;
|
||||
__entry->key = key;
|
||||
),
|
||||
TP_printk(DEV_PR_FMT "phy:%02hhx off:%02hhx",
|
||||
DEV_PR_ARG, __entry->vid, __entry->key)
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH .
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE trace
|
||||
|
||||
#include <trace/define_trace.h>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user