Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for v5.7. Major changes: ath11k * handle RX fragments * enable PN offload * add support for HE BSS color
This commit is contained in:
commit
8bc513b994
|
@ -119,6 +119,7 @@ struct ath10k_skb_cb {
|
|||
u16 airtime_est;
|
||||
struct ieee80211_vif *vif;
|
||||
struct ieee80211_txq *txq;
|
||||
u32 ucast_cipher;
|
||||
} __packed;
|
||||
|
||||
struct ath10k_skb_rxcb {
|
||||
|
@ -504,6 +505,7 @@ struct ath10k_sta {
|
|||
struct work_struct update_wk;
|
||||
u64 rx_duration;
|
||||
struct ath10k_htt_tx_stats *tx_stats;
|
||||
u32 ucast_cipher;
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
/* protected by conf_mutex */
|
||||
|
|
|
@ -1163,6 +1163,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
|||
int len = 0;
|
||||
int msdu_id = -1;
|
||||
int res;
|
||||
const u8 *peer_addr;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
|
||||
len += sizeof(cmd->hdr);
|
||||
|
@ -1178,7 +1179,16 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
|||
ieee80211_is_deauth(hdr->frame_control) ||
|
||||
ieee80211_is_disassoc(hdr->frame_control)) &&
|
||||
ieee80211_has_protected(hdr->frame_control)) {
|
||||
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
||||
peer_addr = hdr->addr1;
|
||||
if (is_multicast_ether_addr(peer_addr)) {
|
||||
skb_put(msdu, sizeof(struct ieee80211_mmie_16));
|
||||
} else {
|
||||
if (skb_cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP ||
|
||||
skb_cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP_256)
|
||||
skb_put(msdu, IEEE80211_GCMP_MIC_LEN);
|
||||
else
|
||||
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
txdesc = ath10k_htc_alloc_skb(ar, len);
|
||||
|
|
|
@ -258,6 +258,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
|
|||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_GCM];
|
||||
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_BIP_GMAC_128:
|
||||
case WLAN_CIPHER_SUITE_BIP_GMAC_256:
|
||||
|
@ -3576,6 +3577,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
|
|||
static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_txq *txq,
|
||||
struct ieee80211_sta *sta,
|
||||
struct sk_buff *skb, u16 airtime)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
|
@ -3583,6 +3585,7 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
|
|||
const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
bool is_data = ieee80211_is_data(hdr->frame_control) ||
|
||||
ieee80211_is_data_qos(hdr->frame_control);
|
||||
struct ath10k_sta *arsta;
|
||||
|
||||
cb->flags = 0;
|
||||
if (!ath10k_tx_h_use_hwcrypto(vif, skb))
|
||||
|
@ -3607,6 +3610,12 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
|
|||
cb->vif = vif;
|
||||
cb->txq = txq;
|
||||
cb->airtime_est = airtime;
|
||||
if (sta) {
|
||||
arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
cb->ucast_cipher = arsta->ucast_cipher;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
}
|
||||
|
||||
bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
|
||||
|
@ -4078,7 +4087,7 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
|
|||
}
|
||||
|
||||
airtime = ath10k_mac_update_airtime(ar, txq, skb);
|
||||
ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
|
||||
ath10k_mac_tx_h_fill_cb(ar, vif, txq, sta, skb, airtime);
|
||||
|
||||
skb_len = skb->len;
|
||||
txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
|
||||
|
@ -4348,7 +4357,7 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
|
|||
u16 airtime;
|
||||
|
||||
airtime = ath10k_mac_update_airtime(ar, txq, skb);
|
||||
ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
|
||||
ath10k_mac_tx_h_fill_cb(ar, vif, txq, sta, skb, airtime);
|
||||
|
||||
txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
|
||||
txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
|
||||
|
@ -6197,6 +6206,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
||||
struct ath10k_sta *arsta;
|
||||
struct ath10k_peer *peer;
|
||||
const u8 *peer_addr;
|
||||
bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
|
||||
|
@ -6221,12 +6231,17 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (sta)
|
||||
if (sta) {
|
||||
arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
peer_addr = sta->addr;
|
||||
else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
arsta->ucast_cipher = key->cipher;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
} else if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
|
||||
peer_addr = vif->bss_conf.bssid;
|
||||
else
|
||||
} else {
|
||||
peer_addr = vif->addr;
|
||||
}
|
||||
|
||||
key->hw_key_idx = key->keyidx;
|
||||
|
||||
|
|
|
@ -1926,6 +1926,7 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
|
|||
u32 vdev_id;
|
||||
u32 buf_len = msdu->len;
|
||||
u16 fc;
|
||||
const u8 *peer_addr;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
fc = le16_to_cpu(hdr->frame_control);
|
||||
|
@ -1946,8 +1947,20 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
|
|||
ieee80211_is_deauth(hdr->frame_control) ||
|
||||
ieee80211_is_disassoc(hdr->frame_control)) &&
|
||||
ieee80211_has_protected(hdr->frame_control)) {
|
||||
len += IEEE80211_CCMP_MIC_LEN;
|
||||
buf_len += IEEE80211_CCMP_MIC_LEN;
|
||||
peer_addr = hdr->addr1;
|
||||
if (is_multicast_ether_addr(peer_addr)) {
|
||||
len += sizeof(struct ieee80211_mmie_16);
|
||||
buf_len += sizeof(struct ieee80211_mmie_16);
|
||||
} else {
|
||||
if (cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP ||
|
||||
cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP_256) {
|
||||
len += IEEE80211_GCMP_MIC_LEN;
|
||||
buf_len += IEEE80211_GCMP_MIC_LEN;
|
||||
} else {
|
||||
len += IEEE80211_CCMP_MIC_LEN;
|
||||
buf_len += IEEE80211_CCMP_MIC_LEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len = round_up(len, 4);
|
||||
|
|
|
@ -3,6 +3,7 @@ config ATH11K
|
|||
tristate "Qualcomm Technologies 802.11ax chipset support"
|
||||
depends on MAC80211 && HAS_DMA
|
||||
depends on REMOTEPROC
|
||||
depends on CRYPTO_MICHAEL_MIC
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
select ATH_COMMON
|
||||
select QCOM_QMI_HELPERS
|
||||
|
|
|
@ -458,7 +458,6 @@ static void ath11k_ahb_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
|
|||
|
||||
static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
|
||||
|
@ -468,9 +467,6 @@ static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab)
|
|||
|
||||
napi_synchronize(&irq_grp->napi);
|
||||
napi_disable(&irq_grp->napi);
|
||||
|
||||
while ((skb = __skb_dequeue(&irq_grp->pending_q)))
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -681,6 +677,9 @@ static irqreturn_t ath11k_ahb_ce_interrupt_handler(int irq, void *arg)
|
|||
{
|
||||
struct ath11k_ce_pipe *ce_pipe = arg;
|
||||
|
||||
/* last interrupt received for this CE */
|
||||
ce_pipe->timestamp = jiffies;
|
||||
|
||||
ath11k_ahb_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num);
|
||||
|
||||
tasklet_schedule(&ce_pipe->intr_tq);
|
||||
|
@ -712,6 +711,9 @@ static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg)
|
|||
{
|
||||
struct ath11k_ext_irq_grp *irq_grp = arg;
|
||||
|
||||
/* last interrupt received for this group */
|
||||
irq_grp->timestamp = jiffies;
|
||||
|
||||
ath11k_ahb_ext_grp_disable(irq_grp);
|
||||
|
||||
napi_schedule(&irq_grp->napi);
|
||||
|
@ -734,7 +736,6 @@ static int ath11k_ahb_ext_irq_config(struct ath11k_base *ab)
|
|||
init_dummy_netdev(&irq_grp->napi_ndev);
|
||||
netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi,
|
||||
ath11k_ahb_ext_grp_napi_poll, NAPI_POLL_WEIGHT);
|
||||
__skb_queue_head_init(&irq_grp->pending_q);
|
||||
|
||||
for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) {
|
||||
if (ath11k_tx_ring_mask[i] & BIT(j)) {
|
||||
|
|
|
@ -161,6 +161,7 @@ struct ath11k_ce_pipe {
|
|||
struct ath11k_ce_ring *src_ring;
|
||||
struct ath11k_ce_ring *dest_ring;
|
||||
struct ath11k_ce_ring *status_ring;
|
||||
u64 timestamp;
|
||||
};
|
||||
|
||||
struct ath11k_ce {
|
||||
|
|
|
@ -77,6 +77,8 @@ struct ath11k_skb_rxcb {
|
|||
u8 err_code;
|
||||
u8 mac_id;
|
||||
u8 unmapped;
|
||||
u8 is_frag;
|
||||
u8 tid;
|
||||
};
|
||||
|
||||
enum ath11k_hw_rev {
|
||||
|
@ -109,12 +111,9 @@ struct ath11k_ext_irq_grp {
|
|||
u32 irqs[ATH11K_EXT_IRQ_NUM_MAX];
|
||||
u32 num_irq;
|
||||
u32 grp_id;
|
||||
u64 timestamp;
|
||||
struct napi_struct napi;
|
||||
struct net_device napi_ndev;
|
||||
/* Queue of pending packets, not expected to be accessed concurrently
|
||||
* to avoid locking overhead.
|
||||
*/
|
||||
struct sk_buff_head pending_q;
|
||||
};
|
||||
|
||||
#define HEHANDLE_CAP_PHYINFO_SIZE 3
|
||||
|
@ -332,6 +331,7 @@ struct ath11k_sta {
|
|||
u32 bw;
|
||||
u32 nss;
|
||||
u32 smps;
|
||||
enum hal_pn_type pn_type;
|
||||
|
||||
struct work_struct update_wk;
|
||||
struct rate_info txrate;
|
||||
|
|
|
@ -53,6 +53,8 @@ enum ath11k_dbg_htt_ext_stats_type {
|
|||
ATH11K_DBG_HTT_EXT_STATS_TWT_SESSIONS = 20,
|
||||
ATH11K_DBG_HTT_EXT_STATS_REO_RESOURCE_STATS = 21,
|
||||
ATH11K_DBG_HTT_EXT_STATS_TX_SOUNDING_INFO = 22,
|
||||
ATH11K_DBG_HTT_EXT_STATS_PDEV_OBSS_PD_STATS = 23,
|
||||
ATH11K_DBG_HTT_EXT_STATS_RING_BACKPRESSURE_STATS = 24,
|
||||
|
||||
/* keep this last */
|
||||
ATH11K_DBG_HTT_NUM_EXT_STATS,
|
||||
|
|
|
@ -3854,6 +3854,47 @@ htt_print_pdev_obss_pd_stats_tlv_v(const void *tag_buf,
|
|||
stats_req->buf_len = len;
|
||||
}
|
||||
|
||||
static inline void htt_print_backpressure_stats_tlv_v(const u32 *tag_buf,
|
||||
u8 *data)
|
||||
{
|
||||
struct debug_htt_stats_req *stats_req =
|
||||
(struct debug_htt_stats_req *)data;
|
||||
struct htt_ring_backpressure_stats_tlv *htt_stats_buf =
|
||||
(struct htt_ring_backpressure_stats_tlv *)tag_buf;
|
||||
int i;
|
||||
u8 *buf = stats_req->buf;
|
||||
u32 len = stats_req->buf_len;
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "pdev_id = %u",
|
||||
htt_stats_buf->pdev_id);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "current_head_idx = %u",
|
||||
htt_stats_buf->current_head_idx);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "current_tail_idx = %u",
|
||||
htt_stats_buf->current_tail_idx);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "num_htt_msgs_sent = %u",
|
||||
htt_stats_buf->num_htt_msgs_sent);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"backpressure_time_ms = %u",
|
||||
htt_stats_buf->backpressure_time_ms);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"backpressure_hist_%u = %u",
|
||||
i + 1, htt_stats_buf->backpressure_hist[i]);
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"============================");
|
||||
|
||||
if (len >= buf_len) {
|
||||
buf[buf_len - 1] = 0;
|
||||
stats_req->buf_len = buf_len - 1;
|
||||
} else {
|
||||
buf[len] = 0;
|
||||
stats_req->buf_len = len;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void htt_htt_stats_debug_dump(const u32 *tag_buf,
|
||||
struct debug_htt_stats_req *stats_req)
|
||||
{
|
||||
|
@ -4246,6 +4287,9 @@ static int ath11k_dbg_htt_ext_stats_parse(struct ath11k_base *ab,
|
|||
case HTT_STATS_PDEV_OBSS_PD_TAG:
|
||||
htt_print_pdev_obss_pd_stats_tlv_v(tag_buf, stats_req);
|
||||
break;
|
||||
case HTT_STATS_RING_BACKPRESSURE_STATS_TAG:
|
||||
htt_print_backpressure_stats_tlv_v(tag_buf, user_data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -100,6 +100,8 @@ enum htt_tlv_tag_t {
|
|||
HTT_STATS_SCHED_TXQ_SCHED_ORDER_SU_TAG = 86,
|
||||
HTT_STATS_SCHED_TXQ_SCHED_INELIGIBILITY_TAG = 87,
|
||||
HTT_STATS_PDEV_OBSS_PD_TAG = 88,
|
||||
HTT_STATS_HW_WAR_TAG = 89,
|
||||
HTT_STATS_RING_BACKPRESSURE_STATS_TAG = 90,
|
||||
|
||||
HTT_STATS_MAX_TAG,
|
||||
};
|
||||
|
@ -1659,4 +1661,30 @@ struct htt_pdev_obss_pd_stats_tlv {
|
|||
};
|
||||
|
||||
void ath11k_debug_htt_stats_init(struct ath11k *ar);
|
||||
|
||||
struct htt_ring_backpressure_stats_tlv {
|
||||
u32 pdev_id;
|
||||
u32 current_head_idx;
|
||||
u32 current_tail_idx;
|
||||
u32 num_htt_msgs_sent;
|
||||
/* Time in milliseconds for which the ring has been in
|
||||
* its current backpressure condition
|
||||
*/
|
||||
u32 backpressure_time_ms;
|
||||
/* backpressure_hist - histogram showing how many times
|
||||
* different degrees of backpressure duration occurred:
|
||||
* Index 0 indicates the number of times ring was
|
||||
* continuously in backpressure state for 100 - 200ms.
|
||||
* Index 1 indicates the number of times ring was
|
||||
* continuously in backpressure state for 200 - 300ms.
|
||||
* Index 2 indicates the number of times ring was
|
||||
* continuously in backpressure state for 300 - 400ms.
|
||||
* Index 3 indicates the number of times ring was
|
||||
* continuously in backpressure state for 400 - 500ms.
|
||||
* Index 4 indicates the number of times ring was
|
||||
* continuously in backpressure state beyond 500ms.
|
||||
*/
|
||||
u32 backpressure_hist[5];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -219,6 +219,9 @@ static ssize_t ath11k_dbg_sta_dump_tx_stats(struct file *file,
|
|||
const int size = 2 * 4096;
|
||||
char *buf;
|
||||
|
||||
if (!arsta->tx_stats)
|
||||
return -ENOENT;
|
||||
|
||||
buf = kzalloc(size, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <crypto/hash.h>
|
||||
#include "core.h"
|
||||
#include "dp_tx.h"
|
||||
#include "hal_tx.h"
|
||||
|
@ -33,6 +34,7 @@ void ath11k_dp_peer_cleanup(struct ath11k *ar, int vdev_id, const u8 *addr)
|
|||
}
|
||||
|
||||
ath11k_peer_rx_tid_cleanup(ar, peer);
|
||||
crypto_free_shash(peer->tfm_mmic);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
}
|
||||
|
||||
|
@ -56,8 +58,8 @@ int ath11k_dp_peer_setup(struct ath11k *ar, int vdev_id, const u8 *addr)
|
|||
}
|
||||
|
||||
for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) {
|
||||
ret = ath11k_peer_rx_tid_setup(ar, addr, vdev_id,
|
||||
tid, 1, 0);
|
||||
ret = ath11k_peer_rx_tid_setup(ar, addr, vdev_id, tid, 1, 0,
|
||||
HAL_PN_TYPE_NONE);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to setup rxd tid queue for tid %d: %d\n",
|
||||
tid, ret);
|
||||
|
@ -65,6 +67,12 @@ int ath11k_dp_peer_setup(struct ath11k *ar, int vdev_id, const u8 *addr)
|
|||
}
|
||||
}
|
||||
|
||||
ret = ath11k_peer_rx_frag_setup(ar, addr, vdev_id);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to setup rx defrag context\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* TODO: Setup other peer specific resource used in data path */
|
||||
|
||||
return 0;
|
||||
|
@ -210,6 +218,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
|
|||
struct ath11k_dp *dp = &ab->dp;
|
||||
struct hal_srng *srng;
|
||||
int i, ret;
|
||||
u32 ring_hash_map;
|
||||
|
||||
ret = ath11k_dp_srng_setup(ab, &dp->wbm_desc_rel_ring,
|
||||
HAL_SW2WBM_RELEASE, 0, 0,
|
||||
|
@ -297,7 +306,21 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
|
|||
goto err;
|
||||
}
|
||||
|
||||
ath11k_hal_reo_hw_setup(ab);
|
||||
/* When hash based routing of rx packet is enabled, 32 entries to map
|
||||
* the hash values to the ring will be configured. Each hash entry uses
|
||||
* three bits to map to a particular ring. The ring mapping will be
|
||||
* 0:TCL, 1:SW1, 2:SW2, 3:SW3, 4:SW4, 5:Release, 6:FW and 7:Not used.
|
||||
*/
|
||||
ring_hash_map = HAL_HASH_ROUTING_RING_SW1 << 0 |
|
||||
HAL_HASH_ROUTING_RING_SW2 << 3 |
|
||||
HAL_HASH_ROUTING_RING_SW3 << 6 |
|
||||
HAL_HASH_ROUTING_RING_SW4 << 9 |
|
||||
HAL_HASH_ROUTING_RING_SW1 << 12 |
|
||||
HAL_HASH_ROUTING_RING_SW2 << 15 |
|
||||
HAL_HASH_ROUTING_RING_SW3 << 18 |
|
||||
HAL_HASH_ROUTING_RING_SW4 << 21;
|
||||
|
||||
ath11k_hal_reo_hw_setup(ab, ring_hash_map);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -627,17 +650,13 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
|
|||
}
|
||||
|
||||
if (ath11k_rx_ring_mask[grp_id]) {
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
if (ath11k_rx_ring_mask[grp_id] & BIT(i)) {
|
||||
work_done = ath11k_dp_process_rx(ab, i, napi,
|
||||
&irq_grp->pending_q,
|
||||
budget);
|
||||
budget -= work_done;
|
||||
tot_work_done += work_done;
|
||||
}
|
||||
if (budget <= 0)
|
||||
goto done;
|
||||
}
|
||||
i = fls(ath11k_rx_ring_mask[grp_id]) - 1;
|
||||
work_done = ath11k_dp_process_rx(ab, i, napi,
|
||||
budget);
|
||||
budget -= work_done;
|
||||
tot_work_done += work_done;
|
||||
if (budget <= 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (rx_mon_status_ring_mask[grp_id]) {
|
||||
|
|
|
@ -22,6 +22,18 @@ struct dp_rx_tid {
|
|||
u32 size;
|
||||
u32 ba_win_sz;
|
||||
bool active;
|
||||
|
||||
/* Info related to rx fragments */
|
||||
u32 cur_sn;
|
||||
u16 last_frag_no;
|
||||
u16 rx_frag_bitmap;
|
||||
|
||||
struct sk_buff_head rx_frags;
|
||||
struct hal_reo_dest_ring *dst_ring_desc;
|
||||
|
||||
/* Timer info related to fragments */
|
||||
struct timer_list frag_timer;
|
||||
struct ath11k_base *ab;
|
||||
};
|
||||
|
||||
#define DP_REO_DESC_FREE_TIMEOUT_MS 1000
|
||||
|
@ -128,7 +140,6 @@ struct ath11k_pdev_dp {
|
|||
u32 mac_id;
|
||||
atomic_t num_tx_pending;
|
||||
wait_queue_head_t tx_empty_waitq;
|
||||
struct dp_srng reo_dst_ring;
|
||||
struct dp_rxdma_ring rx_refill_buf_ring;
|
||||
struct dp_srng rxdma_err_dst_ring;
|
||||
struct dp_srng rxdma_mon_dst_ring;
|
||||
|
@ -148,7 +159,7 @@ struct ath11k_pdev_dp {
|
|||
#define DP_AVG_MPDUS_PER_TID_MAX 128
|
||||
#define DP_AVG_MSDUS_PER_MPDU 4
|
||||
|
||||
#define DP_RX_HASH_ENABLE 0 /* Disable hash based Rx steering */
|
||||
#define DP_RX_HASH_ENABLE 1 /* Enable hash based Rx steering */
|
||||
|
||||
#define DP_BA_WIN_SZ_MAX 256
|
||||
|
||||
|
@ -206,6 +217,7 @@ struct ath11k_dp {
|
|||
struct dp_srng reo_except_ring;
|
||||
struct dp_srng reo_cmd_ring;
|
||||
struct dp_srng reo_status_ring;
|
||||
struct dp_srng reo_dst_ring[DP_REO_DST_RING_MAX];
|
||||
struct dp_tx_ring tx_ring[DP_TCL_NUM_RING_MAX];
|
||||
struct hal_wbm_idle_scatter_list scatter_list[DP_IDLE_SCATTER_BUFS_MAX];
|
||||
struct list_head reo_cmd_list;
|
||||
|
@ -924,6 +936,7 @@ enum htt_t2h_msg_type {
|
|||
HTT_T2H_MSG_TYPE_PEER_UNMAP = 0x1f,
|
||||
HTT_T2H_MSG_TYPE_PPDU_STATS_IND = 0x1d,
|
||||
HTT_T2H_MSG_TYPE_EXT_STATS_CONF = 0x1c,
|
||||
HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND = 0x24,
|
||||
};
|
||||
|
||||
#define HTT_TARGET_VERSION_MAJOR 3
|
||||
|
@ -972,6 +985,13 @@ struct htt_resp_msg {
|
|||
};
|
||||
} __packed;
|
||||
|
||||
#define HTT_BACKPRESSURE_EVENT_PDEV_ID_M GENMASK(15, 8)
|
||||
#define HTT_BACKPRESSURE_EVENT_RING_TYPE_M GENMASK(23, 16)
|
||||
#define HTT_BACKPRESSURE_EVENT_RING_ID_M GENMASK(31, 24)
|
||||
|
||||
#define HTT_BACKPRESSURE_EVENT_HP_M GENMASK(15, 0)
|
||||
#define HTT_BACKPRESSURE_EVENT_TP_M GENMASK(31, 16)
|
||||
|
||||
/* ppdu stats
|
||||
*
|
||||
* @details
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,6 +9,8 @@
|
|||
#include "rx_desc.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define DP_MAX_NWIFI_HDR_LEN 30
|
||||
|
||||
#define DP_RX_MPDU_ERR_FCS BIT(0)
|
||||
#define DP_RX_MPDU_ERR_DECRYPT BIT(1)
|
||||
#define DP_RX_MPDU_ERR_TKIP_MIC BIT(2)
|
||||
|
@ -43,11 +45,16 @@ int ath11k_dp_rx_ampdu_start(struct ath11k *ar,
|
|||
struct ieee80211_ampdu_params *params);
|
||||
int ath11k_dp_rx_ampdu_stop(struct ath11k *ar,
|
||||
struct ieee80211_ampdu_params *params);
|
||||
int ath11k_dp_peer_rx_pn_replay_config(struct ath11k_vif *arvif,
|
||||
const u8 *peer_addr,
|
||||
enum set_key_cmd key_cmd,
|
||||
struct ieee80211_key_conf *key);
|
||||
void ath11k_peer_rx_tid_cleanup(struct ath11k *ar, struct ath11k_peer *peer);
|
||||
void ath11k_peer_rx_tid_delete(struct ath11k *ar,
|
||||
struct ath11k_peer *peer, u8 tid);
|
||||
int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id,
|
||||
u8 tid, u32 ba_win_sz, u16 ssn);
|
||||
u8 tid, u32 ba_win_sz, u16 ssn,
|
||||
enum hal_pn_type pn_type);
|
||||
void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab,
|
||||
struct sk_buff *skb);
|
||||
int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab);
|
||||
|
@ -62,7 +69,7 @@ int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab,
|
|||
int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
|
||||
int budget);
|
||||
int ath11k_dp_process_rx(struct ath11k_base *ab, int mac_id,
|
||||
struct napi_struct *napi, struct sk_buff_head *pending_q,
|
||||
struct napi_struct *napi,
|
||||
int budget);
|
||||
int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id,
|
||||
struct dp_rxdma_ring *rx_ring,
|
||||
|
@ -84,5 +91,6 @@ int ath11k_dp_rx_mon_status_bufs_replenish(struct ath11k_base *ab, int mac_id,
|
|||
gfp_t gfp);
|
||||
int ath11k_dp_rx_pdev_mon_detach(struct ath11k *ar);
|
||||
int ath11k_dp_rx_pdev_mon_attach(struct ath11k *ar);
|
||||
int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id);
|
||||
|
||||
#endif /* ATH11K_DP_RX_H */
|
||||
|
|
|
@ -47,7 +47,7 @@ static u8 ath11k_dp_tx_get_tid(struct sk_buff *skb)
|
|||
return skb->priority & IEEE80211_QOS_CTL_TID_MASK;
|
||||
}
|
||||
|
||||
static enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher)
|
||||
enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher)
|
||||
{
|
||||
switch (cipher) {
|
||||
case WLAN_CIPHER_SUITE_WEP40:
|
||||
|
|
|
@ -877,23 +877,32 @@ void ath11k_hal_srng_access_end(struct ath11k_base *ab, struct hal_srng *srng)
|
|||
/* For LMAC rings, ring pointer updates are done through FW and
|
||||
* hence written to a shared memory location that is read by FW
|
||||
*/
|
||||
if (srng->ring_dir == HAL_SRNG_DIR_SRC)
|
||||
if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
|
||||
srng->u.src_ring.last_tp =
|
||||
*(volatile u32 *)srng->u.src_ring.tp_addr;
|
||||
*srng->u.src_ring.hp_addr = srng->u.src_ring.hp;
|
||||
else
|
||||
} else {
|
||||
srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
|
||||
*srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp;
|
||||
}
|
||||
} else {
|
||||
if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
|
||||
srng->u.src_ring.last_tp =
|
||||
*(volatile u32 *)srng->u.src_ring.tp_addr;
|
||||
ath11k_ahb_write32(ab,
|
||||
(unsigned long)srng->u.src_ring.hp_addr -
|
||||
(unsigned long)ab->mem,
|
||||
srng->u.src_ring.hp);
|
||||
} else {
|
||||
srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
|
||||
ath11k_ahb_write32(ab,
|
||||
(unsigned long)srng->u.dst_ring.tp_addr -
|
||||
(unsigned long)ab->mem,
|
||||
srng->u.dst_ring.tp);
|
||||
}
|
||||
}
|
||||
|
||||
srng->timestamp = jiffies;
|
||||
}
|
||||
|
||||
void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab,
|
||||
|
@ -1017,6 +1026,7 @@ int ath11k_hal_srng_setup(struct ath11k_base *ab, enum hal_ring_type type,
|
|||
params->intr_batch_cntr_thres_entries;
|
||||
srng->intr_timer_thres_us = params->intr_timer_thres_us;
|
||||
srng->flags = params->flags;
|
||||
srng->initialized = 1;
|
||||
spin_lock_init(&srng->lock);
|
||||
|
||||
for (i = 0; i < HAL_SRNG_NUM_REG_GRP; i++) {
|
||||
|
@ -1122,3 +1132,55 @@ void ath11k_hal_srng_deinit(struct ath11k_base *ab)
|
|||
ath11k_hal_free_cont_rdp(ab);
|
||||
ath11k_hal_free_cont_wrp(ab);
|
||||
}
|
||||
|
||||
void ath11k_hal_dump_srng_stats(struct ath11k_base *ab)
|
||||
{
|
||||
struct hal_srng *srng;
|
||||
struct ath11k_ext_irq_grp *irq_grp;
|
||||
struct ath11k_ce_pipe *ce_pipe;
|
||||
int i;
|
||||
|
||||
ath11k_err(ab, "Last interrupt received for each CE:\n");
|
||||
for (i = 0; i < CE_COUNT; i++) {
|
||||
ce_pipe = &ab->ce.ce_pipe[i];
|
||||
|
||||
if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR)
|
||||
continue;
|
||||
|
||||
ath11k_err(ab, "CE_id %d pipe_num %d %ums before\n",
|
||||
i, ce_pipe->pipe_num,
|
||||
jiffies_to_msecs(jiffies - ce_pipe->timestamp));
|
||||
}
|
||||
|
||||
ath11k_err(ab, "\nLast interrupt received for each group:\n");
|
||||
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
|
||||
irq_grp = &ab->ext_irq_grp[i];
|
||||
ath11k_err(ab, "group_id %d %ums before\n",
|
||||
irq_grp->grp_id,
|
||||
jiffies_to_msecs(jiffies - irq_grp->timestamp));
|
||||
}
|
||||
|
||||
for (i = 0; i < HAL_SRNG_RING_ID_MAX; i++) {
|
||||
srng = &ab->hal.srng_list[i];
|
||||
|
||||
if (!srng->initialized)
|
||||
continue;
|
||||
|
||||
if (srng->ring_dir == HAL_SRNG_DIR_SRC)
|
||||
ath11k_err(ab,
|
||||
"src srng id %u hp %u, reap_hp %u, cur tp %u, cached tp %u last tp %u napi processed before %ums\n",
|
||||
srng->ring_id, srng->u.src_ring.hp,
|
||||
srng->u.src_ring.reap_hp,
|
||||
*srng->u.src_ring.tp_addr, srng->u.src_ring.cached_tp,
|
||||
srng->u.src_ring.last_tp,
|
||||
jiffies_to_msecs(jiffies - srng->timestamp));
|
||||
else if (srng->ring_dir == HAL_SRNG_DIR_DST)
|
||||
ath11k_err(ab,
|
||||
"dst srng id %u tp %u, cur hp %u, cached hp %u last hp %u napi processed before %ums\n",
|
||||
srng->ring_id, srng->u.dst_ring.tp,
|
||||
*srng->u.dst_ring.hp_addr,
|
||||
srng->u.dst_ring.cached_hp,
|
||||
srng->u.dst_ring.last_hp,
|
||||
jiffies_to_msecs(jiffies - srng->timestamp));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,8 @@ struct ath11k_base;
|
|||
|
||||
/* REO2SW(x) R0 ring configuration address */
|
||||
#define HAL_REO1_GEN_ENABLE 0x00000000
|
||||
#define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004
|
||||
#define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008
|
||||
#define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c
|
||||
#define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010
|
||||
#define HAL_REO1_RING_BASE_LSB 0x0000029c
|
||||
|
@ -529,6 +531,8 @@ struct hal_srng {
|
|||
*/
|
||||
u32 hwreg_base[HAL_SRNG_NUM_REG_GRP];
|
||||
|
||||
u64 timestamp;
|
||||
|
||||
/* Source or Destination ring */
|
||||
enum hal_srng_dir ring_dir;
|
||||
|
||||
|
@ -554,6 +558,9 @@ struct hal_srng {
|
|||
|
||||
/* max transfer size */
|
||||
u16 max_buffer_length;
|
||||
|
||||
/* head pointer at access end */
|
||||
u32 last_hp;
|
||||
} dst_ring;
|
||||
|
||||
struct {
|
||||
|
@ -577,6 +584,9 @@ struct hal_srng {
|
|||
|
||||
/* Low threshold - in number of ring entries */
|
||||
u32 low_threshold;
|
||||
|
||||
/* tail pointer at access end */
|
||||
u32 last_tp;
|
||||
} src_ring;
|
||||
} u;
|
||||
};
|
||||
|
@ -717,6 +727,14 @@ enum hal_ce_desc {
|
|||
HAL_CE_DESC_DST_STATUS,
|
||||
};
|
||||
|
||||
#define HAL_HASH_ROUTING_RING_TCL 0
|
||||
#define HAL_HASH_ROUTING_RING_SW1 1
|
||||
#define HAL_HASH_ROUTING_RING_SW2 2
|
||||
#define HAL_HASH_ROUTING_RING_SW3 3
|
||||
#define HAL_HASH_ROUTING_RING_SW4 4
|
||||
#define HAL_HASH_ROUTING_RING_REL 5
|
||||
#define HAL_HASH_ROUTING_RING_FW 6
|
||||
|
||||
struct hal_reo_status_header {
|
||||
u16 cmd_num;
|
||||
enum hal_reo_cmd_status cmd_status;
|
||||
|
@ -847,10 +865,10 @@ struct ath11k_hal {
|
|||
|
||||
u32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid);
|
||||
void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size,
|
||||
u32 start_seqtype);
|
||||
u32 start_seq, enum hal_pn_type type);
|
||||
void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
void ath11k_hal_reo_hw_setup(struct ath11k_base *ab);
|
||||
void ath11k_hal_reo_hw_setup(struct ath11k_base *ab, u32 ring_hash_map);
|
||||
void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab,
|
||||
struct hal_wbm_idle_scatter_list *sbuf,
|
||||
u32 nsbufs, u32 tot_link_desc,
|
||||
|
@ -893,5 +911,6 @@ int ath11k_hal_srng_setup(struct ath11k_base *ab, enum hal_ring_type type,
|
|||
struct hal_srng_params *params);
|
||||
int ath11k_hal_srng_init(struct ath11k_base *ath11k);
|
||||
void ath11k_hal_srng_deinit(struct ath11k_base *ath11k);
|
||||
void ath11k_hal_dump_srng_stats(struct ath11k_base *ab);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -694,7 +694,7 @@ u32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid)
|
|||
}
|
||||
|
||||
void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size,
|
||||
u32 start_seq)
|
||||
u32 start_seq, enum hal_pn_type type)
|
||||
{
|
||||
struct hal_rx_reo_queue *qdesc = (struct hal_rx_reo_queue *)vaddr;
|
||||
struct hal_rx_reo_queue_ext *ext_desc;
|
||||
|
@ -723,6 +723,18 @@ void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size,
|
|||
|
||||
qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE,
|
||||
ba_window_size - 1);
|
||||
switch (type) {
|
||||
case HAL_PN_TYPE_NONE:
|
||||
case HAL_PN_TYPE_WAPI_EVEN:
|
||||
case HAL_PN_TYPE_WAPI_UNEVEN:
|
||||
break;
|
||||
case HAL_PN_TYPE_WPA:
|
||||
qdesc->info0 |=
|
||||
FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_CHECK, 1) |
|
||||
FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_SIZE,
|
||||
HAL_RX_REO_QUEUE_PN_SIZE_48);
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: Set Ignore ampdu flags based on BA window size and/or
|
||||
* AMPDU capabilities
|
||||
|
@ -787,7 +799,7 @@ void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab,
|
|||
}
|
||||
}
|
||||
|
||||
void ath11k_hal_reo_hw_setup(struct ath11k_base *ab)
|
||||
void ath11k_hal_reo_hw_setup(struct ath11k_base *ab, u32 ring_hash_map)
|
||||
{
|
||||
u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG;
|
||||
u32 val;
|
||||
|
@ -809,6 +821,19 @@ void ath11k_hal_reo_hw_setup(struct ath11k_base *ab)
|
|||
HAL_DEFAULT_REO_TIMEOUT_USEC);
|
||||
ath11k_ahb_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3,
|
||||
HAL_DEFAULT_REO_TIMEOUT_USEC);
|
||||
|
||||
ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0,
|
||||
FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP,
|
||||
ring_hash_map));
|
||||
ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_1,
|
||||
FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP,
|
||||
ring_hash_map));
|
||||
ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2,
|
||||
FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP,
|
||||
ring_hash_map));
|
||||
ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3,
|
||||
FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP,
|
||||
ring_hash_map));
|
||||
}
|
||||
|
||||
static enum hal_rx_mon_status
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#define TARGET_RX_BATCHMODE 1
|
||||
|
||||
#define ATH11K_HW_MAX_QUEUES 4
|
||||
#define ATH11K_QUEUE_LEN 4096
|
||||
|
||||
#define ATH11k_HW_RATECODE_CCK_SHORT_PREAM_MASK 0x4
|
||||
|
||||
|
|
|
@ -1956,6 +1956,31 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
|
|||
ath11k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id,
|
||||
&info->he_obss_pd);
|
||||
|
||||
if (changed & BSS_CHANGED_HE_BSS_COLOR) {
|
||||
if (vif->type == NL80211_IFTYPE_AP) {
|
||||
ret = ath11k_wmi_send_obss_color_collision_cfg_cmd(
|
||||
ar, arvif->vdev_id, info->he_bss_color.color,
|
||||
ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS,
|
||||
!info->he_bss_color.disabled);
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
} else if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
ret = ath11k_wmi_send_bss_color_change_enable_cmd(ar,
|
||||
arvif->vdev_id,
|
||||
1);
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab, "failed to enable bss color change on vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
ret = ath11k_wmi_send_obss_color_collision_cfg_cmd(
|
||||
ar, arvif->vdev_id, 0,
|
||||
ATH11K_BSS_COLOR_COLLISION_DETECTION_STA_PERIOD_MS, 1);
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
|
@ -2325,6 +2350,7 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
struct ath11k_base *ab = ar->ab;
|
||||
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
|
||||
struct ath11k_peer *peer;
|
||||
struct ath11k_sta *arsta;
|
||||
const u8 *peer_addr;
|
||||
int ret = 0;
|
||||
u32 flags = 0;
|
||||
|
@ -2382,15 +2408,53 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
ret = ath11k_dp_peer_rx_pn_replay_config(arvif, peer_addr, cmd, key);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to offload PN replay detection %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr);
|
||||
if (peer && cmd == SET_KEY)
|
||||
if (peer && cmd == SET_KEY) {
|
||||
peer->keys[key->keyidx] = key;
|
||||
else if (peer && cmd == DISABLE_KEY)
|
||||
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
|
||||
peer->ucast_keyidx = key->keyidx;
|
||||
peer->sec_type = ath11k_dp_tx_get_encrypt_type(key->cipher);
|
||||
} else {
|
||||
peer->mcast_keyidx = key->keyidx;
|
||||
peer->sec_type_grp = ath11k_dp_tx_get_encrypt_type(key->cipher);
|
||||
}
|
||||
} else if (peer && cmd == DISABLE_KEY) {
|
||||
peer->keys[key->keyidx] = NULL;
|
||||
else if (!peer)
|
||||
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
|
||||
peer->ucast_keyidx = 0;
|
||||
else
|
||||
peer->mcast_keyidx = 0;
|
||||
} else if (!peer)
|
||||
/* impossible unless FW goes crazy */
|
||||
ath11k_warn(ab, "peer %pM disappeared!\n", peer_addr);
|
||||
|
||||
if (sta) {
|
||||
arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
|
||||
switch (key->cipher) {
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
case WLAN_CIPHER_SUITE_CCMP_256:
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
if (cmd == SET_KEY)
|
||||
arsta->pn_type = HAL_PN_TYPE_WPA;
|
||||
else
|
||||
arsta->pn_type = HAL_PN_TYPE_NONE;
|
||||
break;
|
||||
default:
|
||||
arsta->pn_type = HAL_PN_TYPE_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
exit:
|
||||
|
@ -3914,6 +3978,9 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw)
|
|||
goto err;
|
||||
}
|
||||
|
||||
/* Configure the hash seed for hash based reo dest ring selection */
|
||||
ath11k_wmi_pdev_lro_cfg(ar, ar->pdev->pdev_id);
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx],
|
||||
|
@ -5731,6 +5798,7 @@ static int __ath11k_mac_register(struct ath11k *ar)
|
|||
ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_REORDERING_BUFFER);
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_AMSDU_IN_AMPDU);
|
||||
ieee80211_hw_set(ar->hw, USES_RSS);
|
||||
}
|
||||
|
||||
ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
|
||||
|
@ -5762,6 +5830,7 @@ static int __ath11k_mac_register(struct ath11k *ar)
|
|||
ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
|
||||
|
||||
ar->hw->queues = ATH11K_HW_MAX_QUEUES;
|
||||
ar->hw->wiphy->tx_queue_len = ATH11K_QUEUE_LEN;
|
||||
ar->hw->offchannel_tx_hw_queue = ATH11K_HW_MAX_QUEUES - 1;
|
||||
ar->hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
|
||||
|
||||
|
|
|
@ -145,4 +145,5 @@ void ath11k_mac_peer_cleanup_all(struct ath11k *ar);
|
|||
int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx);
|
||||
u8 ath11k_mac_bw_to_mac80211_bw(u8 bw);
|
||||
enum ath11k_supported_bw ath11k_mac_mac80211_bw_to_ath11k_bw(enum rate_info_bw bw);
|
||||
enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher);
|
||||
#endif
|
||||
|
|
|
@ -228,6 +228,9 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
|
|||
peer->sta = sta;
|
||||
arvif->ast_hash = peer->ast_hash;
|
||||
|
||||
peer->sec_type = HAL_ENCRYPT_TYPE_OPEN;
|
||||
peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
|
||||
|
||||
ar->num_peers++;
|
||||
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
|
|
|
@ -17,6 +17,15 @@ struct ath11k_peer {
|
|||
/* protected by ab->data_lock */
|
||||
struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
|
||||
struct dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1];
|
||||
|
||||
/* Info used in MMIC verification of
|
||||
* RX fragments
|
||||
*/
|
||||
struct crypto_shash *tfm_mmic;
|
||||
u8 mcast_keyidx;
|
||||
u8 ucast_keyidx;
|
||||
u16 sec_type;
|
||||
u16 sec_type_grp;
|
||||
};
|
||||
|
||||
void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);
|
||||
|
|
|
@ -2365,6 +2365,7 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
|
|||
break;
|
||||
case ATH11K_QMI_EVENT_FW_READY:
|
||||
if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
|
||||
ath11k_hal_dump_srng_stats(ab);
|
||||
queue_work(ab->workqueue, &ab->restart_work);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -342,7 +342,7 @@ struct rx_attention {
|
|||
#define RX_MPDU_START_INFO0_PROTO_VER_ERR BIT(12)
|
||||
#define RX_MPDU_START_INFO0_AST_LOOKUP_VALID BIT(13)
|
||||
|
||||
#define RX_MPDU_START_INFO1_MPDU_CTRL_VALID BIT(0)
|
||||
#define RX_MPDU_START_INFO1_MPDU_FCTRL_VALID BIT(0)
|
||||
#define RX_MPDU_START_INFO1_MPDU_DUR_VALID BIT(1)
|
||||
#define RX_MPDU_START_INFO1_MAC_ADDR1_VALID BIT(2)
|
||||
#define RX_MPDU_START_INFO1_MAC_ADDR2_VALID BIT(3)
|
||||
|
|
|
@ -2707,6 +2707,84 @@ ath11k_wmi_send_obss_spr_cmd(struct ath11k *ar, u32 vdev_id,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id,
|
||||
u8 bss_color, u32 period,
|
||||
bool enable)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct ath11k_base *ab = wmi->wmi_ab->ab;
|
||||
struct wmi_obss_color_collision_cfg_params_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_obss_color_collision_cfg_params_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
|
||||
WMI_TAG_OBSS_COLOR_COLLISION_DET_CONFIG) |
|
||||
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
||||
cmd->vdev_id = vdev_id;
|
||||
cmd->evt_type = enable ? ATH11K_OBSS_COLOR_COLLISION_DETECTION :
|
||||
ATH11K_OBSS_COLOR_COLLISION_DETECTION_DISABLE;
|
||||
cmd->current_bss_color = bss_color;
|
||||
cmd->detection_period_ms = period;
|
||||
cmd->scan_period_ms = ATH11K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS;
|
||||
cmd->free_slot_expiry_time_ms = 0;
|
||||
cmd->flags = 0;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"wmi_send_obss_color_collision_cfg id %d type %d bss_color %d detect_period %d scan_period %d\n",
|
||||
cmd->vdev_id, cmd->evt_type, cmd->current_bss_color,
|
||||
cmd->detection_period_ms, cmd->scan_period_ms);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb,
|
||||
WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "Failed to send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id,
|
||||
bool enable)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct ath11k_base *ab = wmi->wmi_ab->ab;
|
||||
struct wmi_bss_color_change_enable_params_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_bss_color_change_enable_params_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_BSS_COLOR_CHANGE_ENABLE) |
|
||||
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
||||
cmd->vdev_id = vdev_id;
|
||||
cmd->enable = enable ? 1 : 0;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"wmi_send_bss_color_change_enable id %d enable %d\n",
|
||||
cmd->vdev_id, cmd->enable);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb,
|
||||
WMI_BSS_COLOR_CHANGE_ENABLE_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "Failed to send WMI_TWT_DIeABLE_CMDID");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
ath11k_fill_band_to_mac_param(struct ath11k_base *soc,
|
||||
struct wmi_host_pdev_band_to_mac *band_to_mac)
|
||||
|
@ -2917,6 +2995,41 @@ static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_pdev_lro_cfg(struct ath11k *ar,
|
||||
int pdev_id)
|
||||
{
|
||||
struct ath11k_wmi_pdev_lro_config_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct ath11k_wmi_pdev_lro_config_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_LRO_INFO_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
|
||||
get_random_bytes(cmd->th_4, sizeof(uint32_t) * ATH11K_IPV4_TH_SEED_SIZE);
|
||||
get_random_bytes(cmd->th_6, sizeof(uint32_t) * ATH11K_IPV6_TH_SEED_SIZE);
|
||||
|
||||
cmd->pdev_id = pdev_id;
|
||||
|
||||
ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_LRO_CONFIG_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab,
|
||||
"failed to send lro cfg req wmi cmd\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"WMI lro cfg cmd pdev_id 0x%x\n", pdev_id);
|
||||
return 0;
|
||||
err:
|
||||
dev_kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_wait_for_service_ready(struct ath11k_base *ab)
|
||||
{
|
||||
unsigned long time_left;
|
||||
|
|
|
@ -488,6 +488,7 @@ enum wmi_tlv_cmd_id {
|
|||
WMI_SAR_LIMITS_CMDID,
|
||||
WMI_OBSS_SCAN_ENABLE_CMDID = WMI_TLV_CMD(WMI_GRP_OBSS_OFL),
|
||||
WMI_OBSS_SCAN_DISABLE_CMDID,
|
||||
WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID,
|
||||
WMI_LPI_MGMT_SNOOPING_CONFIG_CMDID = WMI_TLV_CMD(WMI_GRP_LPI),
|
||||
WMI_LPI_START_SCAN_CMDID,
|
||||
WMI_LPI_STOP_SCAN_CMDID,
|
||||
|
@ -4620,6 +4621,42 @@ struct wmi_obss_spatial_reuse_params_cmd {
|
|||
u32 vdev_id;
|
||||
} __packed;
|
||||
|
||||
#define ATH11K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS 200
|
||||
#define ATH11K_OBSS_COLOR_COLLISION_DETECTION_DISABLE 0
|
||||
#define ATH11K_OBSS_COLOR_COLLISION_DETECTION 1
|
||||
|
||||
#define ATH11K_BSS_COLOR_COLLISION_DETECTION_STA_PERIOD_MS 10000
|
||||
#define ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS 5000
|
||||
|
||||
struct wmi_obss_color_collision_cfg_params_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
u32 flags;
|
||||
u32 evt_type;
|
||||
u32 current_bss_color;
|
||||
u32 detection_period_ms;
|
||||
u32 scan_period_ms;
|
||||
u32 free_slot_expiry_time_ms;
|
||||
} __packed;
|
||||
|
||||
struct wmi_bss_color_change_enable_params_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
u32 enable;
|
||||
} __packed;
|
||||
|
||||
#define ATH11K_IPV4_TH_SEED_SIZE 5
|
||||
#define ATH11K_IPV6_TH_SEED_SIZE 11
|
||||
|
||||
struct ath11k_wmi_pdev_lro_config_cmd {
|
||||
u32 tlv_header;
|
||||
u32 lro_enable;
|
||||
u32 res;
|
||||
u32 th_4[ATH11K_IPV4_TH_SEED_SIZE];
|
||||
u32 th_6[ATH11K_IPV6_TH_SEED_SIZE];
|
||||
u32 pdev_id;
|
||||
} __packed;
|
||||
|
||||
struct target_resource_config {
|
||||
u32 num_vdevs;
|
||||
u32 num_peers;
|
||||
|
@ -4814,4 +4851,10 @@ int ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id);
|
|||
int ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id);
|
||||
int ath11k_wmi_send_obss_spr_cmd(struct ath11k *ar, u32 vdev_id,
|
||||
struct ieee80211_he_obss_pd *he_obss_pd);
|
||||
int ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id,
|
||||
u8 bss_color, u32 period,
|
||||
bool enable);
|
||||
int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id,
|
||||
bool enable);
|
||||
int ath11k_wmi_pdev_lro_cfg(struct ath11k *ar, int pdev_id);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue