提交 fbbae71d 编写于 作者: K Kalle Valo

Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git

ath.git patches for 4.21. 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
......@@ -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,
/* keep last */
WMI_SERVICE_MAX,
......@@ -244,6 +246,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 {
......@@ -359,6 +364,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)
......@@ -568,6 +576,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,
......@@ -786,6 +796,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
......@@ -986,6 +998,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;
};
/*
......@@ -1601,6 +1614,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,
};
......@@ -4984,6 +4999,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
......@@ -5065,6 +5081,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
......@@ -5404,8 +5421,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)
......@@ -7153,6 +7182,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 @@ static int wil_link_debugfs_show(struct seq_file *s, void *data)
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 @@ static void wil_print_rxtid_crypto(struct seq_file *s, int tid,
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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册