ath6kl: support TX error rate notification
The ath6kl firmware can monitor a connection and report when a certain TX failure threshold is crossed. Support this configuration and event reporting on compatible firmwares. Signed-off-by: Thomas Pedersen <c_tpeder@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
bf744f1178
commit
279b2862ee
|
@ -3326,6 +3326,27 @@ static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
|
||||||
mask);
|
mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
|
||||||
|
struct net_device *dev,
|
||||||
|
u32 rate, u32 pkts, u32 intvl)
|
||||||
|
{
|
||||||
|
struct ath6kl *ar = ath6kl_priv(dev);
|
||||||
|
struct ath6kl_vif *vif = netdev_priv(dev);
|
||||||
|
|
||||||
|
if (vif->nw_type != INFRA_NETWORK ||
|
||||||
|
!test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if (vif->sme_state != SME_CONNECTED)
|
||||||
|
return -ENOTCONN;
|
||||||
|
|
||||||
|
/* save this since the firmware won't report the interval */
|
||||||
|
vif->txe_intvl = intvl;
|
||||||
|
|
||||||
|
return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
|
||||||
|
rate, pkts, intvl);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ieee80211_txrx_stypes
|
static const struct ieee80211_txrx_stypes
|
||||||
ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
|
ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
|
||||||
[NL80211_IFTYPE_STATION] = {
|
[NL80211_IFTYPE_STATION] = {
|
||||||
|
@ -3392,6 +3413,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
|
||||||
.sched_scan_start = ath6kl_cfg80211_sscan_start,
|
.sched_scan_start = ath6kl_cfg80211_sscan_start,
|
||||||
.sched_scan_stop = ath6kl_cfg80211_sscan_stop,
|
.sched_scan_stop = ath6kl_cfg80211_sscan_stop,
|
||||||
.set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
|
.set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
|
||||||
|
.set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
|
||||||
};
|
};
|
||||||
|
|
||||||
void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
|
void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
|
||||||
|
|
|
@ -121,6 +121,9 @@ enum ath6kl_fw_capability {
|
||||||
/* FW sets mac_addr[4] ^= 0x80 for newly created interfaces */
|
/* FW sets mac_addr[4] ^= 0x80 for newly created interfaces */
|
||||||
ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
|
ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
|
||||||
|
|
||||||
|
/* Firmware supports TX error rate notification */
|
||||||
|
ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY,
|
||||||
|
|
||||||
/* this needs to be last */
|
/* this needs to be last */
|
||||||
ATH6KL_FW_CAPABILITY_MAX,
|
ATH6KL_FW_CAPABILITY_MAX,
|
||||||
};
|
};
|
||||||
|
@ -593,6 +596,7 @@ struct ath6kl_vif {
|
||||||
u16 assoc_bss_beacon_int;
|
u16 assoc_bss_beacon_int;
|
||||||
u16 listen_intvl_t;
|
u16 listen_intvl_t;
|
||||||
u16 bmiss_time_t;
|
u16 bmiss_time_t;
|
||||||
|
u32 txe_intvl;
|
||||||
u16 bg_scan_period;
|
u16 bg_scan_period;
|
||||||
u8 assoc_bss_dtim_period;
|
u8 assoc_bss_dtim_period;
|
||||||
struct net_device_stats net_stats;
|
struct net_device_stats net_stats;
|
||||||
|
|
|
@ -1531,6 +1531,50 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ath6kl_wmi_txe_notify_event_rx(struct wmi *wmi, u8 *datap, int len,
|
||||||
|
struct ath6kl_vif *vif)
|
||||||
|
{
|
||||||
|
struct wmi_txe_notify_event *ev;
|
||||||
|
u32 rate, pkts;
|
||||||
|
|
||||||
|
if (len < sizeof(*ev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (vif->sme_state != SME_CONNECTED)
|
||||||
|
return -ENOTCONN;
|
||||||
|
|
||||||
|
ev = (struct wmi_txe_notify_event *) datap;
|
||||||
|
rate = le32_to_cpu(ev->rate);
|
||||||
|
pkts = le32_to_cpu(ev->pkts);
|
||||||
|
|
||||||
|
ath6kl_dbg(ATH6KL_DBG_WMI, "TXE notify event: peer %pM rate %d% pkts %d intvl %ds\n",
|
||||||
|
vif->bssid, rate, pkts, vif->txe_intvl);
|
||||||
|
|
||||||
|
cfg80211_cqm_txe_notify(vif->ndev, vif->bssid, pkts,
|
||||||
|
rate, vif->txe_intvl, GFP_KERNEL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx,
|
||||||
|
u32 rate, u32 pkts, u32 intvl)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb;
|
||||||
|
struct wmi_txe_notify_cmd *cmd;
|
||||||
|
|
||||||
|
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
|
||||||
|
if (!skb)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
cmd = (struct wmi_txe_notify_cmd *) skb->data;
|
||||||
|
cmd->rate = cpu_to_le32(rate);
|
||||||
|
cmd->pkts = cpu_to_le32(pkts);
|
||||||
|
cmd->intvl = cpu_to_le32(intvl);
|
||||||
|
|
||||||
|
return ath6kl_wmi_cmd_send(wmi, idx, skb, WMI_SET_TXE_NOTIFY_CMDID,
|
||||||
|
NO_SYNC_WMIFLAG);
|
||||||
|
}
|
||||||
|
|
||||||
int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi)
|
int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
@ -3768,6 +3812,9 @@ static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id,
|
||||||
case WMI_RX_ACTION_EVENTID:
|
case WMI_RX_ACTION_EVENTID:
|
||||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n");
|
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n");
|
||||||
return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif);
|
return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif);
|
||||||
|
case WMI_TXE_NOTIFY_EVENTID:
|
||||||
|
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TXE_NOTIFY_EVENTID\n");
|
||||||
|
return ath6kl_wmi_txe_notify_event_rx(wmi, datap, len, vif);
|
||||||
default:
|
default:
|
||||||
ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id);
|
ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -632,6 +632,12 @@ enum wmi_cmd_id {
|
||||||
WMI_SET_REGDOMAIN_CMDID,
|
WMI_SET_REGDOMAIN_CMDID,
|
||||||
|
|
||||||
WMI_SET_RSSI_FILTER_CMDID,
|
WMI_SET_RSSI_FILTER_CMDID,
|
||||||
|
|
||||||
|
WMI_SET_KEEP_ALIVE_EXT,
|
||||||
|
|
||||||
|
WMI_VOICE_DETECTION_ENABLE_CMDID,
|
||||||
|
|
||||||
|
WMI_SET_TXE_NOTIFY_CMDID,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum wmi_mgmt_frame_type {
|
enum wmi_mgmt_frame_type {
|
||||||
|
@ -1464,6 +1470,20 @@ enum wmi_event_id {
|
||||||
WMI_P2P_CAPABILITIES_EVENTID,
|
WMI_P2P_CAPABILITIES_EVENTID,
|
||||||
WMI_RX_ACTION_EVENTID,
|
WMI_RX_ACTION_EVENTID,
|
||||||
WMI_P2P_INFO_EVENTID,
|
WMI_P2P_INFO_EVENTID,
|
||||||
|
|
||||||
|
/* WPS Events */
|
||||||
|
WMI_WPS_GET_STATUS_EVENTID,
|
||||||
|
WMI_WPS_PROFILE_EVENTID,
|
||||||
|
|
||||||
|
/* more P2P events */
|
||||||
|
WMI_NOA_INFO_EVENTID,
|
||||||
|
WMI_OPPPS_INFO_EVENTID,
|
||||||
|
WMI_PORT_STATUS_EVENTID,
|
||||||
|
|
||||||
|
/* 802.11w */
|
||||||
|
WMI_GET_RSN_CAP_EVENTID,
|
||||||
|
|
||||||
|
WMI_TXE_NOTIFY_EVENTID,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wmi_ready_event_2 {
|
struct wmi_ready_event_2 {
|
||||||
|
@ -2096,6 +2116,19 @@ struct wmi_del_wow_pattern_cmd {
|
||||||
__le16 filter_id;
|
__le16 filter_id;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/* WMI_SET_TXE_NOTIFY_CMDID */
|
||||||
|
struct wmi_txe_notify_cmd {
|
||||||
|
__le32 rate;
|
||||||
|
__le32 pkts;
|
||||||
|
__le32 intvl;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/* WMI_TXE_NOTIFY_EVENTID */
|
||||||
|
struct wmi_txe_notify_event {
|
||||||
|
__le32 rate;
|
||||||
|
__le32 pkts;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/* WMI_SET_AKMP_PARAMS_CMD */
|
/* WMI_SET_AKMP_PARAMS_CMD */
|
||||||
|
|
||||||
struct wmi_pmkid {
|
struct wmi_pmkid {
|
||||||
|
@ -2610,6 +2643,8 @@ int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
|
||||||
int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
|
int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
|
||||||
u8 *filter, bool add_filter);
|
u8 *filter, bool add_filter);
|
||||||
int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable);
|
int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable);
|
||||||
|
int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx,
|
||||||
|
u32 rate, u32 pkts, u32 intvl);
|
||||||
|
|
||||||
/* AP mode uAPSD */
|
/* AP mode uAPSD */
|
||||||
int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);
|
int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);
|
||||||
|
|
Loading…
Reference in New Issue