Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for 4.10. Major changes: ath10k * add spectral scan support for QCA6174 and QCA9377 families * show used tx bitrate with 10.4 firmware wil6210 * add power save mode support * add abort scan functionality * add support settings retry limit for short frames
This commit is contained in:
commit
d5fb3a1380
|
@ -326,6 +326,7 @@ static const char *const ath10k_core_fw_feature_str[] = {
|
|||
[ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl",
|
||||
[ATH10K_FW_FEATURE_BTCOEX_PARAM] = "btcoex-param",
|
||||
[ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR] = "skip-null-func-war",
|
||||
[ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST] = "allows-mesh-bcast",
|
||||
};
|
||||
|
||||
static unsigned int ath10k_core_get_fw_feature_str(char *buf,
|
||||
|
@ -1536,7 +1537,7 @@ static void ath10k_core_restart(struct work_struct *work)
|
|||
switch (ar->state) {
|
||||
case ATH10K_STATE_ON:
|
||||
ar->state = ATH10K_STATE_RESTARTING;
|
||||
ath10k_hif_stop(ar);
|
||||
ath10k_halt(ar);
|
||||
ath10k_scan_finish(ar);
|
||||
ieee80211_restart_hw(ar->hw);
|
||||
break;
|
||||
|
@ -1857,7 +1858,7 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
|
|||
goto err_wmi_detach;
|
||||
}
|
||||
|
||||
status = ath10k_htt_tx_alloc(&ar->htt);
|
||||
status = ath10k_htt_tx_start(&ar->htt);
|
||||
if (status) {
|
||||
ath10k_err(ar, "failed to alloc htt tx: %d\n", status);
|
||||
goto err_wmi_detach;
|
||||
|
@ -2052,7 +2053,7 @@ void ath10k_core_stop(struct ath10k *ar)
|
|||
ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
|
||||
|
||||
ath10k_hif_stop(ar);
|
||||
ath10k_htt_tx_free(&ar->htt);
|
||||
ath10k_htt_tx_stop(&ar->htt);
|
||||
ath10k_htt_rx_free(&ar->htt);
|
||||
ath10k_wmi_detach(ar);
|
||||
}
|
||||
|
@ -2385,6 +2386,7 @@ void ath10k_core_destroy(struct ath10k *ar)
|
|||
destroy_workqueue(ar->workqueue_aux);
|
||||
|
||||
ath10k_debug_destroy(ar);
|
||||
ath10k_htt_tx_destroy(&ar->htt);
|
||||
ath10k_wmi_free_host_mem(ar);
|
||||
ath10k_mac_destroy(ar);
|
||||
}
|
||||
|
|
|
@ -337,6 +337,7 @@ struct ath10k_sta {
|
|||
u32 nss;
|
||||
u32 smps;
|
||||
u16 peer_id;
|
||||
struct rate_info txrate;
|
||||
|
||||
struct work_struct update_wk;
|
||||
|
||||
|
@ -561,6 +562,13 @@ enum ath10k_fw_features {
|
|||
*/
|
||||
ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR = 15,
|
||||
|
||||
/* Firmware allow other BSS mesh broadcast/multicast frames without
|
||||
* creating monitor interface. Appropriate rxfilters are programmed for
|
||||
* mesh vdev by firmware itself. This feature flags will be used for
|
||||
* not creating monitor vdev while configuring mesh node.
|
||||
*/
|
||||
ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST = 16,
|
||||
|
||||
/* keep last */
|
||||
ATH10K_FW_FEATURE_COUNT,
|
||||
};
|
||||
|
@ -692,6 +700,21 @@ struct ath10k_fw_components {
|
|||
struct ath10k_fw_file fw_file;
|
||||
};
|
||||
|
||||
struct ath10k_per_peer_tx_stats {
|
||||
u32 succ_bytes;
|
||||
u32 retry_bytes;
|
||||
u32 failed_bytes;
|
||||
u8 ratecode;
|
||||
u8 flags;
|
||||
u16 peer_id;
|
||||
u16 succ_pkts;
|
||||
u16 retry_pkts;
|
||||
u16 failed_pkts;
|
||||
u16 duration;
|
||||
u32 reserved1;
|
||||
u32 reserved2;
|
||||
};
|
||||
|
||||
struct ath10k {
|
||||
struct ath_common ath_common;
|
||||
struct ieee80211_hw *hw;
|
||||
|
@ -905,6 +928,7 @@ struct ath10k {
|
|||
|
||||
struct ath10k_thermal thermal;
|
||||
struct ath10k_wow wow;
|
||||
struct ath10k_per_peer_tx_stats peer_tx_stats;
|
||||
|
||||
/* NAPI */
|
||||
struct net_device napi_dev;
|
||||
|
|
|
@ -77,6 +77,19 @@ void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
|
||||
sinfo->rx_duration = arsta->rx_duration;
|
||||
sinfo->filled |= 1ULL << NL80211_STA_INFO_RX_DURATION;
|
||||
|
||||
if (!arsta->txrate.legacy && !arsta->txrate.nss)
|
||||
return;
|
||||
|
||||
if (arsta->txrate.legacy) {
|
||||
sinfo->txrate.legacy = arsta->txrate.legacy;
|
||||
} else {
|
||||
sinfo->txrate.mcs = arsta->txrate.mcs;
|
||||
sinfo->txrate.nss = arsta->txrate.nss;
|
||||
sinfo->txrate.bw = arsta->txrate.bw;
|
||||
}
|
||||
sinfo->txrate.flags = arsta->txrate.flags;
|
||||
sinfo->filled |= 1ULL << NL80211_STA_INFO_TX_BITRATE;
|
||||
}
|
||||
|
||||
static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file,
|
||||
|
|
|
@ -137,6 +137,8 @@ static const enum htt_t2h_msg_type htt_10_4_t2h_msg_types[] = {
|
|||
HTT_T2H_MSG_TYPE_STATS_NOUPLOAD,
|
||||
[HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND] =
|
||||
HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND,
|
||||
[HTT_10_4_T2H_MSG_TYPE_PEER_STATS] =
|
||||
HTT_T2H_MSG_TYPE_PEER_STATS,
|
||||
};
|
||||
|
||||
int ath10k_htt_connect(struct ath10k_htt *htt)
|
||||
|
|
|
@ -419,6 +419,7 @@ enum htt_10_4_t2h_msg_type {
|
|||
HTT_10_4_T2H_MSG_TYPE_STATS_NOUPLOAD = 0x18,
|
||||
/* 0x19 to 0x2f are reserved */
|
||||
HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND = 0x30,
|
||||
HTT_10_4_T2H_MSG_TYPE_PEER_STATS = 0x31,
|
||||
/* keep this last */
|
||||
HTT_10_4_T2H_NUM_MSGS
|
||||
};
|
||||
|
@ -453,6 +454,7 @@ enum htt_t2h_msg_type {
|
|||
HTT_T2H_MSG_TYPE_TX_FETCH_IND,
|
||||
HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM,
|
||||
HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND,
|
||||
HTT_T2H_MSG_TYPE_PEER_STATS,
|
||||
/* keep this last */
|
||||
HTT_T2H_NUM_MSGS
|
||||
};
|
||||
|
@ -1470,6 +1472,28 @@ struct htt_channel_change {
|
|||
__le32 phymode;
|
||||
} __packed;
|
||||
|
||||
struct htt_per_peer_tx_stats_ind {
|
||||
__le32 succ_bytes;
|
||||
__le32 retry_bytes;
|
||||
__le32 failed_bytes;
|
||||
u8 ratecode;
|
||||
u8 flags;
|
||||
__le16 peer_id;
|
||||
__le16 succ_pkts;
|
||||
__le16 retry_pkts;
|
||||
__le16 failed_pkts;
|
||||
__le16 tx_duration;
|
||||
__le32 reserved1;
|
||||
__le32 reserved2;
|
||||
} __packed;
|
||||
|
||||
struct htt_peer_tx_stats {
|
||||
u8 num_ppdu;
|
||||
u8 ppdu_len;
|
||||
u8 version;
|
||||
u8 payload[0];
|
||||
} __packed;
|
||||
|
||||
union htt_rx_pn_t {
|
||||
/* WEP: 24-bit PN */
|
||||
u32 pn24;
|
||||
|
@ -1521,6 +1545,7 @@ struct htt_resp {
|
|||
struct htt_tx_fetch_confirm tx_fetch_confirm;
|
||||
struct htt_tx_mode_switch_ind tx_mode_switch_ind;
|
||||
struct htt_channel_change chan_change;
|
||||
struct htt_peer_tx_stats peer_tx_stats;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
|
@ -1692,6 +1717,8 @@ struct ath10k_htt {
|
|||
enum htt_tx_mode_switch_mode mode;
|
||||
enum htt_q_depth_type type;
|
||||
} tx_q_state;
|
||||
|
||||
bool tx_mem_allocated;
|
||||
};
|
||||
|
||||
#define RX_HTT_HDR_STATUS_LEN 64
|
||||
|
@ -1754,7 +1781,9 @@ int ath10k_htt_connect(struct ath10k_htt *htt);
|
|||
int ath10k_htt_init(struct ath10k *ar);
|
||||
int ath10k_htt_setup(struct ath10k_htt *htt);
|
||||
|
||||
int ath10k_htt_tx_alloc(struct ath10k_htt *htt);
|
||||
int ath10k_htt_tx_start(struct ath10k_htt *htt);
|
||||
void ath10k_htt_tx_stop(struct ath10k_htt *htt);
|
||||
void ath10k_htt_tx_destroy(struct ath10k_htt *htt);
|
||||
void ath10k_htt_tx_free(struct ath10k_htt *htt);
|
||||
|
||||
int ath10k_htt_rx_alloc(struct ath10k_htt *htt);
|
||||
|
|
|
@ -2194,6 +2194,128 @@ void ath10k_htt_htc_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
|
|||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
|
||||
static inline bool is_valid_legacy_rate(u8 rate)
|
||||
{
|
||||
static const u8 legacy_rates[] = {1, 2, 5, 11, 6, 9, 12,
|
||||
18, 24, 36, 48, 54};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(legacy_rates); i++) {
|
||||
if (rate == legacy_rates[i])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
ath10k_update_per_peer_tx_stats(struct ath10k *ar,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ath10k_per_peer_tx_stats *peer_stats)
|
||||
{
|
||||
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
u8 rate = 0, sgi;
|
||||
struct rate_info txrate;
|
||||
|
||||
lockdep_assert_held(&ar->data_lock);
|
||||
|
||||
txrate.flags = ATH10K_HW_PREAMBLE(peer_stats->ratecode);
|
||||
txrate.bw = ATH10K_HW_BW(peer_stats->flags);
|
||||
txrate.nss = ATH10K_HW_NSS(peer_stats->ratecode);
|
||||
txrate.mcs = ATH10K_HW_MCS_RATE(peer_stats->ratecode);
|
||||
sgi = ATH10K_HW_GI(peer_stats->flags);
|
||||
|
||||
if (((txrate.flags == WMI_RATE_PREAMBLE_HT) ||
|
||||
(txrate.flags == WMI_RATE_PREAMBLE_VHT)) && txrate.mcs > 9) {
|
||||
ath10k_warn(ar, "Invalid mcs %hhd peer stats", txrate.mcs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (txrate.flags == WMI_RATE_PREAMBLE_CCK ||
|
||||
txrate.flags == WMI_RATE_PREAMBLE_OFDM) {
|
||||
rate = ATH10K_HW_LEGACY_RATE(peer_stats->ratecode);
|
||||
|
||||
if (!is_valid_legacy_rate(rate)) {
|
||||
ath10k_warn(ar, "Invalid legacy rate %hhd peer stats",
|
||||
rate);
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is hacky, FW sends CCK rate 5.5Mbps as 6 */
|
||||
rate *= 10;
|
||||
if (rate == 60 && txrate.flags == WMI_RATE_PREAMBLE_CCK)
|
||||
rate = rate - 5;
|
||||
arsta->txrate.legacy = rate * 10;
|
||||
} else if (txrate.flags == WMI_RATE_PREAMBLE_HT) {
|
||||
arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
|
||||
arsta->txrate.mcs = txrate.mcs;
|
||||
} else {
|
||||
arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
|
||||
arsta->txrate.mcs = txrate.mcs;
|
||||
}
|
||||
|
||||
if (sgi)
|
||||
arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
|
||||
arsta->txrate.nss = txrate.nss;
|
||||
arsta->txrate.bw = txrate.bw + RATE_INFO_BW_20;
|
||||
}
|
||||
|
||||
static void ath10k_htt_fetch_peer_stats(struct ath10k *ar,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct htt_resp *resp = (struct htt_resp *)skb->data;
|
||||
struct ath10k_per_peer_tx_stats *p_tx_stats = &ar->peer_tx_stats;
|
||||
struct htt_per_peer_tx_stats_ind *tx_stats;
|
||||
struct ieee80211_sta *sta;
|
||||
struct ath10k_peer *peer;
|
||||
int peer_id, i;
|
||||
u8 ppdu_len, num_ppdu;
|
||||
|
||||
num_ppdu = resp->peer_tx_stats.num_ppdu;
|
||||
ppdu_len = resp->peer_tx_stats.ppdu_len * sizeof(__le32);
|
||||
|
||||
if (skb->len < sizeof(struct htt_resp_hdr) + num_ppdu * ppdu_len) {
|
||||
ath10k_warn(ar, "Invalid peer stats buf length %d\n", skb->len);
|
||||
return;
|
||||
}
|
||||
|
||||
tx_stats = (struct htt_per_peer_tx_stats_ind *)
|
||||
(resp->peer_tx_stats.payload);
|
||||
peer_id = __le16_to_cpu(tx_stats->peer_id);
|
||||
|
||||
rcu_read_lock();
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
peer = ath10k_peer_find_by_id(ar, peer_id);
|
||||
if (!peer) {
|
||||
ath10k_warn(ar, "Invalid peer id %d peer stats buffer\n",
|
||||
peer_id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
sta = peer->sta;
|
||||
for (i = 0; i < num_ppdu; i++) {
|
||||
tx_stats = (struct htt_per_peer_tx_stats_ind *)
|
||||
(resp->peer_tx_stats.payload + i * ppdu_len);
|
||||
|
||||
p_tx_stats->succ_bytes = __le32_to_cpu(tx_stats->succ_bytes);
|
||||
p_tx_stats->retry_bytes = __le32_to_cpu(tx_stats->retry_bytes);
|
||||
p_tx_stats->failed_bytes =
|
||||
__le32_to_cpu(tx_stats->failed_bytes);
|
||||
p_tx_stats->ratecode = tx_stats->ratecode;
|
||||
p_tx_stats->flags = tx_stats->flags;
|
||||
p_tx_stats->succ_pkts = __le16_to_cpu(tx_stats->succ_pkts);
|
||||
p_tx_stats->retry_pkts = __le16_to_cpu(tx_stats->retry_pkts);
|
||||
p_tx_stats->failed_pkts = __le16_to_cpu(tx_stats->failed_pkts);
|
||||
|
||||
ath10k_update_per_peer_tx_stats(ar, sta, p_tx_stats);
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct ath10k_htt *htt = &ar->htt;
|
||||
|
@ -2354,6 +2476,9 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
|
|||
case HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND:
|
||||
ath10k_htt_rx_tx_mode_switch_ind(ar, skb);
|
||||
break;
|
||||
case HTT_T2H_MSG_TYPE_PEER_STATS:
|
||||
ath10k_htt_fetch_peer_stats(ar, skb);
|
||||
break;
|
||||
case HTT_T2H_MSG_TYPE_EN_STATS:
|
||||
default:
|
||||
ath10k_warn(ar, "htt event (%d) not handled\n",
|
||||
|
|
|
@ -350,21 +350,15 @@ static int ath10k_htt_tx_alloc_txdone_fifo(struct ath10k_htt *htt)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
|
||||
static int ath10k_htt_tx_alloc_buf(struct ath10k_htt *htt)
|
||||
{
|
||||
struct ath10k *ar = htt->ar;
|
||||
int ret;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n",
|
||||
htt->max_num_pending_tx);
|
||||
|
||||
spin_lock_init(&htt->tx_lock);
|
||||
idr_init(&htt->pending_tx);
|
||||
|
||||
ret = ath10k_htt_tx_alloc_cont_txbuf(htt);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to alloc cont tx buffer: %d\n", ret);
|
||||
goto free_idr_pending_tx;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath10k_htt_tx_alloc_cont_frag_desc(htt);
|
||||
|
@ -396,6 +390,31 @@ free_frag_desc:
|
|||
free_txbuf:
|
||||
ath10k_htt_tx_free_cont_txbuf(htt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath10k_htt_tx_start(struct ath10k_htt *htt)
|
||||
{
|
||||
struct ath10k *ar = htt->ar;
|
||||
int ret;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n",
|
||||
htt->max_num_pending_tx);
|
||||
|
||||
spin_lock_init(&htt->tx_lock);
|
||||
idr_init(&htt->pending_tx);
|
||||
|
||||
if (htt->tx_mem_allocated)
|
||||
return 0;
|
||||
|
||||
ret = ath10k_htt_tx_alloc_buf(htt);
|
||||
if (ret)
|
||||
goto free_idr_pending_tx;
|
||||
|
||||
htt->tx_mem_allocated = true;
|
||||
|
||||
return 0;
|
||||
|
||||
free_idr_pending_tx:
|
||||
idr_destroy(&htt->pending_tx);
|
||||
|
||||
|
@ -418,15 +437,28 @@ static int ath10k_htt_tx_clean_up_pending(int msdu_id, void *skb, void *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ath10k_htt_tx_free(struct ath10k_htt *htt)
|
||||
void ath10k_htt_tx_destroy(struct ath10k_htt *htt)
|
||||
{
|
||||
idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
|
||||
idr_destroy(&htt->pending_tx);
|
||||
if (!htt->tx_mem_allocated)
|
||||
return;
|
||||
|
||||
ath10k_htt_tx_free_cont_txbuf(htt);
|
||||
ath10k_htt_tx_free_txq(htt);
|
||||
ath10k_htt_tx_free_cont_frag_desc(htt);
|
||||
ath10k_htt_tx_free_txdone_fifo(htt);
|
||||
htt->tx_mem_allocated = false;
|
||||
}
|
||||
|
||||
void ath10k_htt_tx_stop(struct ath10k_htt *htt)
|
||||
{
|
||||
idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
|
||||
idr_destroy(&htt->pending_tx);
|
||||
}
|
||||
|
||||
void ath10k_htt_tx_free(struct ath10k_htt *htt)
|
||||
{
|
||||
ath10k_htt_tx_stop(htt);
|
||||
ath10k_htt_tx_destroy(htt);
|
||||
}
|
||||
|
||||
void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
|
||||
|
|
|
@ -1167,7 +1167,9 @@ static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
|
|||
return false;
|
||||
|
||||
return ar->monitor ||
|
||||
ar->filter_flags & FIF_OTHER_BSS ||
|
||||
(!test_bit(ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST,
|
||||
ar->running_fw->fw_file.fw_features) &&
|
||||
(ar->filter_flags & FIF_OTHER_BSS)) ||
|
||||
test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
|
||||
}
|
||||
|
||||
|
@ -4449,7 +4451,6 @@ static int ath10k_start(struct ieee80211_hw *hw)
|
|||
ar->state = ATH10K_STATE_ON;
|
||||
break;
|
||||
case ATH10K_STATE_RESTARTING:
|
||||
ath10k_halt(ar);
|
||||
ar->state = ATH10K_STATE_RESTARTED;
|
||||
break;
|
||||
case ATH10K_STATE_ON:
|
||||
|
@ -6976,40 +6977,28 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
|
|||
ieee80211_queue_work(hw, &arsta->update_wk);
|
||||
}
|
||||
|
||||
static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
{
|
||||
/*
|
||||
* FIXME: Return 0 for time being. Need to figure out whether FW
|
||||
* has the API to fetch 64-bit local TSF
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
u64 tsf)
|
||||
static void ath10k_offset_tsf(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif, s64 tsf_offset)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
|
||||
u32 tsf_offset, vdev_param = ar->wmi.vdev_param->set_tsf;
|
||||
u32 offset, vdev_param;
|
||||
int ret;
|
||||
|
||||
/* Workaround:
|
||||
*
|
||||
* Given tsf argument is entire TSF value, but firmware accepts
|
||||
* only TSF offset to current TSF.
|
||||
*
|
||||
* get_tsf function is used to get offset value, however since
|
||||
* ath10k_get_tsf is not implemented properly, it will return 0 always.
|
||||
* Luckily all the caller functions to set_tsf, as of now, also rely on
|
||||
* get_tsf function to get entire tsf value such get_tsf() + tsf_delta,
|
||||
* final tsf offset value to firmware will be arithmetically correct.
|
||||
*/
|
||||
tsf_offset = tsf - ath10k_get_tsf(hw, vif);
|
||||
if (tsf_offset < 0) {
|
||||
vdev_param = ar->wmi.vdev_param->dec_tsf;
|
||||
offset = -tsf_offset;
|
||||
} else {
|
||||
vdev_param = ar->wmi.vdev_param->inc_tsf;
|
||||
offset = tsf_offset;
|
||||
}
|
||||
|
||||
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
|
||||
vdev_param, tsf_offset);
|
||||
vdev_param, offset);
|
||||
|
||||
if (ret && ret != -EOPNOTSUPP)
|
||||
ath10k_warn(ar, "failed to set tsf offset: %d\n", ret);
|
||||
ath10k_warn(ar, "failed to set tsf offset %d cmd %d: %d\n",
|
||||
offset, vdev_param, ret);
|
||||
}
|
||||
|
||||
static int ath10k_ampdu_action(struct ieee80211_hw *hw,
|
||||
|
@ -7474,8 +7463,7 @@ static const struct ieee80211_ops ath10k_ops = {
|
|||
.get_survey = ath10k_get_survey,
|
||||
.set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
|
||||
.sta_rc_update = ath10k_sta_rc_update,
|
||||
.get_tsf = ath10k_get_tsf,
|
||||
.set_tsf = ath10k_set_tsf,
|
||||
.offset_tsf = ath10k_offset_tsf,
|
||||
.ampdu_action = ath10k_ampdu_action,
|
||||
.get_et_sset_count = ath10k_debug_get_et_sset_count,
|
||||
.get_et_stats = ath10k_debug_get_et_stats,
|
||||
|
@ -8005,6 +7993,7 @@ int ath10k_mac_register(struct ath10k *ar)
|
|||
ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
|
||||
ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
|
||||
ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
|
||||
ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
|
||||
|
||||
if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
|
||||
ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
|
||||
|
|
|
@ -660,6 +660,9 @@ ath10k_wmi_vdev_spectral_conf(struct ath10k *ar,
|
|||
struct sk_buff *skb;
|
||||
u32 cmd_id;
|
||||
|
||||
if (!ar->wmi.ops->gen_vdev_spectral_conf)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_spectral_conf(ar, arg);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
@ -675,6 +678,9 @@ ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger,
|
|||
struct sk_buff *skb;
|
||||
u32 cmd_id;
|
||||
|
||||
if (!ar->wmi.ops->gen_vdev_spectral_enable)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_spectral_enable(ar, vdev_id, trigger,
|
||||
enable);
|
||||
if (IS_ERR(skb))
|
||||
|
|
|
@ -1313,8 +1313,8 @@ ath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar,
|
|||
cmd->regd = __cpu_to_le32(rd);
|
||||
cmd->regd_2ghz = __cpu_to_le32(rd2g);
|
||||
cmd->regd_5ghz = __cpu_to_le32(rd5g);
|
||||
cmd->conform_limit_2ghz = __cpu_to_le32(rd2g);
|
||||
cmd->conform_limit_5ghz = __cpu_to_le32(rd5g);
|
||||
cmd->conform_limit_2ghz = __cpu_to_le32(ctl2g);
|
||||
cmd->conform_limit_5ghz = __cpu_to_le32(ctl5g);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n");
|
||||
return skb;
|
||||
|
@ -3136,6 +3136,76 @@ ath10k_wmi_tlv_op_gen_echo(struct ath10k *ar, u32 value)
|
|||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_tlv_op_gen_vdev_spectral_conf(struct ath10k *ar,
|
||||
const struct wmi_vdev_spectral_conf_arg *arg)
|
||||
{
|
||||
struct wmi_vdev_spectral_conf_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
struct wmi_tlv *tlv;
|
||||
void *ptr;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(*tlv) + sizeof(*cmd);
|
||||
skb = ath10k_wmi_alloc_skb(ar, len);
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ptr = (void *)skb->data;
|
||||
tlv = ptr;
|
||||
tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_CONFIGURE_CMD);
|
||||
tlv->len = __cpu_to_le16(sizeof(*cmd));
|
||||
cmd = (void *)tlv->value;
|
||||
cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
|
||||
cmd->scan_count = __cpu_to_le32(arg->scan_count);
|
||||
cmd->scan_period = __cpu_to_le32(arg->scan_period);
|
||||
cmd->scan_priority = __cpu_to_le32(arg->scan_priority);
|
||||
cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size);
|
||||
cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena);
|
||||
cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena);
|
||||
cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref);
|
||||
cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay);
|
||||
cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr);
|
||||
cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr);
|
||||
cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode);
|
||||
cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode);
|
||||
cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr);
|
||||
cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format);
|
||||
cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode);
|
||||
cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale);
|
||||
cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj);
|
||||
cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_tlv_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
|
||||
u32 trigger, u32 enable)
|
||||
{
|
||||
struct wmi_vdev_spectral_enable_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
struct wmi_tlv *tlv;
|
||||
void *ptr;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(*tlv) + sizeof(*cmd);
|
||||
skb = ath10k_wmi_alloc_skb(ar, len);
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ptr = (void *)skb->data;
|
||||
tlv = ptr;
|
||||
tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_ENABLE_CMD);
|
||||
tlv->len = __cpu_to_le16(sizeof(*cmd));
|
||||
cmd = (void *)tlv->value;
|
||||
cmd->vdev_id = __cpu_to_le32(vdev_id);
|
||||
cmd->trigger_cmd = __cpu_to_le32(trigger);
|
||||
cmd->enable_cmd = __cpu_to_le32(enable);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
/****************/
|
||||
/* TLV mappings */
|
||||
/****************/
|
||||
|
@ -3464,7 +3534,6 @@ static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = {
|
|||
.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static const struct wmi_ops wmi_tlv_ops = {
|
||||
|
@ -3542,6 +3611,8 @@ static const struct wmi_ops wmi_tlv_ops = {
|
|||
.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
.gen_echo = ath10k_wmi_tlv_op_gen_echo,
|
||||
.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
|
||||
.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
|
||||
};
|
||||
|
||||
static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
|
||||
|
|
|
@ -785,7 +785,6 @@ static struct wmi_vdev_param_map wmi_vdev_param_map = {
|
|||
.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* 10.X WMI VDEV param map */
|
||||
|
@ -861,7 +860,6 @@ static struct wmi_vdev_param_map wmi_10x_vdev_param_map = {
|
|||
.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
|
||||
|
@ -936,7 +934,6 @@ static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
|
|||
.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
|
||||
.set_tsf = WMI_10X_VDEV_PARAM_TSF_INCREMENT,
|
||||
};
|
||||
|
||||
static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = {
|
||||
|
@ -1012,7 +1009,8 @@ static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = {
|
|||
.meru_vc = WMI_10_4_VDEV_PARAM_MERU_VC,
|
||||
.rx_decap_type = WMI_10_4_VDEV_PARAM_RX_DECAP_TYPE,
|
||||
.bw_nss_ratemask = WMI_10_4_VDEV_PARAM_BW_NSS_RATEMASK,
|
||||
.set_tsf = WMI_10_4_VDEV_PARAM_TSF_INCREMENT,
|
||||
.inc_tsf = WMI_10_4_VDEV_PARAM_TSF_INCREMENT,
|
||||
.dec_tsf = WMI_10_4_VDEV_PARAM_TSF_DECREMENT,
|
||||
};
|
||||
|
||||
static struct wmi_pdev_param_map wmi_pdev_param_map = {
|
||||
|
@ -4489,7 +4487,7 @@ static int ath10k_wmi_alloc_chunk(struct ath10k *ar, u32 req_id,
|
|||
if (!num_units)
|
||||
return -ENOMEM;
|
||||
|
||||
paddr = dma_map_single(ar->dev, vaddr, pool_size, DMA_TO_DEVICE);
|
||||
paddr = dma_map_single(ar->dev, vaddr, pool_size, DMA_BIDIRECTIONAL);
|
||||
if (dma_mapping_error(ar->dev, paddr)) {
|
||||
kfree(vaddr);
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -4603,9 +4603,17 @@ enum wmi_rate_preamble {
|
|||
|
||||
#define ATH10K_HW_NSS(rate) (1 + (((rate) >> 4) & 0x3))
|
||||
#define ATH10K_HW_PREAMBLE(rate) (((rate) >> 6) & 0x3)
|
||||
#define ATH10K_HW_RATECODE(rate, nss, preamble) \
|
||||
#define ATH10K_HW_MCS_RATE(rate) ((rate) & 0xf)
|
||||
#define ATH10K_HW_LEGACY_RATE(rate) ((rate) & 0x3f)
|
||||
#define ATH10K_HW_BW(flags) (((flags) >> 3) & 0x3)
|
||||
#define ATH10K_HW_GI(flags) (((flags) >> 5) & 0x1)
|
||||
#define ATH10K_HW_RATECODE(rate, nss, preamble) \
|
||||
(((preamble) << 6) | ((nss) << 4) | (rate))
|
||||
|
||||
#define VHT_MCS_NUM 10
|
||||
#define VHT_BW_NUM 4
|
||||
#define VHT_NSS_NUM 4
|
||||
|
||||
/* Value to disable fixed rate setting */
|
||||
#define WMI_FIXED_RATE_NONE (0xff)
|
||||
|
||||
|
@ -4676,7 +4684,8 @@ struct wmi_vdev_param_map {
|
|||
u32 meru_vc;
|
||||
u32 rx_decap_type;
|
||||
u32 bw_nss_ratemask;
|
||||
u32 set_tsf;
|
||||
u32 inc_tsf;
|
||||
u32 dec_tsf;
|
||||
};
|
||||
|
||||
#define WMI_VDEV_PARAM_UNSUPPORTED 0
|
||||
|
@ -5009,6 +5018,11 @@ enum wmi_10_4_vdev_param {
|
|||
WMI_10_4_VDEV_PARAM_STA_KICKOUT,
|
||||
WMI_10_4_VDEV_PARAM_CAPABILITIES,
|
||||
WMI_10_4_VDEV_PARAM_TSF_INCREMENT,
|
||||
WMI_10_4_VDEV_PARAM_RX_FILTER,
|
||||
WMI_10_4_VDEV_PARAM_MGMT_TX_POWER,
|
||||
WMI_10_4_VDEV_PARAM_ATF_SSID_SCHED_POLICY,
|
||||
WMI_10_4_VDEV_PARAM_DISABLE_DYN_BW_RTS,
|
||||
WMI_10_4_VDEV_PARAM_TSF_DECREMENT,
|
||||
};
|
||||
|
||||
#define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0)
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include "debug.h"
|
||||
#include "ath5k.h"
|
||||
#include "reg.h"
|
||||
|
|
|
@ -62,7 +62,7 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
|
|||
return false;
|
||||
}
|
||||
|
||||
static struct ath_bus_ops ath_ahb_bus_ops = {
|
||||
static const struct ath_bus_ops ath_ahb_bus_ops = {
|
||||
.ath_bus_type = ATH_AHB,
|
||||
.read_cachesize = ath_ahb_read_cachesize,
|
||||
.eeprom_read = ath_ahb_eeprom_read,
|
||||
|
|
|
@ -528,6 +528,9 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h
|
|||
if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
|
||||
return 0;
|
||||
|
||||
if (!spec_priv->rfs_chan_spec_scan)
|
||||
return 1;
|
||||
|
||||
/* Output buffers are full, no need to process anything
|
||||
* since there is no space to put the result anyway
|
||||
*/
|
||||
|
@ -1072,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_scan_cb = {
|
|||
|
||||
void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS)) {
|
||||
if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) {
|
||||
relay_close(spec_priv->rfs_chan_spec_scan);
|
||||
spec_priv->rfs_chan_spec_scan = NULL;
|
||||
}
|
||||
|
@ -1086,6 +1089,9 @@ void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,
|
|||
debugfs_phy,
|
||||
1024, 256, &rfs_spec_scan_cb,
|
||||
NULL);
|
||||
if (!spec_priv->rfs_chan_spec_scan)
|
||||
return;
|
||||
|
||||
debugfs_create_file("spectral_scan_ctl",
|
||||
S_IRUSR | S_IWUSR,
|
||||
debugfs_phy, spec_priv,
|
||||
|
|
|
@ -997,7 +997,8 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
|
|||
err = usb_control_msg(hif_dev->udev,
|
||||
usb_sndctrlpipe(hif_dev->udev, 0),
|
||||
FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT,
|
||||
addr >> 8, 0, buf, transfer, HZ);
|
||||
addr >> 8, 0, buf, transfer,
|
||||
USB_MSG_TIMEOUT);
|
||||
if (err < 0) {
|
||||
kfree(buf);
|
||||
return err;
|
||||
|
@ -1020,7 +1021,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
|
|||
err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
|
||||
FIRMWARE_DOWNLOAD_COMP,
|
||||
0x40 | USB_DIR_OUT,
|
||||
firm_offset >> 8, 0, NULL, 0, HZ);
|
||||
firm_offset >> 8, 0, NULL, 0, USB_MSG_TIMEOUT);
|
||||
if (err)
|
||||
return -EIO;
|
||||
|
||||
|
@ -1249,7 +1250,7 @@ static int send_eject_command(struct usb_interface *interface)
|
|||
|
||||
dev_info(&udev->dev, "Ejecting storage device...\n");
|
||||
r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep),
|
||||
cmd, 31, NULL, 2000);
|
||||
cmd, 31, NULL, 2 * USB_MSG_TIMEOUT);
|
||||
kfree(cmd);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -1314,7 +1315,7 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev)
|
|||
return;
|
||||
|
||||
ret = usb_interrupt_msg(udev, usb_sndintpipe(udev, USB_REG_OUT_PIPE),
|
||||
buf, 4, NULL, HZ);
|
||||
buf, 4, NULL, USB_MSG_TIMEOUT);
|
||||
if (ret)
|
||||
dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n");
|
||||
|
||||
|
|
|
@ -71,6 +71,8 @@ extern int htc_use_dev_fw;
|
|||
#define USB_REG_IN_PIPE 3
|
||||
#define USB_REG_OUT_PIPE 4
|
||||
|
||||
#define USB_MSG_TIMEOUT 1000 /* (ms) */
|
||||
|
||||
#define HIF_USB_MAX_RXPIPES 2
|
||||
#define HIF_USB_MAX_TXPIPES 4
|
||||
|
||||
|
|
|
@ -2792,7 +2792,7 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
|
|||
WARN_ON(1);
|
||||
}
|
||||
|
||||
return val;
|
||||
return !!val;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_gpio_get);
|
||||
|
||||
|
|
|
@ -867,10 +867,21 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
|
|||
* can be dropped.
|
||||
*/
|
||||
if (rx_stats->rs_status & ATH9K_RXERR_PHY) {
|
||||
ath9k_dfs_process_phyerr(sc, hdr, rx_stats, rx_status->mactime);
|
||||
if (ath_cmn_process_fft(&sc->spec_priv, hdr, rx_stats, rx_status->mactime))
|
||||
/*
|
||||
* DFS and spectral are mutually exclusive
|
||||
*
|
||||
* Since some chips use PHYERR_RADAR as indication for both, we
|
||||
* need to double check which feature is enabled to prevent
|
||||
* feeding spectral or dfs-detector with wrong frames.
|
||||
*/
|
||||
if (hw->conf.radar_enabled) {
|
||||
ath9k_dfs_process_phyerr(sc, hdr, rx_stats,
|
||||
rx_status->mactime);
|
||||
} else if (sc->spec_priv.spectral_mode != SPECTRAL_DISABLED &&
|
||||
ath_cmn_process_fft(&sc->spec_priv, hdr, rx_stats,
|
||||
rx_status->mactime)) {
|
||||
RX_STAT_INC(rx_spectral);
|
||||
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -354,14 +354,6 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
|
|||
wil_dbg_misc(wil, "%s(), wdev=0x%p iftype=%d\n",
|
||||
__func__, wdev, wdev->iftype);
|
||||
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
if (wil->scan_request) {
|
||||
wil_err(wil, "Already scanning\n");
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
|
||||
/* check we are client side */
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
|
@ -378,12 +370,24 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
if (wil->scan_request || wil->p2p.discovery_started) {
|
||||
wil_err(wil, "Already scanning\n");
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
rc = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
|
||||
/* social scan on P2P_DEVICE is handled as p2p search */
|
||||
if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
|
||||
wil_p2p_is_social_scan(request)) {
|
||||
if (!wil->p2p.p2p_dev_started) {
|
||||
wil_err(wil, "P2P search requested on stopped P2P device\n");
|
||||
return -EIO;
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
wil->scan_request = request;
|
||||
wil->radio_wdev = wdev;
|
||||
|
@ -392,7 +396,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
|
|||
wil->radio_wdev = wil_to_wdev(wil);
|
||||
wil->scan_request = NULL;
|
||||
}
|
||||
return rc;
|
||||
goto out;
|
||||
}
|
||||
|
||||
(void)wil_p2p_stop_discovery(wil);
|
||||
|
@ -415,7 +419,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
|
|||
|
||||
if (rc) {
|
||||
wil_err(wil, "set SSID for scan request failed: %d\n", rc);
|
||||
return rc;
|
||||
goto out;
|
||||
}
|
||||
|
||||
wil->scan_request = request;
|
||||
|
@ -448,7 +452,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
|
|||
|
||||
rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie);
|
||||
if (rc)
|
||||
goto out;
|
||||
goto out_restore;
|
||||
|
||||
if (wil->discovery_mode && cmd.cmd.scan_type == WMI_ACTIVE_SCAN) {
|
||||
cmd.cmd.discovery_mode = 1;
|
||||
|
@ -459,16 +463,45 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
|
|||
rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) +
|
||||
cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0]));
|
||||
|
||||
out:
|
||||
out_restore:
|
||||
if (rc) {
|
||||
del_timer_sync(&wil->scan_timer);
|
||||
wil->radio_wdev = wil_to_wdev(wil);
|
||||
wil->scan_request = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&wil->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void wil_cfg80211_abort_scan(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
wil_dbg_misc(wil, "wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
|
||||
if (!wil->scan_request)
|
||||
goto out;
|
||||
|
||||
if (wdev != wil->scan_request->wdev) {
|
||||
wil_dbg_misc(wil, "abort scan was called on the wrong iface\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (wil->radio_wdev == wil->p2p_wdev)
|
||||
wil_p2p_stop_radio_operations(wil);
|
||||
else
|
||||
wil_abort_scan(wil, true);
|
||||
|
||||
out:
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
mutex_unlock(&wil->mutex);
|
||||
}
|
||||
|
||||
static void wil_print_crypto(struct wil6210_priv *wil,
|
||||
struct cfg80211_crypto_settings *c)
|
||||
{
|
||||
|
@ -674,6 +707,26 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int wil_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
int rc;
|
||||
|
||||
/* these parameters are explicitly not supported */
|
||||
if (changed & (WIPHY_PARAM_RETRY_LONG |
|
||||
WIPHY_PARAM_FRAG_THRESHOLD |
|
||||
WIPHY_PARAM_RTS_THRESHOLD))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (changed & WIPHY_PARAM_RETRY_SHORT) {
|
||||
rc = wmi_set_mgmt_retry(wil, wiphy->retry_short);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct cfg80211_mgmt_tx_params *params,
|
||||
u64 *cookie)
|
||||
|
@ -940,16 +993,8 @@ static int wil_remain_on_channel(struct wiphy *wiphy,
|
|||
wil_dbg_misc(wil, "%s() center_freq=%d, duration=%d iftype=%d\n",
|
||||
__func__, chan->center_freq, duration, wdev->iftype);
|
||||
|
||||
rc = wil_p2p_listen(wil, duration, chan, cookie);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
wil->radio_wdev = wdev;
|
||||
|
||||
cfg80211_ready_on_channel(wdev, *cookie, chan, duration,
|
||||
GFP_KERNEL);
|
||||
|
||||
return 0;
|
||||
rc = wil_p2p_listen(wil, wdev, duration, chan, cookie);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
|
||||
|
@ -1419,17 +1464,49 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
|
|||
|
||||
wil_dbg_misc(wil, "%s: entered\n", __func__);
|
||||
mutex_lock(&wil->mutex);
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
wil_p2p_stop_radio_operations(wil);
|
||||
p2p->p2p_dev_started = 0;
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
mutex_unlock(&wil->mutex);
|
||||
}
|
||||
|
||||
static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
bool enabled, int timeout)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
enum wmi_ps_profile_type ps_profile;
|
||||
int rc;
|
||||
|
||||
if (!test_bit(WMI_FW_CAPABILITY_PS_CONFIG, wil->fw_capabilities)) {
|
||||
wil_err(wil, "set_power_mgmt not supported\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
wil_dbg_misc(wil, "enabled=%d, timeout=%d\n",
|
||||
enabled, timeout);
|
||||
|
||||
if (enabled)
|
||||
ps_profile = WMI_PS_PROFILE_TYPE_DEFAULT;
|
||||
else
|
||||
ps_profile = WMI_PS_PROFILE_TYPE_PS_DISABLED;
|
||||
|
||||
rc = wmi_ps_dev_profile_cfg(wil, ps_profile);
|
||||
if (rc)
|
||||
wil_err(wil, "wmi_ps_dev_profile_cfg failed (%d)\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct cfg80211_ops wil_cfg80211_ops = {
|
||||
.add_virtual_intf = wil_cfg80211_add_iface,
|
||||
.del_virtual_intf = wil_cfg80211_del_iface,
|
||||
.scan = wil_cfg80211_scan,
|
||||
.abort_scan = wil_cfg80211_abort_scan,
|
||||
.connect = wil_cfg80211_connect,
|
||||
.disconnect = wil_cfg80211_disconnect,
|
||||
.set_wiphy_params = wil_cfg80211_set_wiphy_params,
|
||||
.change_virtual_intf = wil_cfg80211_change_iface,
|
||||
.get_station = wil_cfg80211_get_station,
|
||||
.dump_station = wil_cfg80211_dump_station,
|
||||
|
@ -1450,6 +1527,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
|
|||
/* P2P device */
|
||||
.start_p2p_device = wil_cfg80211_start_p2p_device,
|
||||
.stop_p2p_device = wil_cfg80211_stop_p2p_device,
|
||||
.set_power_mgmt = wil_cfg80211_set_power_mgmt,
|
||||
};
|
||||
|
||||
static void wil_wiphy_init(struct wiphy *wiphy)
|
||||
|
@ -1466,7 +1544,8 @@ static void wil_wiphy_init(struct wiphy *wiphy)
|
|||
BIT(NL80211_IFTYPE_MONITOR);
|
||||
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
|
||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
|
||||
WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
|
||||
__func__, wiphy->flags);
|
||||
wiphy->probe_resp_offload =
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "boot_loader.h"
|
||||
|
||||
#define WAIT_FOR_HALP_VOTE_MS 100
|
||||
#define WAIT_FOR_SCAN_ABORT_MS 1000
|
||||
|
||||
bool debug_fw; /* = false; */
|
||||
module_param(debug_fw, bool, S_IRUGO);
|
||||
|
@ -213,7 +214,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
|
|||
memset(&sta->stats, 0, sizeof(sta->stats));
|
||||
}
|
||||
|
||||
static bool wil_ap_is_connected(struct wil6210_priv *wil)
|
||||
static bool wil_is_connected(struct wil6210_priv *wil)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -267,7 +268,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
|
|||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
wil_bcast_fini(wil);
|
||||
netif_tx_stop_all_queues(ndev);
|
||||
wil_update_net_queues_bh(wil, NULL, true);
|
||||
netif_carrier_off(ndev);
|
||||
|
||||
if (test_bit(wil_status_fwconnected, wil->status)) {
|
||||
|
@ -283,8 +284,12 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
|
|||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
if (!wil_ap_is_connected(wil))
|
||||
if (!wil_is_connected(wil)) {
|
||||
wil_update_net_queues_bh(wil, NULL, true);
|
||||
clear_bit(wil_status_fwconnected, wil->status);
|
||||
} else {
|
||||
wil_update_net_queues_bh(wil, NULL, false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -384,18 +389,19 @@ static void wil_fw_error_worker(struct work_struct *work)
|
|||
|
||||
wil->last_fw_recovery = jiffies;
|
||||
|
||||
wil_info(wil, "fw error recovery requested (try %d)...\n",
|
||||
wil->recovery_count);
|
||||
if (!no_fw_recovery)
|
||||
wil->recovery_state = fw_recovery_running;
|
||||
if (wil_wait_for_recovery(wil) != 0)
|
||||
return;
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
wil_info(wil, "fw error recovery requested (try %d)...\n",
|
||||
wil->recovery_count);
|
||||
if (!no_fw_recovery)
|
||||
wil->recovery_state = fw_recovery_running;
|
||||
if (0 != wil_wait_for_recovery(wil))
|
||||
break;
|
||||
|
||||
/* silent recovery, upper layers will see disconnect */
|
||||
__wil_down(wil);
|
||||
__wil_up(wil);
|
||||
break;
|
||||
|
@ -512,10 +518,13 @@ int wil_priv_init(struct wil6210_priv *wil)
|
|||
INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
|
||||
INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker);
|
||||
INIT_WORK(&wil->probe_client_worker, wil_probe_client_worker);
|
||||
INIT_WORK(&wil->p2p.delayed_listen_work, wil_p2p_delayed_listen_work);
|
||||
|
||||
INIT_LIST_HEAD(&wil->pending_wmi_ev);
|
||||
INIT_LIST_HEAD(&wil->probe_client_pending);
|
||||
spin_lock_init(&wil->wmi_ev_lock);
|
||||
spin_lock_init(&wil->net_queue_lock);
|
||||
wil->net_queue_stopped = 1;
|
||||
init_waitqueue_head(&wil->wq);
|
||||
|
||||
wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi");
|
||||
|
@ -571,6 +580,7 @@ void wil_priv_deinit(struct wil6210_priv *wil)
|
|||
cancel_work_sync(&wil->disconnect_worker);
|
||||
cancel_work_sync(&wil->fw_error_worker);
|
||||
cancel_work_sync(&wil->p2p.discovery_expired_work);
|
||||
cancel_work_sync(&wil->p2p.delayed_listen_work);
|
||||
mutex_lock(&wil->mutex);
|
||||
wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
|
||||
mutex_unlock(&wil->mutex);
|
||||
|
@ -685,6 +695,19 @@ static int wil_target_reset(struct wil6210_priv *wil)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void wil_collect_fw_info(struct wil6210_priv *wil)
|
||||
{
|
||||
struct wiphy *wiphy = wil_to_wiphy(wil);
|
||||
u8 retry_short;
|
||||
int rc;
|
||||
|
||||
rc = wmi_get_mgmt_retry(wil, &retry_short);
|
||||
if (!rc) {
|
||||
wiphy->retry_short = retry_short;
|
||||
wil_dbg_misc(wil, "FW retry_short: %d\n", retry_short);
|
||||
}
|
||||
}
|
||||
|
||||
void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
|
||||
{
|
||||
le32_to_cpus(&r->base);
|
||||
|
@ -801,6 +824,34 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void wil_abort_scan(struct wil6210_priv *wil, bool sync)
|
||||
{
|
||||
int rc;
|
||||
struct cfg80211_scan_info info = {
|
||||
.aborted = true,
|
||||
};
|
||||
|
||||
lockdep_assert_held(&wil->p2p_wdev_mutex);
|
||||
|
||||
if (!wil->scan_request)
|
||||
return;
|
||||
|
||||
wil_dbg_misc(wil, "Abort scan_request 0x%p\n", wil->scan_request);
|
||||
del_timer_sync(&wil->scan_timer);
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
rc = wmi_abort_scan(wil);
|
||||
if (!rc && sync)
|
||||
wait_event_interruptible_timeout(wil->wq, !wil->scan_request,
|
||||
msecs_to_jiffies(
|
||||
WAIT_FOR_SCAN_ABORT_MS));
|
||||
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
if (wil->scan_request) {
|
||||
cfg80211_scan_done(wil->scan_request, &info);
|
||||
wil->scan_request = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We reset all the structures, and we reset the UMAC.
|
||||
* After calling this routine, you're expected to reload
|
||||
|
@ -853,17 +904,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
|||
mutex_unlock(&wil->wmi_mutex);
|
||||
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
if (wil->scan_request) {
|
||||
struct cfg80211_scan_info info = {
|
||||
.aborted = true,
|
||||
};
|
||||
|
||||
wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
|
||||
wil->scan_request);
|
||||
del_timer_sync(&wil->scan_timer);
|
||||
cfg80211_scan_done(wil->scan_request, &info);
|
||||
wil->scan_request = NULL;
|
||||
}
|
||||
wil_abort_scan(wil, false);
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
|
||||
wil_mask_irq(wil);
|
||||
|
@ -940,6 +981,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
|||
return rc;
|
||||
}
|
||||
|
||||
wil_collect_fw_info(wil);
|
||||
|
||||
if (wil->platform_ops.notify) {
|
||||
rc = wil->platform_ops.notify(wil->platform_handle,
|
||||
WIL_PLATFORM_EVT_FW_RDY);
|
||||
|
@ -1056,20 +1099,9 @@ int __wil_down(struct wil6210_priv *wil)
|
|||
}
|
||||
wil_enable_irq(wil);
|
||||
|
||||
wil_p2p_stop_radio_operations(wil);
|
||||
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
if (wil->scan_request) {
|
||||
struct cfg80211_scan_info info = {
|
||||
.aborted = true,
|
||||
};
|
||||
|
||||
wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
|
||||
wil->scan_request);
|
||||
del_timer_sync(&wil->scan_timer);
|
||||
cfg80211_scan_done(wil->scan_request, &info);
|
||||
wil->scan_request = NULL;
|
||||
}
|
||||
wil_p2p_stop_radio_operations(wil);
|
||||
wil_abort_scan(wil, false);
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
|
||||
wil_reset(wil, false);
|
||||
|
|
|
@ -214,7 +214,7 @@ int wil_if_add(struct wil6210_priv *wil)
|
|||
netif_tx_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx,
|
||||
WIL6210_NAPI_BUDGET);
|
||||
|
||||
netif_tx_stop_all_queues(ndev);
|
||||
wil_update_net_queues_bh(wil, NULL, true);
|
||||
|
||||
rc = register_netdev(ndev);
|
||||
if (rc < 0) {
|
||||
|
|
|
@ -22,6 +22,43 @@
|
|||
#define P2P_SEARCH_DURATION_MS 500
|
||||
#define P2P_DEFAULT_BI 100
|
||||
|
||||
static int wil_p2p_start_listen(struct wil6210_priv *wil)
|
||||
{
|
||||
struct wil_p2p_info *p2p = &wil->p2p;
|
||||
u8 channel = p2p->listen_chan.hw_value;
|
||||
int rc;
|
||||
|
||||
lockdep_assert_held(&wil->mutex);
|
||||
|
||||
rc = wmi_p2p_cfg(wil, channel, P2P_DEFAULT_BI);
|
||||
if (rc) {
|
||||
wil_err(wil, "wmi_p2p_cfg failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID);
|
||||
if (rc) {
|
||||
wil_err(wil, "wmi_set_ssid failed\n");
|
||||
goto out_stop;
|
||||
}
|
||||
|
||||
rc = wmi_start_listen(wil);
|
||||
if (rc) {
|
||||
wil_err(wil, "wmi_start_listen failed\n");
|
||||
goto out_stop;
|
||||
}
|
||||
|
||||
INIT_WORK(&p2p->discovery_expired_work, wil_p2p_listen_expired);
|
||||
mod_timer(&p2p->discovery_timer,
|
||||
jiffies + msecs_to_jiffies(p2p->listen_duration));
|
||||
out_stop:
|
||||
if (rc)
|
||||
wmi_stop_discovery(wil);
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request)
|
||||
{
|
||||
return (request->n_channels == 1) &&
|
||||
|
@ -46,7 +83,7 @@ int wil_p2p_search(struct wil6210_priv *wil,
|
|||
wil_dbg_misc(wil, "%s: channel %d\n",
|
||||
__func__, P2P_DMG_SOCIAL_CHANNEL);
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
lockdep_assert_held(&wil->mutex);
|
||||
|
||||
if (p2p->discovery_started) {
|
||||
wil_err(wil, "%s: search failed. discovery already ongoing\n",
|
||||
|
@ -103,22 +140,19 @@ out_stop:
|
|||
wmi_stop_discovery(wil);
|
||||
|
||||
out:
|
||||
mutex_unlock(&wil->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration,
|
||||
struct ieee80211_channel *chan, u64 *cookie)
|
||||
int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
|
||||
unsigned int duration, struct ieee80211_channel *chan,
|
||||
u64 *cookie)
|
||||
{
|
||||
struct wil_p2p_info *p2p = &wil->p2p;
|
||||
u8 channel = P2P_DMG_SOCIAL_CHANNEL;
|
||||
int rc;
|
||||
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
|
||||
channel = chan->hw_value;
|
||||
|
||||
wil_dbg_misc(wil, "%s: duration %d\n", __func__, duration);
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
|
@ -129,35 +163,30 @@ int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration,
|
|||
goto out;
|
||||
}
|
||||
|
||||
rc = wmi_p2p_cfg(wil, channel, P2P_DEFAULT_BI);
|
||||
if (rc) {
|
||||
wil_err(wil, "%s: wmi_p2p_cfg failed\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID);
|
||||
if (rc) {
|
||||
wil_err(wil, "%s: wmi_set_ssid failed\n", __func__);
|
||||
goto out_stop;
|
||||
}
|
||||
|
||||
rc = wmi_start_listen(wil);
|
||||
if (rc) {
|
||||
wil_err(wil, "%s: wmi_start_listen failed\n", __func__);
|
||||
goto out_stop;
|
||||
}
|
||||
|
||||
memcpy(&p2p->listen_chan, chan, sizeof(*chan));
|
||||
*cookie = ++p2p->cookie;
|
||||
p2p->listen_duration = duration;
|
||||
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
if (wil->scan_request) {
|
||||
wil_dbg_misc(wil, "Delaying p2p listen until scan done\n");
|
||||
p2p->pending_listen_wdev = wdev;
|
||||
p2p->discovery_started = 1;
|
||||
rc = 0;
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
goto out;
|
||||
}
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
|
||||
rc = wil_p2p_start_listen(wil);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
p2p->discovery_started = 1;
|
||||
INIT_WORK(&p2p->discovery_expired_work, wil_p2p_listen_expired);
|
||||
mod_timer(&p2p->discovery_timer,
|
||||
jiffies + msecs_to_jiffies(duration));
|
||||
wil->radio_wdev = wdev;
|
||||
|
||||
out_stop:
|
||||
if (rc)
|
||||
wmi_stop_discovery(wil);
|
||||
cfg80211_ready_on_channel(wdev, *cookie, chan, duration,
|
||||
GFP_KERNEL);
|
||||
|
||||
out:
|
||||
mutex_unlock(&wil->mutex);
|
||||
|
@ -170,9 +199,14 @@ u8 wil_p2p_stop_discovery(struct wil6210_priv *wil)
|
|||
u8 started = p2p->discovery_started;
|
||||
|
||||
if (p2p->discovery_started) {
|
||||
del_timer_sync(&p2p->discovery_timer);
|
||||
if (p2p->pending_listen_wdev) {
|
||||
/* discovery not really started, only pending */
|
||||
p2p->pending_listen_wdev = NULL;
|
||||
} else {
|
||||
del_timer_sync(&p2p->discovery_timer);
|
||||
wmi_stop_discovery(wil);
|
||||
}
|
||||
p2p->discovery_started = 0;
|
||||
wmi_stop_discovery(wil);
|
||||
}
|
||||
|
||||
return started;
|
||||
|
@ -257,13 +291,59 @@ void wil_p2p_search_expired(struct work_struct *work)
|
|||
};
|
||||
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
cfg80211_scan_done(wil->scan_request, &info);
|
||||
wil->scan_request = NULL;
|
||||
wil->radio_wdev = wil->wdev;
|
||||
if (wil->scan_request) {
|
||||
cfg80211_scan_done(wil->scan_request, &info);
|
||||
wil->scan_request = NULL;
|
||||
wil->radio_wdev = wil->wdev;
|
||||
}
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void wil_p2p_delayed_listen_work(struct work_struct *work)
|
||||
{
|
||||
struct wil_p2p_info *p2p = container_of(work,
|
||||
struct wil_p2p_info, delayed_listen_work);
|
||||
struct wil6210_priv *wil = container_of(p2p,
|
||||
struct wil6210_priv, p2p);
|
||||
int rc;
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
|
||||
wil_dbg_misc(wil, "Checking delayed p2p listen\n");
|
||||
if (!p2p->discovery_started || !p2p->pending_listen_wdev)
|
||||
goto out;
|
||||
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
if (wil->scan_request) {
|
||||
/* another scan started, wait again... */
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
goto out;
|
||||
}
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
|
||||
rc = wil_p2p_start_listen(wil);
|
||||
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
if (rc) {
|
||||
cfg80211_remain_on_channel_expired(p2p->pending_listen_wdev,
|
||||
p2p->cookie,
|
||||
&p2p->listen_chan,
|
||||
GFP_KERNEL);
|
||||
wil->radio_wdev = wil->wdev;
|
||||
} else {
|
||||
cfg80211_ready_on_channel(p2p->pending_listen_wdev, p2p->cookie,
|
||||
&p2p->listen_chan,
|
||||
p2p->listen_duration, GFP_KERNEL);
|
||||
wil->radio_wdev = p2p->pending_listen_wdev;
|
||||
}
|
||||
p2p->pending_listen_wdev = NULL;
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
|
||||
out:
|
||||
mutex_unlock(&wil->mutex);
|
||||
}
|
||||
|
||||
void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
|
||||
{
|
||||
struct wil_p2p_info *p2p = &wil->p2p;
|
||||
|
@ -272,8 +352,7 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
|
|||
};
|
||||
|
||||
lockdep_assert_held(&wil->mutex);
|
||||
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
lockdep_assert_held(&wil->p2p_wdev_mutex);
|
||||
|
||||
if (wil->radio_wdev != wil->p2p_wdev)
|
||||
goto out;
|
||||
|
@ -281,10 +360,8 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
|
|||
if (!p2p->discovery_started) {
|
||||
/* Regular scan on the p2p device */
|
||||
if (wil->scan_request &&
|
||||
wil->scan_request->wdev == wil->p2p_wdev) {
|
||||
cfg80211_scan_done(wil->scan_request, &info);
|
||||
wil->scan_request = NULL;
|
||||
}
|
||||
wil->scan_request->wdev == wil->p2p_wdev)
|
||||
wil_abort_scan(wil, true);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -307,5 +384,4 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
|
|||
|
||||
out:
|
||||
wil->radio_wdev = wil->wdev;
|
||||
mutex_unlock(&wil->p2p_wdev_mutex);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
|
|||
struct pmc_ctx *pmc = &wil->pmc;
|
||||
struct device *dev = wil_to_dev(wil);
|
||||
struct wmi_pmc_cmd pmc_cmd = {0};
|
||||
int last_cmd_err = -ENOMEM;
|
||||
|
||||
mutex_lock(&pmc->lock);
|
||||
|
||||
|
@ -62,6 +63,29 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
|
|||
wil_err(wil, "%s: ERROR pmc is already allocated\n", __func__);
|
||||
goto no_release_err;
|
||||
}
|
||||
if ((num_descriptors <= 0) || (descriptor_size <= 0)) {
|
||||
wil_err(wil,
|
||||
"Invalid params num_descriptors(%d), descriptor_size(%d)\n",
|
||||
num_descriptors, descriptor_size);
|
||||
last_cmd_err = -EINVAL;
|
||||
goto no_release_err;
|
||||
}
|
||||
|
||||
if (num_descriptors > (1 << WIL_RING_SIZE_ORDER_MAX)) {
|
||||
wil_err(wil,
|
||||
"num_descriptors(%d) exceeds max ring size %d\n",
|
||||
num_descriptors, 1 << WIL_RING_SIZE_ORDER_MAX);
|
||||
last_cmd_err = -EINVAL;
|
||||
goto no_release_err;
|
||||
}
|
||||
|
||||
if (num_descriptors > INT_MAX / descriptor_size) {
|
||||
wil_err(wil,
|
||||
"Overflow in num_descriptors(%d)*descriptor_size(%d)\n",
|
||||
num_descriptors, descriptor_size);
|
||||
last_cmd_err = -EINVAL;
|
||||
goto no_release_err;
|
||||
}
|
||||
|
||||
pmc->num_descriptors = num_descriptors;
|
||||
pmc->descriptor_size = descriptor_size;
|
||||
|
@ -189,7 +213,7 @@ release_pmc_skb_list:
|
|||
pmc->descriptors = NULL;
|
||||
|
||||
no_release_err:
|
||||
pmc->last_cmd_status = -ENOMEM;
|
||||
pmc->last_cmd_status = last_cmd_err;
|
||||
mutex_unlock(&pmc->lock);
|
||||
}
|
||||
|
||||
|
@ -295,7 +319,7 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
|
|||
size_t retval = 0;
|
||||
unsigned long long idx;
|
||||
loff_t offset;
|
||||
size_t pmc_size = pmc->descriptor_size * pmc->num_descriptors;
|
||||
size_t pmc_size;
|
||||
|
||||
mutex_lock(&pmc->lock);
|
||||
|
||||
|
@ -306,6 +330,8 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
pmc_size = pmc->descriptor_size * pmc->num_descriptors;
|
||||
|
||||
wil_dbg_misc(wil,
|
||||
"%s: size %u, pos %lld\n",
|
||||
__func__, (unsigned)count, *f_pos);
|
||||
|
@ -345,7 +371,18 @@ loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence)
|
|||
loff_t newpos;
|
||||
struct wil6210_priv *wil = filp->private_data;
|
||||
struct pmc_ctx *pmc = &wil->pmc;
|
||||
size_t pmc_size = pmc->descriptor_size * pmc->num_descriptors;
|
||||
size_t pmc_size;
|
||||
|
||||
mutex_lock(&pmc->lock);
|
||||
|
||||
if (!wil_is_pmc_allocated(pmc)) {
|
||||
wil_err(wil, "error, pmc is not allocated!\n");
|
||||
pmc->last_cmd_status = -EPERM;
|
||||
mutex_unlock(&pmc->lock);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
pmc_size = pmc->descriptor_size * pmc->num_descriptors;
|
||||
|
||||
switch (whence) {
|
||||
case 0: /* SEEK_SET */
|
||||
|
@ -361,15 +398,21 @@ loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence)
|
|||
break;
|
||||
|
||||
default: /* can't happen */
|
||||
return -EINVAL;
|
||||
newpos = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (newpos < 0)
|
||||
return -EINVAL;
|
||||
if (newpos < 0) {
|
||||
newpos = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (newpos > pmc_size)
|
||||
newpos = pmc_size;
|
||||
|
||||
filp->f_pos = newpos;
|
||||
|
||||
out:
|
||||
mutex_unlock(&pmc->lock);
|
||||
|
||||
return newpos;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,18 @@ static inline int wil_vring_wmark_high(struct vring *vring)
|
|||
return vring->size/4;
|
||||
}
|
||||
|
||||
/* returns true if num avail descriptors is lower than wmark_low */
|
||||
static inline int wil_vring_avail_low(struct vring *vring)
|
||||
{
|
||||
return wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring);
|
||||
}
|
||||
|
||||
/* returns true if num avail descriptors is higher than wmark_high */
|
||||
static inline int wil_vring_avail_high(struct vring *vring)
|
||||
{
|
||||
return wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring);
|
||||
}
|
||||
|
||||
/* wil_val_in_range - check if value in [min,max) */
|
||||
static inline bool wil_val_in_range(int val, int min, int max)
|
||||
{
|
||||
|
@ -1780,6 +1792,89 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check status of tx vrings and stop/wake net queues if needed
|
||||
*
|
||||
* This function does one of two checks:
|
||||
* In case check_stop is true, will check if net queues need to be stopped. If
|
||||
* the conditions for stopping are met, netif_tx_stop_all_queues() is called.
|
||||
* In case check_stop is false, will check if net queues need to be waked. If
|
||||
* the conditions for waking are met, netif_tx_wake_all_queues() is called.
|
||||
* vring is the vring which is currently being modified by either adding
|
||||
* descriptors (tx) into it or removing descriptors (tx complete) from it. Can
|
||||
* be null when irrelevant (e.g. connect/disconnect events).
|
||||
*
|
||||
* The implementation is to stop net queues if modified vring has low
|
||||
* descriptor availability. Wake if all vrings are not in low descriptor
|
||||
* availability and modified vring has high descriptor availability.
|
||||
*/
|
||||
static inline void __wil_update_net_queues(struct wil6210_priv *wil,
|
||||
struct vring *vring,
|
||||
bool check_stop)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (vring)
|
||||
wil_dbg_txrx(wil, "vring %d, check_stop=%d, stopped=%d",
|
||||
(int)(vring - wil->vring_tx), check_stop,
|
||||
wil->net_queue_stopped);
|
||||
else
|
||||
wil_dbg_txrx(wil, "check_stop=%d, stopped=%d",
|
||||
check_stop, wil->net_queue_stopped);
|
||||
|
||||
if (check_stop == wil->net_queue_stopped)
|
||||
/* net queues already in desired state */
|
||||
return;
|
||||
|
||||
if (check_stop) {
|
||||
if (!vring || unlikely(wil_vring_avail_low(vring))) {
|
||||
/* not enough room in the vring */
|
||||
netif_tx_stop_all_queues(wil_to_ndev(wil));
|
||||
wil->net_queue_stopped = true;
|
||||
wil_dbg_txrx(wil, "netif_tx_stop called\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* check wake */
|
||||
for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
|
||||
struct vring *cur_vring = &wil->vring_tx[i];
|
||||
struct vring_tx_data *txdata = &wil->vring_tx_data[i];
|
||||
|
||||
if (!cur_vring->va || !txdata->enabled || cur_vring == vring)
|
||||
continue;
|
||||
|
||||
if (wil_vring_avail_low(cur_vring)) {
|
||||
wil_dbg_txrx(wil, "vring %d full, can't wake\n",
|
||||
(int)(cur_vring - wil->vring_tx));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vring || wil_vring_avail_high(vring)) {
|
||||
/* enough room in the vring */
|
||||
wil_dbg_txrx(wil, "calling netif_tx_wake\n");
|
||||
netif_tx_wake_all_queues(wil_to_ndev(wil));
|
||||
wil->net_queue_stopped = false;
|
||||
}
|
||||
}
|
||||
|
||||
void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring,
|
||||
bool check_stop)
|
||||
{
|
||||
spin_lock(&wil->net_queue_lock);
|
||||
__wil_update_net_queues(wil, vring, check_stop);
|
||||
spin_unlock(&wil->net_queue_lock);
|
||||
}
|
||||
|
||||
void wil_update_net_queues_bh(struct wil6210_priv *wil, struct vring *vring,
|
||||
bool check_stop)
|
||||
{
|
||||
spin_lock_bh(&wil->net_queue_lock);
|
||||
__wil_update_net_queues(wil, vring, check_stop);
|
||||
spin_unlock_bh(&wil->net_queue_lock);
|
||||
}
|
||||
|
||||
netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
{
|
||||
struct wil6210_priv *wil = ndev_to_wil(ndev);
|
||||
|
@ -1822,14 +1917,10 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
|||
/* set up vring entry */
|
||||
rc = wil_tx_vring(wil, vring, skb);
|
||||
|
||||
/* do we still have enough room in the vring? */
|
||||
if (unlikely(wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring))) {
|
||||
netif_tx_stop_all_queues(wil_to_ndev(wil));
|
||||
wil_dbg_txrx(wil, "netif_tx_stop : ring full\n");
|
||||
}
|
||||
|
||||
switch (rc) {
|
||||
case 0:
|
||||
/* shall we stop net queues? */
|
||||
wil_update_net_queues_bh(wil, vring, true);
|
||||
/* statistics will be updated on the tx_complete */
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
|
@ -1978,10 +2069,9 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
|
|||
txdata->last_idle = get_cycles();
|
||||
}
|
||||
|
||||
if (wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring)) {
|
||||
wil_dbg_txrx(wil, "netif_tx_wake : ring not full\n");
|
||||
netif_tx_wake_all_queues(wil_to_ndev(wil));
|
||||
}
|
||||
/* shall we wake net queues? */
|
||||
if (done)
|
||||
wil_update_net_queues(wil, vring, false);
|
||||
|
||||
return done;
|
||||
}
|
||||
|
|
|
@ -276,10 +276,11 @@ struct fw_map {
|
|||
u32 to; /* linker address - to, exclusive */
|
||||
u32 host; /* PCI/Host address - BAR0 + 0x880000 */
|
||||
const char *name; /* for debugfs */
|
||||
bool fw; /* true if FW mapping, false if UCODE mapping */
|
||||
};
|
||||
|
||||
/* array size should be in sync with actual definition in the wmi.c */
|
||||
extern const struct fw_map fw_mapping[8];
|
||||
extern const struct fw_map fw_mapping[10];
|
||||
|
||||
/**
|
||||
* mk_cidxtid - construct @cidxtid field
|
||||
|
@ -461,8 +462,11 @@ struct wil_p2p_info {
|
|||
u8 discovery_started;
|
||||
u8 p2p_dev_started;
|
||||
u64 cookie;
|
||||
struct wireless_dev *pending_listen_wdev;
|
||||
unsigned int listen_duration;
|
||||
struct timer_list discovery_timer; /* listen/search duration */
|
||||
struct work_struct discovery_expired_work; /* listen/search expire */
|
||||
struct work_struct delayed_listen_work; /* listen after scan done */
|
||||
};
|
||||
|
||||
enum wil_sta_status {
|
||||
|
@ -624,6 +628,8 @@ struct wil6210_priv {
|
|||
* - consumed in thread by wmi_event_worker
|
||||
*/
|
||||
spinlock_t wmi_ev_lock;
|
||||
spinlock_t net_queue_lock; /* guarding stop/wake netif queue */
|
||||
int net_queue_stopped; /* netif_tx_stop_all_queues invoked */
|
||||
struct napi_struct napi_rx;
|
||||
struct napi_struct napi_tx;
|
||||
/* keep alive */
|
||||
|
@ -817,6 +823,10 @@ int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason);
|
|||
int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason);
|
||||
int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
|
||||
u16 status, bool amsdu, u16 agg_wsize, u16 timeout);
|
||||
int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
|
||||
enum wmi_ps_profile_type ps_profile);
|
||||
int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short);
|
||||
int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short);
|
||||
int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid,
|
||||
u8 dialog_token, __le16 ba_param_set,
|
||||
__le16 ba_timeout, __le16 ba_seq_ctrl);
|
||||
|
@ -837,13 +847,15 @@ bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request);
|
|||
void wil_p2p_discovery_timer_fn(ulong x);
|
||||
int wil_p2p_search(struct wil6210_priv *wil,
|
||||
struct cfg80211_scan_request *request);
|
||||
int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration,
|
||||
struct ieee80211_channel *chan, u64 *cookie);
|
||||
int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
|
||||
unsigned int duration, struct ieee80211_channel *chan,
|
||||
u64 *cookie);
|
||||
u8 wil_p2p_stop_discovery(struct wil6210_priv *wil);
|
||||
int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie);
|
||||
void wil_p2p_listen_expired(struct work_struct *work);
|
||||
void wil_p2p_search_expired(struct work_struct *work);
|
||||
void wil_p2p_stop_radio_operations(struct wil6210_priv *wil);
|
||||
void wil_p2p_delayed_listen_work(struct work_struct *work);
|
||||
|
||||
/* WMI for P2P */
|
||||
int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi);
|
||||
|
@ -869,6 +881,9 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
|
|||
u8 chan, u8 hidden_ssid, u8 is_go);
|
||||
int wmi_pcp_stop(struct wil6210_priv *wil);
|
||||
int wmi_led_cfg(struct wil6210_priv *wil, bool enable);
|
||||
int wmi_abort_scan(struct wil6210_priv *wil);
|
||||
void wil_abort_scan(struct wil6210_priv *wil, bool sync);
|
||||
|
||||
void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
|
||||
u16 reason_code, bool from_event);
|
||||
void wil_probe_client_flush(struct wil6210_priv *wil);
|
||||
|
@ -886,6 +901,10 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size);
|
|||
int wil_bcast_init(struct wil6210_priv *wil);
|
||||
void wil_bcast_fini(struct wil6210_priv *wil);
|
||||
|
||||
void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring,
|
||||
bool should_stop);
|
||||
void wil_update_net_queues_bh(struct wil6210_priv *wil, struct vring *vring,
|
||||
bool check_stop);
|
||||
netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
|
||||
int wil_tx_complete(struct wil6210_priv *wil, int ringid);
|
||||
void wil6210_unmask_irq_tx(struct wil6210_priv *wil);
|
||||
|
|
|
@ -36,6 +36,9 @@ static int wil_fw_get_crash_dump_bounds(struct wil6210_priv *wil,
|
|||
for (i = 1; i < ARRAY_SIZE(fw_mapping); i++) {
|
||||
map = &fw_mapping[i];
|
||||
|
||||
if (!map->fw)
|
||||
continue;
|
||||
|
||||
if (map->host < host_min)
|
||||
host_min = map->host;
|
||||
|
||||
|
@ -73,6 +76,9 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
|
|||
for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
|
||||
map = &fw_mapping[i];
|
||||
|
||||
if (!map->fw)
|
||||
continue;
|
||||
|
||||
data = (void * __force)wil->csr + HOSTADDR(map->host);
|
||||
len = map->to - map->from;
|
||||
offset = map->host - host_min;
|
||||
|
|
|
@ -84,19 +84,29 @@ MODULE_PARM_DESC(led_id,
|
|||
* array size should be in sync with the declaration in the wil6210.h
|
||||
*/
|
||||
const struct fw_map fw_mapping[] = {
|
||||
{0x000000, 0x040000, 0x8c0000, "fw_code"}, /* FW code RAM 256k */
|
||||
{0x800000, 0x808000, 0x900000, "fw_data"}, /* FW data RAM 32k */
|
||||
{0x840000, 0x860000, 0x908000, "fw_peri"}, /* periph. data RAM 128k */
|
||||
{0x880000, 0x88a000, 0x880000, "rgf"}, /* various RGF 40k */
|
||||
{0x88a000, 0x88b000, 0x88a000, "AGC_tbl"}, /* AGC table 4k */
|
||||
{0x88b000, 0x88c000, 0x88b000, "rgf_ext"}, /* Pcie_ext_rgf 4k */
|
||||
{0x88c000, 0x88c200, 0x88c000, "mac_rgf_ext"}, /* mac_ext_rgf 512b */
|
||||
{0x8c0000, 0x949000, 0x8c0000, "upper"}, /* upper area 548k */
|
||||
/*
|
||||
* 920000..930000 ucode code RAM
|
||||
* 930000..932000 ucode data RAM
|
||||
* 932000..949000 back-door debug data
|
||||
/* FW code RAM 256k */
|
||||
{0x000000, 0x040000, 0x8c0000, "fw_code", true},
|
||||
/* FW data RAM 32k */
|
||||
{0x800000, 0x808000, 0x900000, "fw_data", true},
|
||||
/* periph data 128k */
|
||||
{0x840000, 0x860000, 0x908000, "fw_peri", true},
|
||||
/* various RGF 40k */
|
||||
{0x880000, 0x88a000, 0x880000, "rgf", true},
|
||||
/* AGC table 4k */
|
||||
{0x88a000, 0x88b000, 0x88a000, "AGC_tbl", true},
|
||||
/* Pcie_ext_rgf 4k */
|
||||
{0x88b000, 0x88c000, 0x88b000, "rgf_ext", true},
|
||||
/* mac_ext_rgf 512b */
|
||||
{0x88c000, 0x88c200, 0x88c000, "mac_rgf_ext", true},
|
||||
/* upper area 548k */
|
||||
{0x8c0000, 0x949000, 0x8c0000, "upper", true},
|
||||
/* UCODE areas - accessible by debugfs blobs but not by
|
||||
* wmi_addr_remap. UCODE areas MUST be added AFTER FW areas!
|
||||
*/
|
||||
/* ucode code RAM 128k */
|
||||
{0x000000, 0x020000, 0x920000, "uc_code", false},
|
||||
/* ucode data RAM 16k */
|
||||
{0x800000, 0x804000, 0x940000, "uc_data", false},
|
||||
};
|
||||
|
||||
struct blink_on_off_time led_blink_time[] = {
|
||||
|
@ -108,7 +118,7 @@ struct blink_on_off_time led_blink_time[] = {
|
|||
u8 led_polarity = LED_POLARITY_LOW_ACTIVE;
|
||||
|
||||
/**
|
||||
* return AHB address for given firmware/ucode internal (linker) address
|
||||
* return AHB address for given firmware internal (linker) address
|
||||
* @x - internal address
|
||||
* If address have no valid AHB mapping, return 0
|
||||
*/
|
||||
|
@ -117,7 +127,8 @@ static u32 wmi_addr_remap(u32 x)
|
|||
uint i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
|
||||
if ((x >= fw_mapping[i].from) && (x < fw_mapping[i].to))
|
||||
if (fw_mapping[i].fw &&
|
||||
((x >= fw_mapping[i].from) && (x < fw_mapping[i].to)))
|
||||
return x + fw_mapping[i].host - fw_mapping[i].from;
|
||||
}
|
||||
|
||||
|
@ -427,18 +438,24 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
|
|||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
if (wil->scan_request) {
|
||||
struct wmi_scan_complete_event *data = d;
|
||||
int status = le32_to_cpu(data->status);
|
||||
struct cfg80211_scan_info info = {
|
||||
.aborted = (data->status != WMI_SCAN_SUCCESS),
|
||||
.aborted = ((status != WMI_SCAN_SUCCESS) &&
|
||||
(status != WMI_SCAN_ABORT_REJECTED)),
|
||||
};
|
||||
|
||||
wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
|
||||
wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", status);
|
||||
wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n",
|
||||
wil->scan_request, info.aborted);
|
||||
|
||||
del_timer_sync(&wil->scan_timer);
|
||||
cfg80211_scan_done(wil->scan_request, &info);
|
||||
wil->radio_wdev = wil->wdev;
|
||||
wil->scan_request = NULL;
|
||||
wake_up_interruptible(&wil->wq);
|
||||
if (wil->p2p.pending_listen_wdev) {
|
||||
wil_dbg_misc(wil, "Scheduling delayed listen\n");
|
||||
schedule_work(&wil->p2p.delayed_listen_work);
|
||||
}
|
||||
} else {
|
||||
wil_err(wil, "SCAN_COMPLETE while not scanning\n");
|
||||
}
|
||||
|
@ -548,7 +565,6 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
|
|||
if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
|
||||
(wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
|
||||
if (rc) {
|
||||
netif_tx_stop_all_queues(ndev);
|
||||
netif_carrier_off(ndev);
|
||||
wil_err(wil,
|
||||
"%s: cfg80211_connect_result with failure\n",
|
||||
|
@ -588,7 +604,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
|
|||
|
||||
wil->sta[evt->cid].status = wil_sta_connected;
|
||||
set_bit(wil_status_fwconnected, wil->status);
|
||||
netif_tx_wake_all_queues(ndev);
|
||||
wil_update_net_queues_bh(wil, NULL, false);
|
||||
|
||||
out:
|
||||
if (rc)
|
||||
|
@ -1564,6 +1580,112 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
|
|||
return rc;
|
||||
}
|
||||
|
||||
int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
|
||||
enum wmi_ps_profile_type ps_profile)
|
||||
{
|
||||
int rc;
|
||||
struct wmi_ps_dev_profile_cfg_cmd cmd = {
|
||||
.ps_profile = ps_profile,
|
||||
};
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_ps_dev_profile_cfg_event evt;
|
||||
} __packed reply;
|
||||
u32 status;
|
||||
|
||||
wil_dbg_wmi(wil, "Setting ps dev profile %d\n", ps_profile);
|
||||
|
||||
reply.evt.status = cpu_to_le32(WMI_PS_CFG_CMD_STATUS_ERROR);
|
||||
|
||||
rc = wmi_call(wil, WMI_PS_DEV_PROFILE_CFG_CMDID, &cmd, sizeof(cmd),
|
||||
WMI_PS_DEV_PROFILE_CFG_EVENTID, &reply, sizeof(reply),
|
||||
100);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
status = le32_to_cpu(reply.evt.status);
|
||||
|
||||
if (status != WMI_PS_CFG_CMD_STATUS_SUCCESS) {
|
||||
wil_err(wil, "ps dev profile cfg failed with status %d\n",
|
||||
status);
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short)
|
||||
{
|
||||
int rc;
|
||||
struct wmi_set_mgmt_retry_limit_cmd cmd = {
|
||||
.mgmt_retry_limit = retry_short,
|
||||
};
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_set_mgmt_retry_limit_event evt;
|
||||
} __packed reply;
|
||||
|
||||
wil_dbg_wmi(wil, "Setting mgmt retry short %d\n", retry_short);
|
||||
|
||||
if (!test_bit(WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT, wil->fw_capabilities))
|
||||
return -ENOTSUPP;
|
||||
|
||||
reply.evt.status = WMI_FW_STATUS_FAILURE;
|
||||
|
||||
rc = wmi_call(wil, WMI_SET_MGMT_RETRY_LIMIT_CMDID, &cmd, sizeof(cmd),
|
||||
WMI_SET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply),
|
||||
100);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (reply.evt.status != WMI_FW_STATUS_SUCCESS) {
|
||||
wil_err(wil, "set mgmt retry limit failed with status %d\n",
|
||||
reply.evt.status);
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short)
|
||||
{
|
||||
int rc;
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_get_mgmt_retry_limit_event evt;
|
||||
} __packed reply;
|
||||
|
||||
wil_dbg_wmi(wil, "getting mgmt retry short\n");
|
||||
|
||||
if (!test_bit(WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT, wil->fw_capabilities))
|
||||
return -ENOTSUPP;
|
||||
|
||||
reply.evt.mgmt_retry_limit = 0;
|
||||
rc = wmi_call(wil, WMI_GET_MGMT_RETRY_LIMIT_CMDID, NULL, 0,
|
||||
WMI_GET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply),
|
||||
100);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (retry_short)
|
||||
*retry_short = reply.evt.mgmt_retry_limit;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wmi_abort_scan(struct wil6210_priv *wil)
|
||||
{
|
||||
int rc;
|
||||
|
||||
wil_dbg_wmi(wil, "sending WMI_ABORT_SCAN_CMDID\n");
|
||||
|
||||
rc = wmi_send(wil, WMI_ABORT_SCAN_CMDID, NULL, 0);
|
||||
if (rc)
|
||||
wil_err(wil, "Failed to abort scan (%d)\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void wmi_event_flush(struct wil6210_priv *wil)
|
||||
{
|
||||
struct pending_wmi_event *evt, *t;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#define WMI_MAC_LEN (6)
|
||||
#define WMI_PROX_RANGE_NUM (3)
|
||||
#define WMI_MAX_LOSS_DMG_BEACONS (20)
|
||||
#define MAX_NUM_OF_SECTORS (128)
|
||||
|
||||
/* Mailbox interface
|
||||
* used for commands and events
|
||||
|
@ -51,8 +52,10 @@ enum wmi_mid {
|
|||
* the host
|
||||
*/
|
||||
enum wmi_fw_capability {
|
||||
WMI_FW_CAPABILITY_FTM = 0,
|
||||
WMI_FW_CAPABILITY_PS_CONFIG = 1,
|
||||
WMI_FW_CAPABILITY_FTM = 0,
|
||||
WMI_FW_CAPABILITY_PS_CONFIG = 1,
|
||||
WMI_FW_CAPABILITY_RF_SECTORS = 2,
|
||||
WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT = 3,
|
||||
WMI_FW_CAPABILITY_MAX,
|
||||
};
|
||||
|
||||
|
@ -66,137 +69,149 @@ struct wmi_cmd_hdr {
|
|||
|
||||
/* List of Commands */
|
||||
enum wmi_command_id {
|
||||
WMI_CONNECT_CMDID = 0x01,
|
||||
WMI_DISCONNECT_CMDID = 0x03,
|
||||
WMI_DISCONNECT_STA_CMDID = 0x04,
|
||||
WMI_START_SCAN_CMDID = 0x07,
|
||||
WMI_SET_BSS_FILTER_CMDID = 0x09,
|
||||
WMI_SET_PROBED_SSID_CMDID = 0x0A,
|
||||
WMI_SET_LISTEN_INT_CMDID = 0x0B,
|
||||
WMI_BCON_CTRL_CMDID = 0x0F,
|
||||
WMI_ADD_CIPHER_KEY_CMDID = 0x16,
|
||||
WMI_DELETE_CIPHER_KEY_CMDID = 0x17,
|
||||
WMI_PCP_CONF_CMDID = 0x18,
|
||||
WMI_SET_APPIE_CMDID = 0x3F,
|
||||
WMI_SET_WSC_STATUS_CMDID = 0x41,
|
||||
WMI_PXMT_RANGE_CFG_CMDID = 0x42,
|
||||
WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x43,
|
||||
WMI_MEM_READ_CMDID = 0x800,
|
||||
WMI_MEM_WR_CMDID = 0x801,
|
||||
WMI_ECHO_CMDID = 0x803,
|
||||
WMI_DEEP_ECHO_CMDID = 0x804,
|
||||
WMI_CONFIG_MAC_CMDID = 0x805,
|
||||
WMI_CONFIG_PHY_DEBUG_CMDID = 0x806,
|
||||
WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x808,
|
||||
WMI_PHY_GET_STATISTICS_CMDID = 0x809,
|
||||
WMI_FS_TUNE_CMDID = 0x80A,
|
||||
WMI_CORR_MEASURE_CMDID = 0x80B,
|
||||
WMI_READ_RSSI_CMDID = 0x80C,
|
||||
WMI_TEMP_SENSE_CMDID = 0x80E,
|
||||
WMI_DC_CALIB_CMDID = 0x80F,
|
||||
WMI_SEND_TONE_CMDID = 0x810,
|
||||
WMI_IQ_TX_CALIB_CMDID = 0x811,
|
||||
WMI_IQ_RX_CALIB_CMDID = 0x812,
|
||||
WMI_SET_UCODE_IDLE_CMDID = 0x813,
|
||||
WMI_SET_WORK_MODE_CMDID = 0x815,
|
||||
WMI_LO_LEAKAGE_CALIB_CMDID = 0x816,
|
||||
WMI_MARLON_R_READ_CMDID = 0x818,
|
||||
WMI_MARLON_R_WRITE_CMDID = 0x819,
|
||||
WMI_MARLON_R_TXRX_SEL_CMDID = 0x81A,
|
||||
MAC_IO_STATIC_PARAMS_CMDID = 0x81B,
|
||||
MAC_IO_DYNAMIC_PARAMS_CMDID = 0x81C,
|
||||
WMI_SILENT_RSSI_CALIB_CMDID = 0x81D,
|
||||
WMI_RF_RX_TEST_CMDID = 0x81E,
|
||||
WMI_CFG_RX_CHAIN_CMDID = 0x820,
|
||||
WMI_VRING_CFG_CMDID = 0x821,
|
||||
WMI_BCAST_VRING_CFG_CMDID = 0x822,
|
||||
WMI_VRING_BA_EN_CMDID = 0x823,
|
||||
WMI_VRING_BA_DIS_CMDID = 0x824,
|
||||
WMI_RCP_ADDBA_RESP_CMDID = 0x825,
|
||||
WMI_RCP_DELBA_CMDID = 0x826,
|
||||
WMI_SET_SSID_CMDID = 0x827,
|
||||
WMI_GET_SSID_CMDID = 0x828,
|
||||
WMI_SET_PCP_CHANNEL_CMDID = 0x829,
|
||||
WMI_GET_PCP_CHANNEL_CMDID = 0x82A,
|
||||
WMI_SW_TX_REQ_CMDID = 0x82B,
|
||||
WMI_READ_MAC_RXQ_CMDID = 0x830,
|
||||
WMI_READ_MAC_TXQ_CMDID = 0x831,
|
||||
WMI_WRITE_MAC_RXQ_CMDID = 0x832,
|
||||
WMI_WRITE_MAC_TXQ_CMDID = 0x833,
|
||||
WMI_WRITE_MAC_XQ_FIELD_CMDID = 0x834,
|
||||
WMI_MLME_PUSH_CMDID = 0x835,
|
||||
WMI_BEAMFORMING_MGMT_CMDID = 0x836,
|
||||
WMI_BF_TXSS_MGMT_CMDID = 0x837,
|
||||
WMI_BF_SM_MGMT_CMDID = 0x838,
|
||||
WMI_BF_RXSS_MGMT_CMDID = 0x839,
|
||||
WMI_BF_TRIG_CMDID = 0x83A,
|
||||
WMI_LINK_MAINTAIN_CFG_WRITE_CMDID = 0x842,
|
||||
WMI_LINK_MAINTAIN_CFG_READ_CMDID = 0x843,
|
||||
WMI_SET_SECTORS_CMDID = 0x849,
|
||||
WMI_MAINTAIN_PAUSE_CMDID = 0x850,
|
||||
WMI_MAINTAIN_RESUME_CMDID = 0x851,
|
||||
WMI_RS_MGMT_CMDID = 0x852,
|
||||
WMI_RF_MGMT_CMDID = 0x853,
|
||||
WMI_THERMAL_THROTTLING_CTRL_CMDID = 0x854,
|
||||
WMI_THERMAL_THROTTLING_GET_STATUS_CMDID = 0x855,
|
||||
WMI_OTP_READ_CMDID = 0x856,
|
||||
WMI_OTP_WRITE_CMDID = 0x857,
|
||||
WMI_LED_CFG_CMDID = 0x858,
|
||||
WMI_CONNECT_CMDID = 0x01,
|
||||
WMI_DISCONNECT_CMDID = 0x03,
|
||||
WMI_DISCONNECT_STA_CMDID = 0x04,
|
||||
WMI_START_SCAN_CMDID = 0x07,
|
||||
WMI_SET_BSS_FILTER_CMDID = 0x09,
|
||||
WMI_SET_PROBED_SSID_CMDID = 0x0A,
|
||||
WMI_SET_LISTEN_INT_CMDID = 0x0B,
|
||||
WMI_BCON_CTRL_CMDID = 0x0F,
|
||||
WMI_ADD_CIPHER_KEY_CMDID = 0x16,
|
||||
WMI_DELETE_CIPHER_KEY_CMDID = 0x17,
|
||||
WMI_PCP_CONF_CMDID = 0x18,
|
||||
WMI_SET_APPIE_CMDID = 0x3F,
|
||||
WMI_SET_WSC_STATUS_CMDID = 0x41,
|
||||
WMI_PXMT_RANGE_CFG_CMDID = 0x42,
|
||||
WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x43,
|
||||
WMI_MEM_READ_CMDID = 0x800,
|
||||
WMI_MEM_WR_CMDID = 0x801,
|
||||
WMI_ECHO_CMDID = 0x803,
|
||||
WMI_DEEP_ECHO_CMDID = 0x804,
|
||||
WMI_CONFIG_MAC_CMDID = 0x805,
|
||||
WMI_CONFIG_PHY_DEBUG_CMDID = 0x806,
|
||||
WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x808,
|
||||
WMI_PHY_GET_STATISTICS_CMDID = 0x809,
|
||||
WMI_FS_TUNE_CMDID = 0x80A,
|
||||
WMI_CORR_MEASURE_CMDID = 0x80B,
|
||||
WMI_READ_RSSI_CMDID = 0x80C,
|
||||
WMI_TEMP_SENSE_CMDID = 0x80E,
|
||||
WMI_DC_CALIB_CMDID = 0x80F,
|
||||
WMI_SEND_TONE_CMDID = 0x810,
|
||||
WMI_IQ_TX_CALIB_CMDID = 0x811,
|
||||
WMI_IQ_RX_CALIB_CMDID = 0x812,
|
||||
WMI_SET_UCODE_IDLE_CMDID = 0x813,
|
||||
WMI_SET_WORK_MODE_CMDID = 0x815,
|
||||
WMI_LO_LEAKAGE_CALIB_CMDID = 0x816,
|
||||
WMI_MARLON_R_READ_CMDID = 0x818,
|
||||
WMI_MARLON_R_WRITE_CMDID = 0x819,
|
||||
WMI_MARLON_R_TXRX_SEL_CMDID = 0x81A,
|
||||
MAC_IO_STATIC_PARAMS_CMDID = 0x81B,
|
||||
MAC_IO_DYNAMIC_PARAMS_CMDID = 0x81C,
|
||||
WMI_SILENT_RSSI_CALIB_CMDID = 0x81D,
|
||||
WMI_RF_RX_TEST_CMDID = 0x81E,
|
||||
WMI_CFG_RX_CHAIN_CMDID = 0x820,
|
||||
WMI_VRING_CFG_CMDID = 0x821,
|
||||
WMI_BCAST_VRING_CFG_CMDID = 0x822,
|
||||
WMI_VRING_BA_EN_CMDID = 0x823,
|
||||
WMI_VRING_BA_DIS_CMDID = 0x824,
|
||||
WMI_RCP_ADDBA_RESP_CMDID = 0x825,
|
||||
WMI_RCP_DELBA_CMDID = 0x826,
|
||||
WMI_SET_SSID_CMDID = 0x827,
|
||||
WMI_GET_SSID_CMDID = 0x828,
|
||||
WMI_SET_PCP_CHANNEL_CMDID = 0x829,
|
||||
WMI_GET_PCP_CHANNEL_CMDID = 0x82A,
|
||||
WMI_SW_TX_REQ_CMDID = 0x82B,
|
||||
WMI_READ_MAC_RXQ_CMDID = 0x830,
|
||||
WMI_READ_MAC_TXQ_CMDID = 0x831,
|
||||
WMI_WRITE_MAC_RXQ_CMDID = 0x832,
|
||||
WMI_WRITE_MAC_TXQ_CMDID = 0x833,
|
||||
WMI_WRITE_MAC_XQ_FIELD_CMDID = 0x834,
|
||||
WMI_MLME_PUSH_CMDID = 0x835,
|
||||
WMI_BEAMFORMING_MGMT_CMDID = 0x836,
|
||||
WMI_BF_TXSS_MGMT_CMDID = 0x837,
|
||||
WMI_BF_SM_MGMT_CMDID = 0x838,
|
||||
WMI_BF_RXSS_MGMT_CMDID = 0x839,
|
||||
WMI_BF_TRIG_CMDID = 0x83A,
|
||||
WMI_LINK_MAINTAIN_CFG_WRITE_CMDID = 0x842,
|
||||
WMI_LINK_MAINTAIN_CFG_READ_CMDID = 0x843,
|
||||
WMI_SET_SECTORS_CMDID = 0x849,
|
||||
WMI_MAINTAIN_PAUSE_CMDID = 0x850,
|
||||
WMI_MAINTAIN_RESUME_CMDID = 0x851,
|
||||
WMI_RS_MGMT_CMDID = 0x852,
|
||||
WMI_RF_MGMT_CMDID = 0x853,
|
||||
WMI_THERMAL_THROTTLING_CTRL_CMDID = 0x854,
|
||||
WMI_THERMAL_THROTTLING_GET_STATUS_CMDID = 0x855,
|
||||
WMI_OTP_READ_CMDID = 0x856,
|
||||
WMI_OTP_WRITE_CMDID = 0x857,
|
||||
WMI_LED_CFG_CMDID = 0x858,
|
||||
/* Performance monitoring commands */
|
||||
WMI_BF_CTRL_CMDID = 0x862,
|
||||
WMI_NOTIFY_REQ_CMDID = 0x863,
|
||||
WMI_GET_STATUS_CMDID = 0x864,
|
||||
WMI_GET_RF_STATUS_CMDID = 0x866,
|
||||
WMI_GET_BASEBAND_TYPE_CMDID = 0x867,
|
||||
WMI_UNIT_TEST_CMDID = 0x900,
|
||||
WMI_HICCUP_CMDID = 0x901,
|
||||
WMI_FLASH_READ_CMDID = 0x902,
|
||||
WMI_FLASH_WRITE_CMDID = 0x903,
|
||||
WMI_BF_CTRL_CMDID = 0x862,
|
||||
WMI_NOTIFY_REQ_CMDID = 0x863,
|
||||
WMI_GET_STATUS_CMDID = 0x864,
|
||||
WMI_GET_RF_STATUS_CMDID = 0x866,
|
||||
WMI_GET_BASEBAND_TYPE_CMDID = 0x867,
|
||||
WMI_UNIT_TEST_CMDID = 0x900,
|
||||
WMI_HICCUP_CMDID = 0x901,
|
||||
WMI_FLASH_READ_CMDID = 0x902,
|
||||
WMI_FLASH_WRITE_CMDID = 0x903,
|
||||
/* Power management */
|
||||
WMI_TRAFFIC_DEFERRAL_CMDID = 0x904,
|
||||
WMI_TRAFFIC_RESUME_CMDID = 0x905,
|
||||
WMI_TRAFFIC_DEFERRAL_CMDID = 0x904,
|
||||
WMI_TRAFFIC_RESUME_CMDID = 0x905,
|
||||
/* P2P */
|
||||
WMI_P2P_CFG_CMDID = 0x910,
|
||||
WMI_PORT_ALLOCATE_CMDID = 0x911,
|
||||
WMI_PORT_DELETE_CMDID = 0x912,
|
||||
WMI_POWER_MGMT_CFG_CMDID = 0x913,
|
||||
WMI_START_LISTEN_CMDID = 0x914,
|
||||
WMI_START_SEARCH_CMDID = 0x915,
|
||||
WMI_DISCOVERY_START_CMDID = 0x916,
|
||||
WMI_DISCOVERY_STOP_CMDID = 0x917,
|
||||
WMI_PCP_START_CMDID = 0x918,
|
||||
WMI_PCP_STOP_CMDID = 0x919,
|
||||
WMI_GET_PCP_FACTOR_CMDID = 0x91B,
|
||||
WMI_P2P_CFG_CMDID = 0x910,
|
||||
WMI_PORT_ALLOCATE_CMDID = 0x911,
|
||||
WMI_PORT_DELETE_CMDID = 0x912,
|
||||
WMI_POWER_MGMT_CFG_CMDID = 0x913,
|
||||
WMI_START_LISTEN_CMDID = 0x914,
|
||||
WMI_START_SEARCH_CMDID = 0x915,
|
||||
WMI_DISCOVERY_START_CMDID = 0x916,
|
||||
WMI_DISCOVERY_STOP_CMDID = 0x917,
|
||||
WMI_PCP_START_CMDID = 0x918,
|
||||
WMI_PCP_STOP_CMDID = 0x919,
|
||||
WMI_GET_PCP_FACTOR_CMDID = 0x91B,
|
||||
/* Power Save Configuration Commands */
|
||||
WMI_PS_DEV_PROFILE_CFG_CMDID = 0x91C,
|
||||
WMI_PS_DEV_PROFILE_CFG_CMDID = 0x91C,
|
||||
/* Not supported yet */
|
||||
WMI_PS_DEV_CFG_CMDID = 0x91D,
|
||||
WMI_PS_DEV_CFG_CMDID = 0x91D,
|
||||
/* Not supported yet */
|
||||
WMI_PS_DEV_CFG_READ_CMDID = 0x91E,
|
||||
WMI_PS_DEV_CFG_READ_CMDID = 0x91E,
|
||||
/* Per MAC Power Save Configuration commands
|
||||
* Not supported yet
|
||||
*/
|
||||
WMI_PS_MID_CFG_CMDID = 0x91F,
|
||||
WMI_PS_MID_CFG_CMDID = 0x91F,
|
||||
/* Not supported yet */
|
||||
WMI_PS_MID_CFG_READ_CMDID = 0x920,
|
||||
WMI_RS_CFG_CMDID = 0x921,
|
||||
WMI_GET_DETAILED_RS_RES_CMDID = 0x922,
|
||||
WMI_AOA_MEAS_CMDID = 0x923,
|
||||
WMI_TOF_SESSION_START_CMDID = 0x991,
|
||||
WMI_TOF_GET_CAPABILITIES_CMDID = 0x992,
|
||||
WMI_TOF_SET_LCR_CMDID = 0x993,
|
||||
WMI_TOF_SET_LCI_CMDID = 0x994,
|
||||
WMI_TOF_CHANNEL_INFO_CMDID = 0x995,
|
||||
WMI_SET_MAC_ADDRESS_CMDID = 0xF003,
|
||||
WMI_ABORT_SCAN_CMDID = 0xF007,
|
||||
WMI_SET_PROMISCUOUS_MODE_CMDID = 0xF041,
|
||||
WMI_GET_PMK_CMDID = 0xF048,
|
||||
WMI_SET_PASSPHRASE_CMDID = 0xF049,
|
||||
WMI_SEND_ASSOC_RES_CMDID = 0xF04A,
|
||||
WMI_SET_ASSOC_REQ_RELAY_CMDID = 0xF04B,
|
||||
WMI_MAC_ADDR_REQ_CMDID = 0xF04D,
|
||||
WMI_FW_VER_CMDID = 0xF04E,
|
||||
WMI_PMC_CMDID = 0xF04F,
|
||||
WMI_PS_MID_CFG_READ_CMDID = 0x920,
|
||||
WMI_RS_CFG_CMDID = 0x921,
|
||||
WMI_GET_DETAILED_RS_RES_CMDID = 0x922,
|
||||
WMI_AOA_MEAS_CMDID = 0x923,
|
||||
WMI_SET_MGMT_RETRY_LIMIT_CMDID = 0x930,
|
||||
WMI_GET_MGMT_RETRY_LIMIT_CMDID = 0x931,
|
||||
WMI_TOF_SESSION_START_CMDID = 0x991,
|
||||
WMI_TOF_GET_CAPABILITIES_CMDID = 0x992,
|
||||
WMI_TOF_SET_LCR_CMDID = 0x993,
|
||||
WMI_TOF_SET_LCI_CMDID = 0x994,
|
||||
WMI_TOF_CHANNEL_INFO_CMDID = 0x995,
|
||||
WMI_TOF_SET_TX_RX_OFFSET_CMDID = 0x997,
|
||||
WMI_TOF_GET_TX_RX_OFFSET_CMDID = 0x998,
|
||||
WMI_GET_RF_SECTOR_PARAMS_CMDID = 0x9A0,
|
||||
WMI_SET_RF_SECTOR_PARAMS_CMDID = 0x9A1,
|
||||
WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID = 0x9A2,
|
||||
WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID = 0x9A3,
|
||||
WMI_SET_RF_SECTOR_ON_CMDID = 0x9A4,
|
||||
WMI_PRIO_TX_SECTORS_ORDER_CMDID = 0x9A5,
|
||||
WMI_PRIO_TX_SECTORS_NUMBER_CMDID = 0x9A6,
|
||||
WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_CMDID = 0x9A7,
|
||||
WMI_SET_MAC_ADDRESS_CMDID = 0xF003,
|
||||
WMI_ABORT_SCAN_CMDID = 0xF007,
|
||||
WMI_SET_PROMISCUOUS_MODE_CMDID = 0xF041,
|
||||
WMI_GET_PMK_CMDID = 0xF048,
|
||||
WMI_SET_PASSPHRASE_CMDID = 0xF049,
|
||||
WMI_SEND_ASSOC_RES_CMDID = 0xF04A,
|
||||
WMI_SET_ASSOC_REQ_RELAY_CMDID = 0xF04B,
|
||||
WMI_MAC_ADDR_REQ_CMDID = 0xF04D,
|
||||
WMI_FW_VER_CMDID = 0xF04E,
|
||||
WMI_PMC_CMDID = 0xF04F,
|
||||
};
|
||||
|
||||
/* WMI_CONNECT_CMDID */
|
||||
|
@ -879,6 +894,14 @@ struct wmi_aoa_meas_cmd {
|
|||
__le32 meas_rf_mask;
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_MGMT_RETRY_LIMIT_CMDID */
|
||||
struct wmi_set_mgmt_retry_limit_cmd {
|
||||
/* MAC retransmit limit for mgmt frames */
|
||||
u8 mgmt_retry_limit;
|
||||
/* alignment to 32b */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
enum wmi_tof_burst_duration {
|
||||
WMI_TOF_BURST_DURATION_250_USEC = 2,
|
||||
WMI_TOF_BURST_DURATION_500_USEC = 3,
|
||||
|
@ -942,6 +965,15 @@ struct wmi_tof_channel_info_cmd {
|
|||
__le32 channel_info_report_request;
|
||||
} __packed;
|
||||
|
||||
/* WMI_TOF_SET_TX_RX_OFFSET_CMDID */
|
||||
struct wmi_tof_set_tx_rx_offset_cmd {
|
||||
/* TX delay offset */
|
||||
__le32 tx_offset;
|
||||
/* RX delay offset */
|
||||
__le32 rx_offset;
|
||||
__le32 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* WMI Events
|
||||
* List of Events (target to host)
|
||||
*/
|
||||
|
@ -1035,12 +1067,24 @@ enum wmi_event_id {
|
|||
WMI_RS_CFG_DONE_EVENTID = 0x1921,
|
||||
WMI_GET_DETAILED_RS_RES_EVENTID = 0x1922,
|
||||
WMI_AOA_MEAS_EVENTID = 0x1923,
|
||||
WMI_SET_MGMT_RETRY_LIMIT_EVENTID = 0x1930,
|
||||
WMI_GET_MGMT_RETRY_LIMIT_EVENTID = 0x1931,
|
||||
WMI_TOF_SESSION_END_EVENTID = 0x1991,
|
||||
WMI_TOF_GET_CAPABILITIES_EVENTID = 0x1992,
|
||||
WMI_TOF_SET_LCR_EVENTID = 0x1993,
|
||||
WMI_TOF_SET_LCI_EVENTID = 0x1994,
|
||||
WMI_TOF_FTM_PER_DEST_RES_EVENTID = 0x1995,
|
||||
WMI_TOF_CHANNEL_INFO_EVENTID = 0x1996,
|
||||
WMI_TOF_SET_TX_RX_OFFSET_EVENTID = 0x1997,
|
||||
WMI_TOF_GET_TX_RX_OFFSET_EVENTID = 0x1998,
|
||||
WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID = 0x19A0,
|
||||
WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID = 0x19A1,
|
||||
WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID = 0x19A2,
|
||||
WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID = 0x19A3,
|
||||
WMI_SET_RF_SECTOR_ON_DONE_EVENTID = 0x19A4,
|
||||
WMI_PRIO_TX_SECTORS_ORDER_EVENTID = 0x19A5,
|
||||
WMI_PRIO_TX_SECTORS_NUMBER_EVENTID = 0x19A6,
|
||||
WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_EVENTID = 0x19A7,
|
||||
WMI_SET_CHANNEL_EVENTID = 0x9000,
|
||||
WMI_ASSOC_REQ_EVENTID = 0x9001,
|
||||
WMI_EAPOL_RX_EVENTID = 0x9002,
|
||||
|
@ -1166,6 +1210,7 @@ enum baseband_type {
|
|||
BASEBAND_SPARROW_M_B0 = 0x05,
|
||||
BASEBAND_SPARROW_M_C0 = 0x06,
|
||||
BASEBAND_SPARROW_M_D0 = 0x07,
|
||||
BASEBAND_TALYN_M_A0 = 0x08,
|
||||
};
|
||||
|
||||
/* WMI_GET_BASEBAND_TYPE_EVENTID */
|
||||
|
@ -2070,6 +2115,22 @@ struct wmi_aoa_meas_event {
|
|||
u8 meas_data[WMI_AOA_MAX_DATA_SIZE];
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_MGMT_RETRY_LIMIT_EVENTID */
|
||||
struct wmi_set_mgmt_retry_limit_event {
|
||||
/* enum wmi_fw_status */
|
||||
u8 status;
|
||||
/* alignment to 32b */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_GET_MGMT_RETRY_LIMIT_EVENTID */
|
||||
struct wmi_get_mgmt_retry_limit_event {
|
||||
/* MAC retransmit limit for mgmt frames */
|
||||
u8 mgmt_retry_limit;
|
||||
/* alignment to 32b */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_TOF_GET_CAPABILITIES_EVENTID */
|
||||
struct wmi_tof_get_capabilities_event {
|
||||
u8 ftm_capability;
|
||||
|
@ -2184,4 +2245,283 @@ struct wmi_tof_channel_info_event {
|
|||
u8 report[0];
|
||||
} __packed;
|
||||
|
||||
/* WMI_TOF_SET_TX_RX_OFFSET_EVENTID */
|
||||
struct wmi_tof_set_tx_rx_offset_event {
|
||||
/* enum wmi_fw_status */
|
||||
u8 status;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_TOF_GET_TX_RX_OFFSET_EVENTID */
|
||||
struct wmi_tof_get_tx_rx_offset_event {
|
||||
/* enum wmi_fw_status */
|
||||
u8 status;
|
||||
u8 reserved1[3];
|
||||
/* TX delay offset */
|
||||
__le32 tx_offset;
|
||||
/* RX delay offset */
|
||||
__le32 rx_offset;
|
||||
__le32 reserved2[2];
|
||||
} __packed;
|
||||
|
||||
/* Result status codes for WMI commands */
|
||||
enum wmi_rf_sector_status {
|
||||
WMI_RF_SECTOR_STATUS_SUCCESS = 0x00,
|
||||
WMI_RF_SECTOR_STATUS_BAD_PARAMETERS_ERROR = 0x01,
|
||||
WMI_RF_SECTOR_STATUS_BUSY_ERROR = 0x02,
|
||||
WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR = 0x03,
|
||||
};
|
||||
|
||||
/* Types of the RF sector (TX,RX) */
|
||||
enum wmi_rf_sector_type {
|
||||
WMI_RF_SECTOR_TYPE_RX = 0x00,
|
||||
WMI_RF_SECTOR_TYPE_TX = 0x01,
|
||||
};
|
||||
|
||||
/* Content of RF Sector (six 32-bits registers) */
|
||||
struct wmi_rf_sector_info {
|
||||
/* Phase values for RF Chains[15-0] (2bits per RF chain) */
|
||||
__le32 psh_hi;
|
||||
/* Phase values for RF Chains[31-16] (2bits per RF chain) */
|
||||
__le32 psh_lo;
|
||||
/* ETYPE Bit0 for all RF chains[31-0] - bit0 of Edge amplifier gain
|
||||
* index
|
||||
*/
|
||||
__le32 etype0;
|
||||
/* ETYPE Bit1 for all RF chains[31-0] - bit1 of Edge amplifier gain
|
||||
* index
|
||||
*/
|
||||
__le32 etype1;
|
||||
/* ETYPE Bit2 for all RF chains[31-0] - bit2 of Edge amplifier gain
|
||||
* index
|
||||
*/
|
||||
__le32 etype2;
|
||||
/* D-Type values (3bits each) for 8 Distribution amplifiers + X16
|
||||
* switch bits
|
||||
*/
|
||||
__le32 dtype_swch_off;
|
||||
} __packed;
|
||||
|
||||
#define WMI_INVALID_RF_SECTOR_INDEX (0xFFFF)
|
||||
#define WMI_MAX_RF_MODULES_NUM (8)
|
||||
|
||||
/* WMI_GET_RF_SECTOR_PARAMS_CMD */
|
||||
struct wmi_get_rf_sector_params_cmd {
|
||||
/* Sector number to be retrieved */
|
||||
__le16 sector_idx;
|
||||
/* enum wmi_rf_sector_type - type of requested RF sector */
|
||||
u8 sector_type;
|
||||
/* bitmask vector specifying destination RF modules */
|
||||
u8 rf_modules_vec;
|
||||
} __packed;
|
||||
|
||||
/* \WMI_GET_RF_SECTOR_PARAMS_DONE_EVENT */
|
||||
struct wmi_get_rf_sector_params_done_event {
|
||||
/* result status of WMI_GET_RF_SECTOR_PARAMS_CMD (enum
|
||||
* wmi_rf_sector_status)
|
||||
*/
|
||||
u8 status;
|
||||
/* align next field to U64 boundary */
|
||||
u8 reserved[7];
|
||||
/* TSF timestamp when RF sectors where retrieved */
|
||||
__le64 tsf;
|
||||
/* Content of RF sector retrieved from each RF module */
|
||||
struct wmi_rf_sector_info sectors_info[WMI_MAX_RF_MODULES_NUM];
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_RF_SECTOR_PARAMS_CMD */
|
||||
struct wmi_set_rf_sector_params_cmd {
|
||||
/* Sector number to be retrieved */
|
||||
__le16 sector_idx;
|
||||
/* enum wmi_rf_sector_type - type of requested RF sector */
|
||||
u8 sector_type;
|
||||
/* bitmask vector specifying destination RF modules */
|
||||
u8 rf_modules_vec;
|
||||
/* Content of RF sector to be written to each RF module */
|
||||
struct wmi_rf_sector_info sectors_info[WMI_MAX_RF_MODULES_NUM];
|
||||
} __packed;
|
||||
|
||||
/* \WMI_SET_RF_SECTOR_PARAMS_DONE_EVENT */
|
||||
struct wmi_set_rf_sector_params_done_event {
|
||||
/* result status of WMI_SET_RF_SECTOR_PARAMS_CMD (enum
|
||||
* wmi_rf_sector_status)
|
||||
*/
|
||||
u8 status;
|
||||
} __packed;
|
||||
|
||||
/* WMI_GET_SELECTED_RF_SECTOR_INDEX_CMD - Get RF sector index selected by
|
||||
* TXSS/BRP for communication with specified CID
|
||||
*/
|
||||
struct wmi_get_selected_rf_sector_index_cmd {
|
||||
/* Connection/Station ID in [0:7] range */
|
||||
u8 cid;
|
||||
/* type of requested RF sector (enum wmi_rf_sector_type) */
|
||||
u8 sector_type;
|
||||
/* align to U32 boundary */
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* \WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENT - Returns retrieved RF sector
|
||||
* index selected by TXSS/BRP for communication with specified CID
|
||||
*/
|
||||
struct wmi_get_selected_rf_sector_index_done_event {
|
||||
/* Retrieved sector index selected in TXSS (for TX sector request) or
|
||||
* BRP (for RX sector request)
|
||||
*/
|
||||
__le16 sector_idx;
|
||||
/* result status of WMI_GET_SELECTED_RF_SECTOR_INDEX_CMD (enum
|
||||
* wmi_rf_sector_status)
|
||||
*/
|
||||
u8 status;
|
||||
/* align next field to U64 boundary */
|
||||
u8 reserved[5];
|
||||
/* TSF timestamp when result was retrieved */
|
||||
__le64 tsf;
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_SELECTED_RF_SECTOR_INDEX_CMD - Force RF sector index for
|
||||
* communication with specified CID. Assumes that TXSS/BRP is disabled by
|
||||
* other command
|
||||
*/
|
||||
struct wmi_set_selected_rf_sector_index_cmd {
|
||||
/* Connection/Station ID in [0:7] range */
|
||||
u8 cid;
|
||||
/* type of requested RF sector (enum wmi_rf_sector_type) */
|
||||
u8 sector_type;
|
||||
/* Forced sector index */
|
||||
__le16 sector_idx;
|
||||
} __packed;
|
||||
|
||||
/* \WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENT - Success/Fail status for
|
||||
* WMI_SET_SELECTED_RF_SECTOR_INDEX_CMD
|
||||
*/
|
||||
struct wmi_set_selected_rf_sector_index_done_event {
|
||||
/* result status of WMI_SET_SELECTED_RF_SECTOR_INDEX_CMD (enum
|
||||
* wmi_rf_sector_status)
|
||||
*/
|
||||
u8 status;
|
||||
/* align to U32 boundary */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_RF_SECTOR_ON_CMD - Activates specified sector for specified rf
|
||||
* modules
|
||||
*/
|
||||
struct wmi_set_rf_sector_on_cmd {
|
||||
/* Sector index to be activated */
|
||||
__le16 sector_idx;
|
||||
/* type of requested RF sector (enum wmi_rf_sector_type) */
|
||||
u8 sector_type;
|
||||
/* bitmask vector specifying destination RF modules */
|
||||
u8 rf_modules_vec;
|
||||
} __packed;
|
||||
|
||||
/* \WMI_SET_RF_SECTOR_ON_DONE_EVENT - Success/Fail status for
|
||||
* WMI_SET_RF_SECTOR_ON_CMD
|
||||
*/
|
||||
struct wmi_set_rf_sector_on_done_event {
|
||||
/* result status of WMI_SET_RF_SECTOR_ON_CMD (enum
|
||||
* wmi_rf_sector_status)
|
||||
*/
|
||||
u8 status;
|
||||
/* align to U32 boundary */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
enum wmi_sector_sweep_type {
|
||||
WMI_SECTOR_SWEEP_TYPE_TXSS = 0x00,
|
||||
WMI_SECTOR_SWEEP_TYPE_BCON = 0x01,
|
||||
WMI_SECTOR_SWEEP_TYPE_TXSS_AND_BCON = 0x02,
|
||||
WMI_SECTOR_SWEEP_TYPE_NUM = 0x03,
|
||||
};
|
||||
|
||||
/* WMI_PRIO_TX_SECTORS_ORDER_CMDID
|
||||
*
|
||||
* Set the order of TX sectors in TXSS and/or Beacon(AP).
|
||||
*
|
||||
* Returned event:
|
||||
* - WMI_PRIO_TX_SECTORS_ORDER_EVENTID
|
||||
*/
|
||||
struct wmi_prio_tx_sectors_order_cmd {
|
||||
/* tx sectors order to be applied, 0xFF for end of array */
|
||||
u8 tx_sectors_priority_array[MAX_NUM_OF_SECTORS];
|
||||
/* enum wmi_sector_sweep_type, TXSS and/or Beacon */
|
||||
u8 sector_sweep_type;
|
||||
/* needed only for TXSS configuration */
|
||||
u8 cid;
|
||||
/* alignment to 32b */
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* completion status codes */
|
||||
enum wmi_prio_tx_sectors_cmd_status {
|
||||
WMI_PRIO_TX_SECT_CMD_STATUS_SUCCESS = 0x00,
|
||||
WMI_PRIO_TX_SECT_CMD_STATUS_BAD_PARAM = 0x01,
|
||||
/* other error */
|
||||
WMI_PRIO_TX_SECT_CMD_STATUS_ERROR = 0x02,
|
||||
};
|
||||
|
||||
/* WMI_PRIO_TX_SECTORS_ORDER_EVENTID */
|
||||
struct wmi_prio_tx_sectors_order_event {
|
||||
/* enum wmi_prio_tx_sectors_cmd_status */
|
||||
u8 status;
|
||||
/* alignment to 32b */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
struct wmi_prio_tx_sectors_num_cmd {
|
||||
/* [0-128], 0 = No changes */
|
||||
u8 beacon_number_of_sectors;
|
||||
/* [0-128], 0 = No changes */
|
||||
u8 txss_number_of_sectors;
|
||||
/* [0-8] needed only for TXSS configuration */
|
||||
u8 cid;
|
||||
} __packed;
|
||||
|
||||
/* WMI_PRIO_TX_SECTORS_NUMBER_CMDID
|
||||
*
|
||||
* Set the number of active sectors in TXSS and/or Beacon.
|
||||
*
|
||||
* Returned event:
|
||||
* - WMI_PRIO_TX_SECTORS_NUMBER_EVENTID
|
||||
*/
|
||||
struct wmi_prio_tx_sectors_number_cmd {
|
||||
struct wmi_prio_tx_sectors_num_cmd active_sectors_num;
|
||||
/* alignment to 32b */
|
||||
u8 reserved;
|
||||
} __packed;
|
||||
|
||||
/* WMI_PRIO_TX_SECTORS_NUMBER_EVENTID */
|
||||
struct wmi_prio_tx_sectors_number_event {
|
||||
/* enum wmi_prio_tx_sectors_cmd_status */
|
||||
u8 status;
|
||||
/* alignment to 32b */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_CMDID
|
||||
*
|
||||
* Set default sectors order and number (hard coded in board file)
|
||||
* in TXSS and/or Beacon.
|
||||
*
|
||||
* Returned event:
|
||||
* - WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_EVENTID
|
||||
*/
|
||||
struct wmi_prio_tx_sectors_set_default_cfg_cmd {
|
||||
/* enum wmi_sector_sweep_type, TXSS and/or Beacon */
|
||||
u8 sector_sweep_type;
|
||||
/* needed only for TXSS configuration */
|
||||
u8 cid;
|
||||
/* alignment to 32b */
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_EVENTID */
|
||||
struct wmi_prio_tx_sectors_set_default_cfg_event {
|
||||
/* enum wmi_prio_tx_sectors_cmd_status */
|
||||
u8 status;
|
||||
/* alignment to 32b */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
#endif /* __WILOCITY_WMI_H__ */
|
||||
|
|
Loading…
Reference in New Issue