mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-24 09:19:34 +07:00
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for v5.8. Major changes: ath11k * add debugfs file for testing ADDBA and DELBA ath10k * enable VHT160 and VHT80+80 modes * enable radar detection in secondary segment * sdio: disable TX complete indication to improve throughput
This commit is contained in:
commit
67f373122b
@ -723,10 +723,7 @@ static int ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Data transfer is not initiated, when reduced Tx completion
|
||||
* is used for SDIO. disable it until fixed
|
||||
*/
|
||||
param &= ~HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET;
|
||||
param |= HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET;
|
||||
|
||||
/* Alternate credit size of 1544 as used by SDIO firmware is
|
||||
* not big enough for mac80211 / native wifi frames. disable it
|
||||
|
@ -56,6 +56,8 @@ struct ath10k_hif_ops {
|
||||
|
||||
int (*swap_mailbox)(struct ath10k *ar);
|
||||
|
||||
int (*get_htt_tx_complete)(struct ath10k *ar);
|
||||
|
||||
int (*map_service_to_pipe)(struct ath10k *ar, u16 service_id,
|
||||
u8 *ul_pipe, u8 *dl_pipe);
|
||||
|
||||
@ -144,6 +146,13 @@ static inline int ath10k_hif_swap_mailbox(struct ath10k *ar)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ath10k_hif_get_htt_tx_complete(struct ath10k *ar)
|
||||
{
|
||||
if (ar->hif.ops->get_htt_tx_complete)
|
||||
return ar->hif.ops->get_htt_tx_complete(ar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ath10k_hif_map_service_to_pipe(struct ath10k *ar,
|
||||
u16 service_id,
|
||||
u8 *ul_pipe, u8 *dl_pipe)
|
||||
|
@ -660,6 +660,16 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath10k_htc_change_tx_credit_flow(struct ath10k_htc *htc,
|
||||
enum ath10k_htc_ep_id eid,
|
||||
bool enable)
|
||||
{
|
||||
struct ath10k *ar = htc->ar;
|
||||
struct ath10k_htc_ep *ep = &ar->htc.endpoint[eid];
|
||||
|
||||
ep->tx_credit_flow_enabled = enable;
|
||||
}
|
||||
|
||||
int ath10k_htc_connect_service(struct ath10k_htc *htc,
|
||||
struct ath10k_htc_svc_conn_req *conn_req,
|
||||
struct ath10k_htc_svc_conn_resp *conn_resp)
|
||||
|
@ -386,6 +386,9 @@ int ath10k_htc_start(struct ath10k_htc *htc);
|
||||
int ath10k_htc_connect_service(struct ath10k_htc *htc,
|
||||
struct ath10k_htc_svc_conn_req *conn_req,
|
||||
struct ath10k_htc_svc_conn_resp *conn_resp);
|
||||
void ath10k_htc_change_tx_credit_flow(struct ath10k_htc *htc,
|
||||
enum ath10k_htc_ep_id eid,
|
||||
bool enable);
|
||||
int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid,
|
||||
struct sk_buff *packet);
|
||||
struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "htt.h"
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
#include "hif.h"
|
||||
|
||||
static const enum htt_t2h_msg_type htt_main_t2h_msg_types[] = {
|
||||
[HTT_MAIN_T2H_MSG_TYPE_VERSION_CONF] = HTT_T2H_MSG_TYPE_VERSION_CONF,
|
||||
@ -153,6 +154,10 @@ int ath10k_htt_connect(struct ath10k_htt *htt)
|
||||
|
||||
htt->eid = conn_resp.eid;
|
||||
|
||||
htt->disable_tx_comp = ath10k_hif_get_htt_tx_complete(htt->ar);
|
||||
if (htt->disable_tx_comp)
|
||||
ath10k_htc_change_tx_credit_flow(&htt->ar->htc, htt->eid, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -150,9 +150,19 @@ enum htt_data_tx_desc_flags1 {
|
||||
HTT_DATA_TX_DESC_FLAGS1_MORE_IN_BATCH = 1 << 12,
|
||||
HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD = 1 << 13,
|
||||
HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD = 1 << 14,
|
||||
HTT_DATA_TX_DESC_FLAGS1_RSVD1 = 1 << 15
|
||||
HTT_DATA_TX_DESC_FLAGS1_TX_COMPLETE = 1 << 15
|
||||
};
|
||||
|
||||
#define HTT_TX_CREDIT_DELTA_ABS_M 0xffff0000
|
||||
#define HTT_TX_CREDIT_DELTA_ABS_S 16
|
||||
#define HTT_TX_CREDIT_DELTA_ABS_GET(word) \
|
||||
(((word) & HTT_TX_CREDIT_DELTA_ABS_M) >> HTT_TX_CREDIT_DELTA_ABS_S)
|
||||
|
||||
#define HTT_TX_CREDIT_SIGN_BIT_M 0x00000100
|
||||
#define HTT_TX_CREDIT_SIGN_BIT_S 8
|
||||
#define HTT_TX_CREDIT_SIGN_BIT_GET(word) \
|
||||
(((word) & HTT_TX_CREDIT_SIGN_BIT_M) >> HTT_TX_CREDIT_SIGN_BIT_S)
|
||||
|
||||
enum htt_data_tx_ext_tid {
|
||||
HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST = 16,
|
||||
HTT_DATA_TX_EXT_TID_MGMT = 17,
|
||||
@ -2021,6 +2031,7 @@ struct ath10k_htt {
|
||||
bool tx_mem_allocated;
|
||||
const struct ath10k_htt_tx_ops *tx_ops;
|
||||
const struct ath10k_htt_rx_ops *rx_ops;
|
||||
bool disable_tx_comp;
|
||||
};
|
||||
|
||||
struct ath10k_htt_tx_ops {
|
||||
|
@ -3789,6 +3789,9 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
|
||||
}
|
||||
case HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION: {
|
||||
struct htt_tx_done tx_done = {};
|
||||
struct ath10k_htt *htt = &ar->htt;
|
||||
struct ath10k_htc *htc = &ar->htc;
|
||||
struct ath10k_htc_ep *ep = &ar->htc.endpoint[htt->eid];
|
||||
int status = __le32_to_cpu(resp->mgmt_tx_completion.status);
|
||||
int info = __le32_to_cpu(resp->mgmt_tx_completion.info);
|
||||
|
||||
@ -3814,6 +3817,12 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
|
||||
break;
|
||||
}
|
||||
|
||||
if (htt->disable_tx_comp) {
|
||||
spin_lock_bh(&htc->tx_lock);
|
||||
ep->tx_credits++;
|
||||
spin_unlock_bh(&htc->tx_lock);
|
||||
}
|
||||
|
||||
status = ath10k_txrx_tx_unref(htt, &tx_done);
|
||||
if (!status) {
|
||||
spin_lock_bh(&htt->tx_lock);
|
||||
@ -3888,8 +3897,31 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
|
||||
skb_queue_tail(&htt->rx_in_ord_compl_q, skb);
|
||||
return false;
|
||||
}
|
||||
case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND:
|
||||
case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND: {
|
||||
struct ath10k_htt *htt = &ar->htt;
|
||||
struct ath10k_htc *htc = &ar->htc;
|
||||
struct ath10k_htc_ep *ep = &ar->htc.endpoint[htt->eid];
|
||||
u32 msg_word = __le32_to_cpu(*(__le32 *)resp);
|
||||
int htt_credit_delta;
|
||||
|
||||
htt_credit_delta = HTT_TX_CREDIT_DELTA_ABS_GET(msg_word);
|
||||
if (HTT_TX_CREDIT_SIGN_BIT_GET(msg_word))
|
||||
htt_credit_delta = -htt_credit_delta;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_HTT,
|
||||
"htt credit update delta %d\n",
|
||||
htt_credit_delta);
|
||||
|
||||
if (htt->disable_tx_comp) {
|
||||
spin_lock_bh(&htc->tx_lock);
|
||||
ep->tx_credits += htt_credit_delta;
|
||||
spin_unlock_bh(&htc->tx_lock);
|
||||
ath10k_dbg(ar, ATH10K_DBG_HTT,
|
||||
"htt credit total %d\n",
|
||||
ep->tx_credits);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HTT_T2H_MSG_TYPE_CHAN_CHANGE: {
|
||||
u32 phymode = __le32_to_cpu(resp->chan_change.phymode);
|
||||
u32 freq = __le32_to_cpu(resp->chan_change.freq);
|
||||
|
@ -543,7 +543,39 @@ void ath10k_htt_tx_free(struct ath10k_htt *htt)
|
||||
|
||||
void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct ath10k_htt *htt = &ar->htt;
|
||||
struct htt_tx_done tx_done = {0};
|
||||
struct htt_cmd_hdr *htt_hdr;
|
||||
struct htt_data_tx_desc *desc_hdr = NULL;
|
||||
u16 flags1 = 0;
|
||||
u8 msg_type = 0;
|
||||
|
||||
if (htt->disable_tx_comp) {
|
||||
htt_hdr = (struct htt_cmd_hdr *)skb->data;
|
||||
msg_type = htt_hdr->msg_type;
|
||||
|
||||
if (msg_type == HTT_H2T_MSG_TYPE_TX_FRM) {
|
||||
desc_hdr = (struct htt_data_tx_desc *)
|
||||
(skb->data + sizeof(*htt_hdr));
|
||||
flags1 = __le16_to_cpu(desc_hdr->flags1);
|
||||
}
|
||||
}
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
if ((!htt->disable_tx_comp) || (msg_type != HTT_H2T_MSG_TYPE_TX_FRM))
|
||||
return;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_HTT,
|
||||
"htt tx complete msdu id:%u ,flags1:%x\n",
|
||||
__le16_to_cpu(desc_hdr->id), flags1);
|
||||
|
||||
if (flags1 & HTT_DATA_TX_DESC_FLAGS1_TX_COMPLETE)
|
||||
return;
|
||||
|
||||
tx_done.status = HTT_TX_COMPL_STATE_ACK;
|
||||
tx_done.msdu_id = __le16_to_cpu(desc_hdr->id);
|
||||
ath10k_txrx_tx_unref(&ar->htt, &tx_done);
|
||||
}
|
||||
|
||||
void ath10k_htt_hif_tx_complete(struct ath10k *ar, struct sk_buff *skb)
|
||||
@ -1279,6 +1311,9 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
|
||||
flags0 |= SM(ATH10K_HW_TXRX_MGMT,
|
||||
HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
|
||||
flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
|
||||
|
||||
if (htt->disable_tx_comp)
|
||||
flags1 |= HTT_DATA_TX_DESC_FLAGS1_TX_COMPLETE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -765,7 +765,7 @@ ath10k_is_rssi_enable(struct ath10k_hw_params *hw,
|
||||
#define TARGET_TLV_NUM_TDLS_VDEVS 1
|
||||
#define TARGET_TLV_NUM_TIDS ((TARGET_TLV_NUM_PEERS) * 2)
|
||||
#define TARGET_TLV_NUM_MSDU_DESC (1024 + 32)
|
||||
#define TARGET_TLV_NUM_MSDU_DESC_HL 64
|
||||
#define TARGET_TLV_NUM_MSDU_DESC_HL 1024
|
||||
#define TARGET_TLV_NUM_WOW_PATTERNS 22
|
||||
#define TARGET_TLV_MGMT_NUM_MSDU_DESC (50)
|
||||
|
||||
|
@ -2505,6 +2505,30 @@ ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
|
||||
return tx_mcs_set;
|
||||
}
|
||||
|
||||
static u32 get_160mhz_nss_from_maxrate(int rate)
|
||||
{
|
||||
u32 nss;
|
||||
|
||||
switch (rate) {
|
||||
case 780:
|
||||
nss = 1;
|
||||
break;
|
||||
case 1560:
|
||||
nss = 2;
|
||||
break;
|
||||
case 2106:
|
||||
nss = 3; /* not support MCS9 from spec*/
|
||||
break;
|
||||
case 3120:
|
||||
nss = 4;
|
||||
break;
|
||||
default:
|
||||
nss = 1;
|
||||
}
|
||||
|
||||
return nss;
|
||||
}
|
||||
|
||||
static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
@ -2512,6 +2536,7 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
|
||||
{
|
||||
const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
|
||||
struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
||||
struct ath10k_hw_params *hw = &ar->hw_params;
|
||||
struct cfg80211_chan_def def;
|
||||
enum nl80211_band band;
|
||||
const u16 *vht_mcs_mask;
|
||||
@ -2578,22 +2603,38 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
|
||||
arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
|
||||
__le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
|
||||
sta->addr, arg->peer_max_mpdu, arg->peer_flags);
|
||||
/* Configure bandwidth-NSS mapping to FW
|
||||
* for the chip's tx chains setting on 160Mhz bw
|
||||
*/
|
||||
if (arg->peer_phymode == MODE_11AC_VHT160 ||
|
||||
arg->peer_phymode == MODE_11AC_VHT80_80) {
|
||||
u32 rx_nss;
|
||||
u32 max_rate;
|
||||
|
||||
if (arg->peer_vht_rates.rx_max_rate &&
|
||||
(sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) {
|
||||
switch (arg->peer_vht_rates.rx_max_rate) {
|
||||
case 1560:
|
||||
/* Must be 2x2 at 160Mhz is all it can do. */
|
||||
arg->peer_bw_rxnss_override = 2;
|
||||
break;
|
||||
case 780:
|
||||
/* Can only do 1x1 at 160Mhz (Long Guard Interval) */
|
||||
arg->peer_bw_rxnss_override = 1;
|
||||
break;
|
||||
max_rate = arg->peer_vht_rates.rx_max_rate;
|
||||
rx_nss = get_160mhz_nss_from_maxrate(max_rate);
|
||||
|
||||
if (rx_nss == 0)
|
||||
rx_nss = arg->peer_num_spatial_streams;
|
||||
else
|
||||
rx_nss = min(arg->peer_num_spatial_streams, rx_nss);
|
||||
|
||||
max_rate = hw->vht160_mcs_tx_highest;
|
||||
rx_nss = min(rx_nss, get_160mhz_nss_from_maxrate(max_rate));
|
||||
|
||||
arg->peer_bw_rxnss_override =
|
||||
FIELD_PREP(WMI_PEER_NSS_MAP_ENABLE, 1) |
|
||||
FIELD_PREP(WMI_PEER_NSS_160MHZ_MASK, (rx_nss - 1));
|
||||
|
||||
if (arg->peer_phymode == MODE_11AC_VHT80_80) {
|
||||
arg->peer_bw_rxnss_override |=
|
||||
FIELD_PREP(WMI_PEER_NSS_80_80MHZ_MASK, (rx_nss - 1));
|
||||
}
|
||||
}
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac vht peer %pM max_mpdu %d flags 0x%x peer_rx_nss_override 0x%x\n",
|
||||
sta->addr, arg->peer_max_mpdu,
|
||||
arg->peer_flags, arg->peer_bw_rxnss_override);
|
||||
}
|
||||
|
||||
static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
|
||||
@ -2745,9 +2786,9 @@ static int ath10k_peer_assoc_prepare(struct ath10k *ar,
|
||||
ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -4563,13 +4604,6 @@ static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
|
||||
vht_cap.cap |= val;
|
||||
}
|
||||
|
||||
/* Currently the firmware seems to be buggy, don't enable 80+80
|
||||
* mode until that's resolved.
|
||||
*/
|
||||
if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) &&
|
||||
(ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == 0)
|
||||
vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
|
||||
|
||||
mcs_map = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
|
||||
@ -8625,7 +8659,9 @@ static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
|
||||
.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
|
||||
BIT(NL80211_CHAN_WIDTH_20) |
|
||||
BIT(NL80211_CHAN_WIDTH_40) |
|
||||
BIT(NL80211_CHAN_WIDTH_80),
|
||||
BIT(NL80211_CHAN_WIDTH_80) |
|
||||
BIT(NL80211_CHAN_WIDTH_80P80) |
|
||||
BIT(NL80211_CHAN_WIDTH_160),
|
||||
#endif
|
||||
},
|
||||
};
|
||||
@ -8643,7 +8679,9 @@ ieee80211_iface_combination ath10k_10_4_bcn_int_if_comb[] = {
|
||||
.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
|
||||
BIT(NL80211_CHAN_WIDTH_20) |
|
||||
BIT(NL80211_CHAN_WIDTH_40) |
|
||||
BIT(NL80211_CHAN_WIDTH_80),
|
||||
BIT(NL80211_CHAN_WIDTH_80) |
|
||||
BIT(NL80211_CHAN_WIDTH_80P80) |
|
||||
BIT(NL80211_CHAN_WIDTH_160),
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
@ -2074,6 +2074,7 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
|
||||
ath10k_pci_irq_sync(ar);
|
||||
napi_synchronize(&ar->napi);
|
||||
napi_disable(&ar->napi);
|
||||
cancel_work_sync(&ar_pci->dump_work);
|
||||
|
||||
/* Most likely the device has HTT Rx ring configured. The only way to
|
||||
* prevent the device from accessing (and possible corrupting) host
|
||||
|
@ -1752,6 +1752,28 @@ static int ath10k_sdio_hif_swap_mailbox(struct ath10k *ar)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_sdio_get_htt_tx_complete(struct ath10k *ar)
|
||||
{
|
||||
u32 addr, val;
|
||||
int ret;
|
||||
|
||||
addr = host_interest_item_address(HI_ITEM(hi_acs_flags));
|
||||
|
||||
ret = ath10k_sdio_hif_diag_read32(ar, addr, &val);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"unable to read hi_acs_flags for htt tx comple : %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = (val & HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_FW_ACK);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_SDIO, "sdio reduce tx complete fw%sack\n",
|
||||
ret ? " " : " not ");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* HIF start/stop */
|
||||
|
||||
static int ath10k_sdio_hif_start(struct ath10k *ar)
|
||||
@ -2026,6 +2048,7 @@ static const struct ath10k_hif_ops ath10k_sdio_hif_ops = {
|
||||
.start = ath10k_sdio_hif_start,
|
||||
.stop = ath10k_sdio_hif_stop,
|
||||
.swap_mailbox = ath10k_sdio_hif_swap_mailbox,
|
||||
.get_htt_tx_complete = ath10k_sdio_get_htt_tx_complete,
|
||||
.map_service_to_pipe = ath10k_sdio_hif_map_service_to_pipe,
|
||||
.get_default_pipe = ath10k_sdio_hif_get_default_pipe,
|
||||
.send_complete_check = ath10k_sdio_hif_send_complete_check,
|
||||
|
@ -37,7 +37,7 @@
|
||||
(ATH10K_SDIO_MAX_BUFFER_SIZE - sizeof(struct ath10k_htc_hdr))
|
||||
|
||||
#define ATH10K_HIF_MBOX_NUM_MAX 4
|
||||
#define ATH10K_SDIO_BUS_REQUEST_MAX_NUM 64
|
||||
#define ATH10K_SDIO_BUS_REQUEST_MAX_NUM 1024
|
||||
|
||||
#define ATH10K_SDIO_HIF_COMMUNICATION_TIMEOUT_HZ (100 * HZ)
|
||||
|
||||
@ -98,6 +98,7 @@
|
||||
#define ATH10K_FIFO_TIMEOUT_AND_CHIP_CONTROL_DISABLE_SLEEP_OFF 0xFFFEFFFF
|
||||
#define ATH10K_FIFO_TIMEOUT_AND_CHIP_CONTROL_DISABLE_SLEEP_ON 0x10000
|
||||
|
||||
/* TODO: remove this and use skb->cb instead, much cleaner approach */
|
||||
struct ath10k_sdio_bus_request {
|
||||
struct list_head list;
|
||||
|
||||
|
@ -84,9 +84,11 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
|
||||
wake_up(&htt->empty_tx_wq);
|
||||
spin_unlock_bh(&htt->tx_lock);
|
||||
|
||||
rcu_read_lock();
|
||||
if (txq && txq->sta && skb_cb->airtime_est)
|
||||
ieee80211_sta_register_airtime(txq->sta, txq->tid,
|
||||
skb_cb->airtime_est, 0);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
|
||||
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
|
||||
|
@ -2123,7 +2123,7 @@ ath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar,
|
||||
tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
|
||||
tlv->len = __cpu_to_le16(sizeof(*ch));
|
||||
ch = (void *)tlv->value;
|
||||
ath10k_wmi_put_wmi_channel(ch, &arg->channel);
|
||||
ath10k_wmi_put_wmi_channel(ar, ch, &arg->channel);
|
||||
|
||||
ptr += sizeof(*tlv);
|
||||
ptr += sizeof(*ch);
|
||||
@ -2763,7 +2763,7 @@ ath10k_wmi_tlv_op_gen_scan_chan_list(struct ath10k *ar,
|
||||
tlv->len = __cpu_to_le16(sizeof(*ci));
|
||||
ci = (void *)tlv->value;
|
||||
|
||||
ath10k_wmi_put_wmi_channel(ci, ch);
|
||||
ath10k_wmi_put_wmi_channel(ar, ci, ch);
|
||||
|
||||
chans += sizeof(*tlv);
|
||||
chans += sizeof(*ci);
|
||||
@ -3450,7 +3450,7 @@ ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar,
|
||||
tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
|
||||
tlv->len = __cpu_to_le16(sizeof(*chan));
|
||||
chan = (void *)tlv->value;
|
||||
ath10k_wmi_put_wmi_channel(chan, &chan_arg[i]);
|
||||
ath10k_wmi_put_wmi_channel(ar, chan, &chan_arg[i]);
|
||||
|
||||
ptr += sizeof(*tlv);
|
||||
ptr += sizeof(*chan);
|
||||
|
@ -1694,10 +1694,11 @@ static const struct wmi_peer_flags_map wmi_10_2_peer_flags_map = {
|
||||
.bw160 = WMI_10_2_PEER_160MHZ,
|
||||
};
|
||||
|
||||
void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
|
||||
void ath10k_wmi_put_wmi_channel(struct ath10k *ar, struct wmi_channel *ch,
|
||||
const struct wmi_channel_arg *arg)
|
||||
{
|
||||
u32 flags = 0;
|
||||
struct ieee80211_channel *chan = NULL;
|
||||
|
||||
memset(ch, 0, sizeof(*ch));
|
||||
|
||||
@ -1714,12 +1715,39 @@ void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
|
||||
if (arg->chan_radar)
|
||||
flags |= WMI_CHAN_FLAG_DFS;
|
||||
|
||||
ch->band_center_freq2 = 0;
|
||||
ch->mhz = __cpu_to_le32(arg->freq);
|
||||
ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1);
|
||||
if (arg->mode == MODE_11AC_VHT80_80)
|
||||
if (arg->mode == MODE_11AC_VHT80_80) {
|
||||
ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq2);
|
||||
else
|
||||
ch->band_center_freq2 = 0;
|
||||
chan = ieee80211_get_channel(ar->hw->wiphy,
|
||||
arg->band_center_freq2 - 10);
|
||||
}
|
||||
|
||||
if (arg->mode == MODE_11AC_VHT160) {
|
||||
u32 band_center_freq1;
|
||||
u32 band_center_freq2;
|
||||
|
||||
if (arg->freq > arg->band_center_freq1) {
|
||||
band_center_freq1 = arg->band_center_freq1 + 40;
|
||||
band_center_freq2 = arg->band_center_freq1 - 40;
|
||||
} else {
|
||||
band_center_freq1 = arg->band_center_freq1 - 40;
|
||||
band_center_freq2 = arg->band_center_freq1 + 40;
|
||||
}
|
||||
|
||||
ch->band_center_freq1 =
|
||||
__cpu_to_le32(band_center_freq1);
|
||||
/* Minus 10 to get a defined 5G channel frequency*/
|
||||
chan = ieee80211_get_channel(ar->hw->wiphy,
|
||||
band_center_freq2 - 10);
|
||||
/* The center frequency of the entire VHT160 */
|
||||
ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq1);
|
||||
}
|
||||
|
||||
if (chan && chan->flags & IEEE80211_CHAN_RADAR)
|
||||
flags |= WMI_CHAN_FLAG_DFS_CFREQ2;
|
||||
|
||||
ch->min_power = arg->min_power;
|
||||
ch->max_power = arg->max_power;
|
||||
ch->reg_power = arg->max_reg_power;
|
||||
@ -7165,7 +7193,7 @@ ath10k_wmi_op_gen_vdev_start(struct ath10k *ar,
|
||||
memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
|
||||
}
|
||||
|
||||
ath10k_wmi_put_wmi_channel(&cmd->chan, &arg->channel);
|
||||
ath10k_wmi_put_wmi_channel(ar, &cmd->chan, &arg->channel);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, ch_flags: 0x%0X, max_power: %d\n",
|
||||
@ -7537,7 +7565,7 @@ ath10k_wmi_op_gen_scan_chan_list(struct ath10k *ar,
|
||||
ch = &arg->channels[i];
|
||||
ci = &cmd->chan_info[i];
|
||||
|
||||
ath10k_wmi_put_wmi_channel(ci, ch);
|
||||
ath10k_wmi_put_wmi_channel(ar, ci, ch);
|
||||
}
|
||||
|
||||
return skb;
|
||||
@ -7628,12 +7656,8 @@ ath10k_wmi_peer_assoc_fill_10_4(struct ath10k *ar, void *buf,
|
||||
struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf;
|
||||
|
||||
ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg);
|
||||
if (arg->peer_bw_rxnss_override)
|
||||
cmd->peer_bw_rxnss_override =
|
||||
__cpu_to_le32((arg->peer_bw_rxnss_override - 1) |
|
||||
BIT(PEER_BW_RXNSS_OVERRIDE_OFFSET));
|
||||
else
|
||||
cmd->peer_bw_rxnss_override = 0;
|
||||
cmd->peer_bw_rxnss_override =
|
||||
__cpu_to_le32(arg->peer_bw_rxnss_override);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -8945,7 +8969,7 @@ ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar,
|
||||
|
||||
for (i = 0; i < cap->peer_chan_len; i++) {
|
||||
chan = (struct wmi_channel *)&peer_cap->peer_chan_list[i];
|
||||
ath10k_wmi_put_wmi_channel(chan, &chan_arg[i]);
|
||||
ath10k_wmi_put_wmi_channel(ar, chan, &chan_arg[i]);
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
|
@ -2094,7 +2094,8 @@ enum wmi_channel_change_cause {
|
||||
|
||||
/* Indicate reason for channel switch */
|
||||
#define WMI_CHANNEL_CHANGE_CAUSE_CSA (1 << 13)
|
||||
|
||||
/* DFS required on channel for 2nd segment of VHT160 and VHT80+80*/
|
||||
#define WMI_CHAN_FLAG_DFS_CFREQ2 (1 << 15)
|
||||
#define WMI_MAX_SPATIAL_STREAM 3 /* default max ss */
|
||||
|
||||
/* HT Capabilities*/
|
||||
@ -6508,7 +6509,10 @@ struct wmi_10_2_peer_assoc_complete_cmd {
|
||||
__le32 info0; /* WMI_PEER_ASSOC_INFO0_ */
|
||||
} __packed;
|
||||
|
||||
#define PEER_BW_RXNSS_OVERRIDE_OFFSET 31
|
||||
/* NSS Mapping to FW */
|
||||
#define WMI_PEER_NSS_MAP_ENABLE BIT(31)
|
||||
#define WMI_PEER_NSS_160MHZ_MASK GENMASK(2, 0)
|
||||
#define WMI_PEER_NSS_80_80MHZ_MASK GENMASK(5, 3)
|
||||
|
||||
struct wmi_10_4_peer_assoc_complete_cmd {
|
||||
struct wmi_10_2_peer_assoc_complete_cmd cmd;
|
||||
@ -7348,7 +7352,7 @@ void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn,
|
||||
const struct wmi_start_scan_arg *arg);
|
||||
void ath10k_wmi_set_wmm_param(struct wmi_wmm_params *params,
|
||||
const struct wmi_wmm_params_arg *arg);
|
||||
void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
|
||||
void ath10k_wmi_put_wmi_channel(struct ath10k *ar, struct wmi_channel *ch,
|
||||
const struct wmi_channel_arg *arg);
|
||||
int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg);
|
||||
|
||||
|
@ -788,7 +788,7 @@ static int ath11k_ahb_ext_irq_config(struct ath11k_base *ab)
|
||||
irq = platform_get_irq_byname(ab->pdev,
|
||||
irq_name[irq_idx]);
|
||||
ab->irq_num[irq_idx] = irq;
|
||||
irq_set_status_flags(irq, IRQ_NOAUTOEN);
|
||||
irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY);
|
||||
ret = request_irq(irq, ath11k_ahb_ext_interrupt_handler,
|
||||
IRQF_TRIGGER_RISING,
|
||||
irq_name[irq_idx], irq_grp);
|
||||
|
@ -341,6 +341,11 @@ struct ath11k_sta {
|
||||
u8 rssi_comb;
|
||||
struct ath11k_htt_tx_stats *tx_stats;
|
||||
struct ath11k_rx_peer_stats *rx_stats;
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
/* protected by conf_mutex */
|
||||
bool aggr_mode;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define ATH11K_NUM_CHANS 41
|
||||
@ -650,6 +655,7 @@ struct ath11k_base {
|
||||
/* protected by data_lock */
|
||||
u32 fw_crash_counter;
|
||||
} stats;
|
||||
u32 pktlog_defs_checksum;
|
||||
};
|
||||
|
||||
struct ath11k_fw_stats_pdev {
|
||||
|
@ -112,6 +112,12 @@ enum ath11k_pktlog_enum {
|
||||
ATH11K_PKTLOG_TYPE_LITE_RX = 24,
|
||||
};
|
||||
|
||||
enum ath11k_dbg_aggr_mode {
|
||||
ATH11K_DBG_AGGR_MODE_AUTO,
|
||||
ATH11K_DBG_AGGR_MODE_MANUAL,
|
||||
ATH11K_DBG_AGGR_MODE_MAX,
|
||||
};
|
||||
|
||||
__printf(2, 3) void ath11k_info(struct ath11k_base *ab, const char *fmt, ...);
|
||||
__printf(2, 3) void ath11k_err(struct ath11k_base *ab, const char *fmt, ...);
|
||||
__printf(2, 3) void ath11k_warn(struct ath11k_base *ab, const char *fmt, ...);
|
||||
|
@ -533,6 +533,222 @@ static const struct file_operations fops_peer_pktlog = {
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath11k_dbg_sta_write_delba(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ieee80211_sta *sta = file->private_data;
|
||||
struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
struct ath11k *ar = arsta->arvif->ar;
|
||||
u32 tid, initiator, reason;
|
||||
int ret;
|
||||
char buf[64] = {0};
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
|
||||
user_buf, count);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
|
||||
if (ret != 3)
|
||||
return -EINVAL;
|
||||
|
||||
/* Valid TID values are 0 through 15 */
|
||||
if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
if (ar->state != ATH11K_STATE_ON ||
|
||||
arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
|
||||
ret = count;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ath11k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
|
||||
tid, initiator, reason);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
|
||||
arsta->arvif->vdev_id, sta->addr, tid, initiator,
|
||||
reason);
|
||||
}
|
||||
ret = count;
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_delba = {
|
||||
.write = ath11k_dbg_sta_write_delba,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath11k_dbg_sta_write_addba_resp(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ieee80211_sta *sta = file->private_data;
|
||||
struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
struct ath11k *ar = arsta->arvif->ar;
|
||||
u32 tid, status;
|
||||
int ret;
|
||||
char buf[64] = {0};
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
|
||||
user_buf, count);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
ret = sscanf(buf, "%u %u", &tid, &status);
|
||||
if (ret != 2)
|
||||
return -EINVAL;
|
||||
|
||||
/* Valid TID values are 0 through 15 */
|
||||
if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
if (ar->state != ATH11K_STATE_ON ||
|
||||
arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
|
||||
ret = count;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ath11k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
|
||||
tid, status);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
|
||||
arsta->arvif->vdev_id, sta->addr, tid, status);
|
||||
}
|
||||
ret = count;
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_addba_resp = {
|
||||
.write = ath11k_dbg_sta_write_addba_resp,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath11k_dbg_sta_write_addba(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ieee80211_sta *sta = file->private_data;
|
||||
struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
struct ath11k *ar = arsta->arvif->ar;
|
||||
u32 tid, buf_size;
|
||||
int ret;
|
||||
char buf[64] = {0};
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
|
||||
user_buf, count);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
ret = sscanf(buf, "%u %u", &tid, &buf_size);
|
||||
if (ret != 2)
|
||||
return -EINVAL;
|
||||
|
||||
/* Valid TID values are 0 through 15 */
|
||||
if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
if (ar->state != ATH11K_STATE_ON ||
|
||||
arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
|
||||
ret = count;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ath11k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
|
||||
tid, buf_size);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
|
||||
arsta->arvif->vdev_id, sta->addr, tid, buf_size);
|
||||
}
|
||||
|
||||
ret = count;
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_addba = {
|
||||
.write = ath11k_dbg_sta_write_addba,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath11k_dbg_sta_read_aggr_mode(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ieee80211_sta *sta = file->private_data;
|
||||
struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
struct ath11k *ar = arsta->arvif->ar;
|
||||
char buf[64];
|
||||
int len = 0;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
len = scnprintf(buf, sizeof(buf) - len,
|
||||
"aggregation mode: %s\n\n%s\n%s\n",
|
||||
(arsta->aggr_mode == ATH11K_DBG_AGGR_MODE_AUTO) ?
|
||||
"auto" : "manual", "auto = 0", "manual = 1");
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t ath11k_dbg_sta_write_aggr_mode(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ieee80211_sta *sta = file->private_data;
|
||||
struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
struct ath11k *ar = arsta->arvif->ar;
|
||||
u32 aggr_mode;
|
||||
int ret;
|
||||
|
||||
if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
|
||||
return -EINVAL;
|
||||
|
||||
if (aggr_mode >= ATH11K_DBG_AGGR_MODE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
if (ar->state != ATH11K_STATE_ON ||
|
||||
aggr_mode == arsta->aggr_mode) {
|
||||
ret = count;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ath11k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to clear addba session ret: %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
arsta->aggr_mode = aggr_mode;
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_aggr_mode = {
|
||||
.read = ath11k_dbg_sta_read_aggr_mode,
|
||||
.write = ath11k_dbg_sta_write_aggr_mode,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
void ath11k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, struct dentry *dir)
|
||||
{
|
||||
@ -550,4 +766,9 @@ void ath11k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
|
||||
debugfs_create_file("peer_pktlog", 0644, dir, sta,
|
||||
&fops_peer_pktlog);
|
||||
|
||||
debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode);
|
||||
debugfs_create_file("addba", 0200, dir, sta, &fops_addba);
|
||||
debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp);
|
||||
debugfs_create_file("delba", 0200, dir, sta, &fops_delba);
|
||||
}
|
||||
|
@ -169,8 +169,8 @@ struct ath11k_pdev_dp {
|
||||
|
||||
#define DP_WBM_RELEASE_RING_SIZE 64
|
||||
#define DP_TCL_DATA_RING_SIZE 512
|
||||
#define DP_TX_COMP_RING_SIZE 8192
|
||||
#define DP_TX_IDR_SIZE (DP_TX_COMP_RING_SIZE << 1)
|
||||
#define DP_TX_COMP_RING_SIZE 32768
|
||||
#define DP_TX_IDR_SIZE DP_TX_COMP_RING_SIZE
|
||||
#define DP_TCL_CMD_RING_SIZE 32
|
||||
#define DP_TCL_STATUS_RING_SIZE 32
|
||||
#define DP_REO_DST_RING_MAX 4
|
||||
|
@ -1491,7 +1491,8 @@ static void ath11k_htt_pktlog(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
return;
|
||||
}
|
||||
|
||||
trace_ath11k_htt_pktlog(ar, data->payload, hdr->size);
|
||||
trace_ath11k_htt_pktlog(ar, data->payload, hdr->size,
|
||||
ar->ab->pktlog_defs_checksum);
|
||||
}
|
||||
|
||||
static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab,
|
||||
@ -2402,12 +2403,12 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
|
||||
|
||||
try_again:
|
||||
while ((rx_desc = ath11k_hal_srng_dst_get_next_entry(ab, srng))) {
|
||||
struct hal_reo_dest_ring *desc = (struct hal_reo_dest_ring *)rx_desc;
|
||||
struct hal_reo_dest_ring desc = *(struct hal_reo_dest_ring *)rx_desc;
|
||||
enum hal_reo_dest_ring_push_reason push_reason;
|
||||
u32 cookie;
|
||||
|
||||
cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
|
||||
desc->buf_addr_info.info1);
|
||||
desc.buf_addr_info.info1);
|
||||
buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,
|
||||
cookie);
|
||||
mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
|
||||
@ -2435,7 +2436,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
|
||||
total_msdu_reaped++;
|
||||
|
||||
push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
|
||||
desc->info0);
|
||||
desc.info0);
|
||||
if (push_reason !=
|
||||
HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
@ -2443,15 +2444,15 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
|
||||
continue;
|
||||
}
|
||||
|
||||
rxcb->is_first_msdu = !!(desc->rx_msdu_info.info0 &
|
||||
rxcb->is_first_msdu = !!(desc.rx_msdu_info.info0 &
|
||||
RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
|
||||
rxcb->is_last_msdu = !!(desc->rx_msdu_info.info0 &
|
||||
rxcb->is_last_msdu = !!(desc.rx_msdu_info.info0 &
|
||||
RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
|
||||
rxcb->is_continuation = !!(desc->rx_msdu_info.info0 &
|
||||
rxcb->is_continuation = !!(desc.rx_msdu_info.info0 &
|
||||
RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
|
||||
rxcb->mac_id = mac_id;
|
||||
rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
|
||||
desc->info0);
|
||||
desc.info0);
|
||||
|
||||
__skb_queue_tail(&msdu_list, msdu);
|
||||
|
||||
|
@ -599,7 +599,7 @@ struct hal_srng {
|
||||
/* Interrupt mitigation - timer threshold in us */
|
||||
#define HAL_SRNG_INT_TIMER_THRESHOLD_TX 1000
|
||||
#define HAL_SRNG_INT_TIMER_THRESHOLD_RX 500
|
||||
#define HAL_SRNG_INT_TIMER_THRESHOLD_OTHER 1000
|
||||
#define HAL_SRNG_INT_TIMER_THRESHOLD_OTHER 256
|
||||
|
||||
/* HW SRNG configuration table */
|
||||
struct hal_srng_config {
|
||||
|
@ -17,7 +17,26 @@ struct ath11k_peer *ath11k_peer_find(struct ath11k_base *ab, int vdev_id,
|
||||
list_for_each_entry(peer, &ab->peers, list) {
|
||||
if (peer->vdev_id != vdev_id)
|
||||
continue;
|
||||
if (memcmp(peer->addr, addr, ETH_ALEN))
|
||||
if (!ether_addr_equal(peer->addr, addr))
|
||||
continue;
|
||||
|
||||
return peer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct ath11k_peer *ath11k_peer_find_by_pdev_idx(struct ath11k_base *ab,
|
||||
u8 pdev_idx, const u8 *addr)
|
||||
{
|
||||
struct ath11k_peer *peer;
|
||||
|
||||
lockdep_assert_held(&ab->base_lock);
|
||||
|
||||
list_for_each_entry(peer, &ab->peers, list) {
|
||||
if (peer->pdev_idx != pdev_idx)
|
||||
continue;
|
||||
if (!ether_addr_equal(peer->addr, addr))
|
||||
continue;
|
||||
|
||||
return peer;
|
||||
@ -34,7 +53,7 @@ struct ath11k_peer *ath11k_peer_find_by_addr(struct ath11k_base *ab,
|
||||
lockdep_assert_held(&ab->base_lock);
|
||||
|
||||
list_for_each_entry(peer, &ab->peers, list) {
|
||||
if (memcmp(peer->addr, addr, ETH_ALEN))
|
||||
if (!ether_addr_equal(peer->addr, addr))
|
||||
continue;
|
||||
|
||||
return peer;
|
||||
@ -200,6 +219,17 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ar->ab->base_lock);
|
||||
peer = ath11k_peer_find_by_pdev_idx(ar->ab, ar->pdev_idx, param->peer_addr);
|
||||
if (peer) {
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
ath11k_info(ar->ab,
|
||||
"ignoring the peer %pM creation on same pdev idx %d\n",
|
||||
param->peer_addr, ar->pdev_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
|
||||
ret = ath11k_wmi_send_peer_create_cmd(ar, param);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab,
|
||||
@ -225,6 +255,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
peer->pdev_idx = ar->pdev_idx;
|
||||
peer->sta = sta;
|
||||
arvif->ast_hash = peer->ast_hash;
|
||||
|
||||
|
@ -13,6 +13,7 @@ struct ath11k_peer {
|
||||
u8 addr[ETH_ALEN];
|
||||
int peer_id;
|
||||
u16 ast_hash;
|
||||
u8 pdev_idx;
|
||||
|
||||
/* protected by ab->data_lock */
|
||||
struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
|
||||
|
@ -21,14 +21,16 @@ static inline void trace_ ## name(proto) {}
|
||||
#define TRACE_SYSTEM ath11k
|
||||
|
||||
TRACE_EVENT(ath11k_htt_pktlog,
|
||||
TP_PROTO(struct ath11k *ar, const void *buf, u16 buf_len),
|
||||
TP_PROTO(struct ath11k *ar, const void *buf, u16 buf_len,
|
||||
u32 pktlog_checksum),
|
||||
|
||||
TP_ARGS(ar, buf, buf_len),
|
||||
TP_ARGS(ar, buf, buf_len, pktlog_checksum),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(device, dev_name(ar->ab->dev))
|
||||
__string(driver, dev_driver_string(ar->ab->dev))
|
||||
__field(u16, buf_len)
|
||||
__field(u32, pktlog_checksum)
|
||||
__dynamic_array(u8, pktlog, buf_len)
|
||||
),
|
||||
|
||||
@ -36,14 +38,16 @@ TRACE_EVENT(ath11k_htt_pktlog,
|
||||
__assign_str(device, dev_name(ar->ab->dev));
|
||||
__assign_str(driver, dev_driver_string(ar->ab->dev));
|
||||
__entry->buf_len = buf_len;
|
||||
__entry->pktlog_checksum = pktlog_checksum;
|
||||
memcpy(__get_dynamic_array(pktlog), buf, buf_len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s %s size %hu",
|
||||
"%s %s size %hu pktlog_checksum %d",
|
||||
__get_str(driver),
|
||||
__get_str(device),
|
||||
__entry->buf_len
|
||||
__entry->buf_len,
|
||||
__entry->pktlog_checksum
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -87,8 +87,8 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = {
|
||||
= { .min_len = sizeof(struct wmi_pdev_bss_chan_info_event) },
|
||||
[WMI_TAG_VDEV_INSTALL_KEY_COMPLETE_EVENT]
|
||||
= { .min_len = sizeof(struct wmi_vdev_install_key_compl_event) },
|
||||
[WMI_TAG_READY_EVENT]
|
||||
= {.min_len = sizeof(struct wmi_ready_event) },
|
||||
[WMI_TAG_READY_EVENT] = {
|
||||
.min_len = sizeof(struct wmi_ready_event_min) },
|
||||
[WMI_TAG_SERVICE_AVAILABLE_EVENT]
|
||||
= {.min_len = sizeof(struct wmi_service_available_event) },
|
||||
[WMI_TAG_PEER_ASSOC_CONF_EVENT]
|
||||
@ -2368,6 +2368,146 @@ int ath11k_wmi_send_dfs_phyerr_offload_enable_cmd(struct ath11k *ar,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_delba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac,
|
||||
u32 tid, u32 initiator, u32 reason)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct wmi_delba_send_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_delba_send_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DELBA_SEND_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
cmd->vdev_id = vdev_id;
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, mac);
|
||||
cmd->tid = tid;
|
||||
cmd->initiator = initiator;
|
||||
cmd->reasoncode = reason;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"wmi delba send vdev_id 0x%X mac_addr %pM tid %u initiator %u reason %u\n",
|
||||
vdev_id, mac, tid, initiator, reason);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_DELBA_SEND_CMDID);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab,
|
||||
"failed to send WMI_DELBA_SEND_CMDID cmd\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_addba_set_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac,
|
||||
u32 tid, u32 status)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct wmi_addba_setresponse_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_addba_setresponse_cmd *)skb->data;
|
||||
cmd->tlv_header =
|
||||
FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_SETRESPONSE_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
cmd->vdev_id = vdev_id;
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, mac);
|
||||
cmd->tid = tid;
|
||||
cmd->statuscode = status;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"wmi addba set resp vdev_id 0x%X mac_addr %pM tid %u status %u\n",
|
||||
vdev_id, mac, tid, status);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_SET_RESP_CMDID);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab,
|
||||
"failed to send WMI_ADDBA_SET_RESP_CMDID cmd\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_addba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac,
|
||||
u32 tid, u32 buf_size)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct wmi_addba_send_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_addba_send_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_SEND_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
cmd->vdev_id = vdev_id;
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, mac);
|
||||
cmd->tid = tid;
|
||||
cmd->buffersize = buf_size;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"wmi addba send vdev_id 0x%X mac_addr %pM tid %u bufsize %u\n",
|
||||
vdev_id, mac, tid, buf_size);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_SEND_CMDID);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab,
|
||||
"failed to send WMI_ADDBA_SEND_CMDID cmd\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_addba_clear_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct wmi_addba_clear_resp_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_addba_clear_resp_cmd *)skb->data;
|
||||
cmd->tlv_header =
|
||||
FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_CLEAR_RESP_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
cmd->vdev_id = vdev_id;
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, mac);
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"wmi addba clear resp vdev_id 0x%X mac_addr %pM\n",
|
||||
vdev_id, mac);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_CLEAR_RESP_CMDID);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab,
|
||||
"failed to send WMI_ADDBA_CLEAR_RESP_CMDID cmd\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_pdev_peer_pktlog_filter(struct ath11k *ar, u8 *addr, u8 enable)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
@ -2779,7 +2919,7 @@ int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id,
|
||||
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");
|
||||
ath11k_warn(ab, "Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
return ret;
|
||||
@ -3105,7 +3245,7 @@ int ath11k_wmi_cmd_init(struct ath11k_base *ab)
|
||||
config.beacon_tx_offload_max_vdev = ab->num_radios * TARGET_MAX_BCN_OFFLD;
|
||||
config.rx_batchmode = TARGET_RX_BATCHMODE;
|
||||
config.peer_map_unmap_v2_support = 1;
|
||||
config.twt_ap_pdev_count = 2;
|
||||
config.twt_ap_pdev_count = ab->num_radios;
|
||||
config.twt_ap_sta_count = 1000;
|
||||
|
||||
memcpy(&wmi_sc->wlan_resource_config, &config, sizeof(config));
|
||||
@ -3740,8 +3880,9 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id,
|
||||
|
||||
ieee80211_tx_status_irqsafe(ar->hw, msdu);
|
||||
|
||||
WARN_ON_ONCE(atomic_read(&ar->num_pending_mgmt_tx) == 0);
|
||||
atomic_dec(&ar->num_pending_mgmt_tx);
|
||||
/* WARN when we received this event without doing any mgmt tx */
|
||||
if (atomic_dec_if_positive(&ar->num_pending_mgmt_tx) < 0)
|
||||
WARN_ON_ONCE(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -4851,7 +4992,7 @@ static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len,
|
||||
const void *ptr, void *data)
|
||||
{
|
||||
struct wmi_tlv_rdy_parse *rdy_parse = data;
|
||||
struct wmi_ready_event *fixed_param;
|
||||
struct wmi_ready_event fixed_param;
|
||||
struct wmi_mac_addr *addr_list;
|
||||
struct ath11k_pdev *pdev;
|
||||
u32 num_mac_addr;
|
||||
@ -4859,11 +5000,16 @@ static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len,
|
||||
|
||||
switch (tag) {
|
||||
case WMI_TAG_READY_EVENT:
|
||||
fixed_param = (struct wmi_ready_event *)ptr;
|
||||
ab->wlan_init_status = fixed_param->status;
|
||||
rdy_parse->num_extra_mac_addr = fixed_param->num_extra_mac_addr;
|
||||
memset(&fixed_param, 0, sizeof(fixed_param));
|
||||
memcpy(&fixed_param, (struct wmi_ready_event *)ptr,
|
||||
min_t(u16, sizeof(fixed_param), len));
|
||||
ab->wlan_init_status = fixed_param.ready_event_min.status;
|
||||
rdy_parse->num_extra_mac_addr =
|
||||
fixed_param.ready_event_min.num_extra_mac_addr;
|
||||
|
||||
ether_addr_copy(ab->mac_addr, fixed_param->mac_addr.addr);
|
||||
ether_addr_copy(ab->mac_addr,
|
||||
fixed_param.ready_event_min.mac_addr.addr);
|
||||
ab->pktlog_defs_checksum = fixed_param.pktlog_defs_checksum;
|
||||
ab->wmi_ready = true;
|
||||
break;
|
||||
case WMI_TAG_ARRAY_FIXED_STRUCT:
|
||||
|
@ -2345,7 +2345,7 @@ struct wmi_mac_addr {
|
||||
} __packed;
|
||||
} __packed;
|
||||
|
||||
struct wmi_ready_event {
|
||||
struct wmi_ready_event_min {
|
||||
struct wmi_abi_version fw_abi_vers;
|
||||
struct wmi_mac_addr mac_addr;
|
||||
u32 status;
|
||||
@ -2355,6 +2355,12 @@ struct wmi_ready_event {
|
||||
u32 num_extra_peers;
|
||||
} __packed;
|
||||
|
||||
struct wmi_ready_event {
|
||||
struct wmi_ready_event_min ready_event_min;
|
||||
u32 max_ast_index;
|
||||
u32 pktlog_defs_checksum;
|
||||
} __packed;
|
||||
|
||||
struct wmi_service_available_event {
|
||||
u32 wmi_service_segment_offset;
|
||||
u32 wmi_service_segment_bitmap[WMI_SERVICE_SEGMENT_BM_SIZE32];
|
||||
@ -3649,6 +3655,37 @@ struct wmi_therm_throt_level_config_info {
|
||||
u32 prio;
|
||||
} __packed;
|
||||
|
||||
struct wmi_delba_send_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
u32 tid;
|
||||
u32 initiator;
|
||||
u32 reasoncode;
|
||||
} __packed;
|
||||
|
||||
struct wmi_addba_setresponse_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
u32 tid;
|
||||
u32 statuscode;
|
||||
} __packed;
|
||||
|
||||
struct wmi_addba_send_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
u32 tid;
|
||||
u32 buffersize;
|
||||
} __packed;
|
||||
|
||||
struct wmi_addba_clear_resp_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
} __packed;
|
||||
|
||||
struct wmi_pdev_pktlog_filter_info {
|
||||
u32 tlv_header;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
@ -4822,6 +4859,13 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar,
|
||||
struct scan_chan_list_params *chan_list);
|
||||
int ath11k_wmi_send_dfs_phyerr_offload_enable_cmd(struct ath11k *ar,
|
||||
u32 pdev_id);
|
||||
int ath11k_wmi_addba_clear_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac);
|
||||
int ath11k_wmi_addba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac,
|
||||
u32 tid, u32 buf_size);
|
||||
int ath11k_wmi_addba_set_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac,
|
||||
u32 tid, u32 status);
|
||||
int ath11k_wmi_delba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac,
|
||||
u32 tid, u32 initiator, u32 reason);
|
||||
int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
|
||||
u32 vdev_id, u32 bcn_ctrl_op);
|
||||
int
|
||||
|
@ -612,6 +612,11 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
|
||||
hif_dev->remain_skb = nskb;
|
||||
spin_unlock(&hif_dev->rx_lock);
|
||||
} else {
|
||||
if (pool_index == MAX_PKT_NUM_IN_TRANSFER) {
|
||||
dev_err(&hif_dev->udev->dev,
|
||||
"ath9k_htc: over RX MAX_PKT_NUM\n");
|
||||
goto err;
|
||||
}
|
||||
nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
|
||||
if (!nskb) {
|
||||
dev_err(&hif_dev->udev->dev,
|
||||
@ -638,9 +643,9 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
|
||||
|
||||
static void ath9k_hif_usb_rx_cb(struct urb *urb)
|
||||
{
|
||||
struct sk_buff *skb = (struct sk_buff *) urb->context;
|
||||
struct hif_device_usb *hif_dev =
|
||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
|
||||
struct hif_device_usb *hif_dev = rx_buf->hif_dev;
|
||||
struct sk_buff *skb = rx_buf->skb;
|
||||
int ret;
|
||||
|
||||
if (!skb)
|
||||
@ -680,14 +685,15 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
|
||||
return;
|
||||
free:
|
||||
kfree_skb(skb);
|
||||
kfree(rx_buf);
|
||||
}
|
||||
|
||||
static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
|
||||
{
|
||||
struct sk_buff *skb = (struct sk_buff *) urb->context;
|
||||
struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
|
||||
struct hif_device_usb *hif_dev = rx_buf->hif_dev;
|
||||
struct sk_buff *skb = rx_buf->skb;
|
||||
struct sk_buff *nskb;
|
||||
struct hif_device_usb *hif_dev =
|
||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
int ret;
|
||||
|
||||
if (!skb)
|
||||
@ -745,6 +751,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
|
||||
return;
|
||||
free:
|
||||
kfree_skb(skb);
|
||||
kfree(rx_buf);
|
||||
urb->context = NULL;
|
||||
}
|
||||
|
||||
@ -790,7 +797,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
|
||||
init_usb_anchor(&hif_dev->mgmt_submitted);
|
||||
|
||||
for (i = 0; i < MAX_TX_URB_NUM; i++) {
|
||||
tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
|
||||
tx_buf = kzalloc(sizeof(*tx_buf), GFP_KERNEL);
|
||||
if (!tx_buf)
|
||||
goto err;
|
||||
|
||||
@ -827,8 +834,9 @@ static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
|
||||
|
||||
static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
|
||||
{
|
||||
struct urb *urb = NULL;
|
||||
struct rx_buf *rx_buf = NULL;
|
||||
struct sk_buff *skb = NULL;
|
||||
struct urb *urb = NULL;
|
||||
int i, ret;
|
||||
|
||||
init_usb_anchor(&hif_dev->rx_submitted);
|
||||
@ -836,6 +844,12 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
|
||||
|
||||
for (i = 0; i < MAX_RX_URB_NUM; i++) {
|
||||
|
||||
rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL);
|
||||
if (!rx_buf) {
|
||||
ret = -ENOMEM;
|
||||
goto err_rxb;
|
||||
}
|
||||
|
||||
/* Allocate URB */
|
||||
urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (urb == NULL) {
|
||||
@ -850,11 +864,14 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
|
||||
goto err_skb;
|
||||
}
|
||||
|
||||
rx_buf->hif_dev = hif_dev;
|
||||
rx_buf->skb = skb;
|
||||
|
||||
usb_fill_bulk_urb(urb, hif_dev->udev,
|
||||
usb_rcvbulkpipe(hif_dev->udev,
|
||||
USB_WLAN_RX_PIPE),
|
||||
skb->data, MAX_RX_BUF_SIZE,
|
||||
ath9k_hif_usb_rx_cb, skb);
|
||||
ath9k_hif_usb_rx_cb, rx_buf);
|
||||
|
||||
/* Anchor URB */
|
||||
usb_anchor_urb(urb, &hif_dev->rx_submitted);
|
||||
@ -880,6 +897,8 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
|
||||
err_skb:
|
||||
usb_free_urb(urb);
|
||||
err_urb:
|
||||
kfree(rx_buf);
|
||||
err_rxb:
|
||||
ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
|
||||
return ret;
|
||||
}
|
||||
@ -891,14 +910,21 @@ static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev)
|
||||
|
||||
static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
|
||||
{
|
||||
struct urb *urb = NULL;
|
||||
struct rx_buf *rx_buf = NULL;
|
||||
struct sk_buff *skb = NULL;
|
||||
struct urb *urb = NULL;
|
||||
int i, ret;
|
||||
|
||||
init_usb_anchor(&hif_dev->reg_in_submitted);
|
||||
|
||||
for (i = 0; i < MAX_REG_IN_URB_NUM; i++) {
|
||||
|
||||
rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL);
|
||||
if (!rx_buf) {
|
||||
ret = -ENOMEM;
|
||||
goto err_rxb;
|
||||
}
|
||||
|
||||
/* Allocate URB */
|
||||
urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (urb == NULL) {
|
||||
@ -913,11 +939,14 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
|
||||
goto err_skb;
|
||||
}
|
||||
|
||||
rx_buf->hif_dev = hif_dev;
|
||||
rx_buf->skb = skb;
|
||||
|
||||
usb_fill_int_urb(urb, hif_dev->udev,
|
||||
usb_rcvintpipe(hif_dev->udev,
|
||||
USB_REG_IN_PIPE),
|
||||
skb->data, MAX_REG_IN_BUF_SIZE,
|
||||
ath9k_hif_usb_reg_in_cb, skb, 1);
|
||||
ath9k_hif_usb_reg_in_cb, rx_buf, 1);
|
||||
|
||||
/* Anchor URB */
|
||||
usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
|
||||
@ -943,6 +972,8 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
|
||||
err_skb:
|
||||
usb_free_urb(urb);
|
||||
err_urb:
|
||||
kfree(rx_buf);
|
||||
err_rxb:
|
||||
ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
|
||||
return ret;
|
||||
}
|
||||
@ -973,7 +1004,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
|
||||
void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
|
||||
{
|
||||
usb_kill_anchored_urbs(&hif_dev->regout_submitted);
|
||||
ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
|
||||
@ -1341,8 +1372,9 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
|
||||
|
||||
if (hif_dev->flags & HIF_USB_READY) {
|
||||
ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
|
||||
ath9k_htc_hw_free(hif_dev->htc_handle);
|
||||
ath9k_hif_usb_dev_deinit(hif_dev);
|
||||
ath9k_destoy_wmi(hif_dev->htc_handle->drv_priv);
|
||||
ath9k_htc_hw_free(hif_dev->htc_handle);
|
||||
}
|
||||
|
||||
usb_set_intfdata(interface, NULL);
|
||||
|
@ -86,6 +86,11 @@ struct tx_buf {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct rx_buf {
|
||||
struct sk_buff *skb;
|
||||
struct hif_device_usb *hif_dev;
|
||||
};
|
||||
|
||||
#define HIF_USB_TX_STOP BIT(0)
|
||||
#define HIF_USB_TX_FLUSH BIT(1)
|
||||
|
||||
@ -133,5 +138,6 @@ struct hif_device_usb {
|
||||
|
||||
int ath9k_hif_usb_init(void);
|
||||
void ath9k_hif_usb_exit(void);
|
||||
void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev);
|
||||
|
||||
#endif /* HTC_USB_H */
|
||||
|
@ -931,8 +931,9 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
|
||||
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
|
||||
u16 devid, char *product, u32 drv_info)
|
||||
{
|
||||
struct ieee80211_hw *hw;
|
||||
struct hif_device_usb *hif_dev;
|
||||
struct ath9k_htc_priv *priv;
|
||||
struct ieee80211_hw *hw;
|
||||
int ret;
|
||||
|
||||
hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops);
|
||||
@ -967,7 +968,10 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
|
||||
return 0;
|
||||
|
||||
err_init:
|
||||
ath9k_deinit_wmi(priv);
|
||||
ath9k_stop_wmi(priv);
|
||||
hif_dev = (struct hif_device_usb *)htc_handle->hif_dev;
|
||||
ath9k_hif_usb_dealloc_urbs(hif_dev);
|
||||
ath9k_destoy_wmi(priv);
|
||||
err_free:
|
||||
ieee80211_free_hw(hw);
|
||||
return ret;
|
||||
@ -982,7 +986,7 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
|
||||
htc_handle->drv_priv->ah->ah_flags |= AH_UNPLUGGED;
|
||||
|
||||
ath9k_deinit_device(htc_handle->drv_priv);
|
||||
ath9k_deinit_wmi(htc_handle->drv_priv);
|
||||
ath9k_stop_wmi(htc_handle->drv_priv);
|
||||
ieee80211_free_hw(htc_handle->drv_priv->hw);
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,9 @@ static void htc_process_conn_rsp(struct htc_target *target,
|
||||
|
||||
if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
|
||||
epid = svc_rspmsg->endpoint_id;
|
||||
if (epid < 0 || epid >= ENDPOINT_MAX)
|
||||
return;
|
||||
|
||||
service_id = be16_to_cpu(svc_rspmsg->service_id);
|
||||
max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
|
||||
endpoint = &target->endpoint[epid];
|
||||
@ -170,7 +173,6 @@ static int htc_config_pipe_credits(struct htc_target *target)
|
||||
time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
|
||||
if (!time_left) {
|
||||
dev_err(target->dev, "HTC credit config timeout\n");
|
||||
kfree_skb(skb);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -206,7 +208,6 @@ static int htc_setup_complete(struct htc_target *target)
|
||||
time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
|
||||
if (!time_left) {
|
||||
dev_err(target->dev, "HTC start timeout\n");
|
||||
kfree_skb(skb);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -279,7 +280,6 @@ int htc_connect_service(struct htc_target *target,
|
||||
if (!time_left) {
|
||||
dev_err(target->dev, "Service connection timeout for: %d\n",
|
||||
service_connreq->service_id);
|
||||
kfree_skb(skb);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -112,14 +112,17 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
|
||||
return wmi;
|
||||
}
|
||||
|
||||
void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
|
||||
void ath9k_stop_wmi(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
struct wmi *wmi = priv->wmi;
|
||||
|
||||
mutex_lock(&wmi->op_mutex);
|
||||
wmi->stopped = true;
|
||||
mutex_unlock(&wmi->op_mutex);
|
||||
}
|
||||
|
||||
void ath9k_destoy_wmi(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
kfree(priv->wmi);
|
||||
}
|
||||
|
||||
@ -336,7 +339,6 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
|
||||
ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n",
|
||||
wmi_cmd_to_name(cmd_id));
|
||||
mutex_unlock(&wmi->op_mutex);
|
||||
kfree_skb(skb);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,6 @@ struct wmi {
|
||||
};
|
||||
|
||||
struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
|
||||
void ath9k_deinit_wmi(struct ath9k_htc_priv *priv);
|
||||
int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
|
||||
enum htc_endpoint_id *wmi_ctrl_epid);
|
||||
int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
|
||||
@ -189,6 +188,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
|
||||
void ath9k_wmi_event_tasklet(unsigned long data);
|
||||
void ath9k_fatal_work(struct work_struct *work);
|
||||
void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv);
|
||||
void ath9k_stop_wmi(struct ath9k_htc_priv *priv);
|
||||
void ath9k_destoy_wmi(struct ath9k_htc_priv *priv);
|
||||
|
||||
#define WMI_CMD(_wmi_cmd) \
|
||||
do { \
|
||||
|
Loading…
Reference in New Issue
Block a user