build/patch/kernel/archive/sunxi-6.4/patches.megous/8723cs-Fix-the-RSSI-monitor-implementation.patch

254 lines
10 KiB
Diff

From 1ec550443add6c355bee0a0b6cf6bc3f4a9a5f91 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megi@xff.cz>
Date: Thu, 30 Mar 2023 15:45:50 +0200
Subject: [PATCH 149/469] 8723cs: Fix the RSSI monitor implementation
We need to send both signal LOW and signal HIGH events.
While we're at it, implement hystheresis, too.
Signed-off-by: Ondrej Jirman <megi@xff.cz>
---
.../rtl8723cs/os_dep/linux/ioctl_cfg80211.c | 17 ++-
.../rtl8723cs/os_dep/linux/ioctl_cfg80211.h | 9 +-
.../rtl8723cs/os_dep/linux/rtw_cfgvendor.c | 139 ++++--------------
3 files changed, 44 insertions(+), 121 deletions(-)
diff --git a/drivers/staging/rtl8723cs/os_dep/linux/ioctl_cfg80211.c b/drivers/staging/rtl8723cs/os_dep/linux/ioctl_cfg80211.c
index 4067369e65f1..7eea58711252 100644
--- a/drivers/staging/rtl8723cs/os_dep/linux/ioctl_cfg80211.c
+++ b/drivers/staging/rtl8723cs/os_dep/linux/ioctl_cfg80211.c
@@ -3405,7 +3405,7 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy
&& rtw_mi_busy_traffic_check(padapter)) {
RTW_WARN(FUNC_ADPT_FMT ": scan abort!! BusyTraffic\n",
FUNC_ADPT_ARG(padapter));
- need_indicate_scan_done = _TRUE;
+ need_indicate_scan_done = _TRUE;
goto check_need_indicate_scan_done;
}
#endif /* RTW_BUSY_DENY_SCAN */
@@ -3518,14 +3518,15 @@ static void cfg80211_rtw_abort_scan(struct wiphy *wiphy,
static int cfg80211_rtw_set_cqm_rssi_config(struct wiphy *wiphy,
struct net_device *dev,
- s32 rssi_thold,
- u32 rssi_hyst)
+ s32 rssi_thold,
+ u32 rssi_hyst)
{
_adapter *padapter = GET_PRIMARY_ADAPTER(wiphy_to_adapter(wiphy));
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
- pwdev_priv->rssi_monitor_max = 0;
- pwdev_priv->rssi_monitor_min = rssi_thold;
+ pwdev_priv->rssi_monitor_th = rssi_thold;
+ pwdev_priv->rssi_monitor_hyst = rssi_hyst;
+ pwdev_priv->rssi_monitor_state = 1;
pwdev_priv->rssi_monitor_enable = 1;
RTW_INFO("%s, rssi_thold=%d, rssi_hyst=%d\n", __func__, rssi_thold, rssi_hyst);
return 0;
@@ -10599,12 +10600,12 @@ int rtw_wdev_alloc(_adapter *padapter, struct wiphy *wiphy)
#endif
#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR
+ pwdev_priv->rssi_monitor_th = 0;
+ pwdev_priv->rssi_monitor_hyst = 0;
+ pwdev_priv->rssi_monitor_state = 1;
pwdev_priv->rssi_monitor_enable = 0;
- pwdev_priv->rssi_monitor_max = 0;
- pwdev_priv->rssi_monitor_min = 0;
#endif
-
exit:
return ret;
}
diff --git a/drivers/staging/rtl8723cs/os_dep/linux/ioctl_cfg80211.h b/drivers/staging/rtl8723cs/os_dep/linux/ioctl_cfg80211.h
index 22018caa33fe..a2b4be249814 100644
--- a/drivers/staging/rtl8723cs/os_dep/linux/ioctl_cfg80211.h
+++ b/drivers/staging/rtl8723cs/os_dep/linux/ioctl_cfg80211.h
@@ -191,9 +191,12 @@ struct rtw_wdev_priv {
#endif
#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR
- s8 rssi_monitor_max;
- s8 rssi_monitor_min;
- u8 rssi_monitor_enable;
+ s32 rssi_monitor_th;
+ u32 rssi_monitor_hyst;
+ s32 rssi_monitor_state; // 0 = midpoint
+ // -1 = last crossed low threshold
+ // 1 = last crossed high threshold
+ bool rssi_monitor_enable;
#endif
};
diff --git a/drivers/staging/rtl8723cs/os_dep/linux/rtw_cfgvendor.c b/drivers/staging/rtl8723cs/os_dep/linux/rtw_cfgvendor.c
index 5095272414c5..ea7c81e291f1 100644
--- a/drivers/staging/rtl8723cs/os_dep/linux/rtw_cfgvendor.c
+++ b/drivers/staging/rtl8723cs/os_dep/linux/rtw_cfgvendor.c
@@ -1305,111 +1305,43 @@ static int rtw_cfgvendor_lstats_clear_info(struct wiphy *wiphy,
}
#endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */
#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR
-static int rtw_cfgvendor_set_rssi_monitor(struct wiphy *wiphy,
- struct wireless_dev *wdev, const void *data, int len)
-{
- _adapter *padapter = GET_PRIMARY_ADAPTER(wiphy_to_adapter(wiphy));
- struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
-
- struct recv_priv *precvpriv = &padapter->recvpriv;
- int err = 0, rem, type;
- const struct nlattr *iter;
-
- RTW_DBG(FUNC_NDEV_FMT" %s\n", FUNC_NDEV_ARG(wdev_to_ndev(wdev)), (char*)data);
-
- nla_for_each_attr(iter, data, len, rem) {
- type = nla_type(iter);
-
- switch (type) {
- case RSSI_MONITOR_ATTRIBUTE_MAX_RSSI:
- pwdev_priv->rssi_monitor_max = (s8)nla_get_u32(iter);;
- break;
- case RSSI_MONITOR_ATTRIBUTE_MIN_RSSI:
- pwdev_priv->rssi_monitor_min = (s8)nla_get_u32(iter);
- break;
- case RSSI_MONITOR_ATTRIBUTE_START:
- pwdev_priv->rssi_monitor_enable = (u8)nla_get_u32(iter);
- break;
- }
- }
-
- return err;
-}
-
void rtw_cfgvendor_rssi_monitor_evt(_adapter *padapter) {
- struct wireless_dev *wdev = padapter->rtw_wdev;
- struct wiphy *wiphy= wdev->wiphy;
- struct recv_priv *precvpriv = &padapter->recvpriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct wlan_network *pcur_network = &pmlmepriv->cur_network;
+ gfp_t kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
+ struct wireless_dev *wdev = padapter->rtw_wdev;
+ //struct wiphy *wiphy = wdev->wiphy;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ //struct wlan_network *pcur_network = &pmlmepriv->cur_network;
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
- struct sk_buff *skb;
- u32 tot_len = NLMSG_DEFAULT_SIZE;
- gfp_t kflags;
-#ifndef CONFIG_RTW_CFGVENDOR_CQM_THRESHOLD_EVT_LOW
- rssi_monitor_evt data ;
-#endif
- s8 rssi = precvpriv->rssi;
-
- if (pwdev_priv->rssi_monitor_enable == 0 || check_fwstate(pmlmepriv, WIFI_ASOC_STATE) != _TRUE)
- return;
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+ s32 rssi = precvpriv->rssi;
- #ifdef CONFIG_RTW_CFGVENDOR_CQM_THRESHOLD_EVT_LOW
- /* Updated this function to return NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, which is the
- type of event expected by wpa_supplicant when the rssi value drops below threshold.
- This type of event triggers a scan, and is generally followed by a roam to an AP
- with stronger signal. */
- if (rssi < pwdev_priv->rssi_monitor_max && rssi > pwdev_priv->rssi_monitor_min)
+ /*
+ * Nothing to monitor.
+ */
+ if (!pwdev_priv->rssi_monitor_enable || check_fwstate(pmlmepriv, WIFI_ASOC_STATE) != _TRUE)
return;
- kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
-
- cfg80211_cqm_rssi_notify(wdev->netdev, NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, rssi, kflags);
-
- /* After a cqm rssi threshold event, disable event triggering to:
- 1. prevent constant event generation.
- 2. allow the wpa_supplicant to drive this process based on its bgscan interval settings. */
- pwdev_priv->rssi_monitor_enable = 0;
-
- return;
-
- #else
- /* The original code calls rtw_cfg80211_vendor_event_alloc() to allocate an skb to
- send a "vendor event" to user space. The third value passed to
- rtw_cfg80211_vendor_event_alloc() should be "event_idx: index of the vendor event
- in the wiphy's vendor_events", but rather than passing the index of the vendor event
- in the vendor_events array, the code incorrectly passes the enum value 13 of the
- GOOGLE_RSSI_MONITOR_EVENT vendor event. This value is larger than the size of the
- vendor_events array and results in a return value of NULL rather than the address of
- an allocated skb buffer. Since the skb is not allocated, no vendor event is actually
- reported. Modifying this code to send the proper index of the vendor_event does not
- improve things, since this vendor defined event type is not handled by wpa_supplicant
- anyway. */
-
- if (rssi < pwdev_priv->rssi_monitor_max || rssi > pwdev_priv->rssi_monitor_min)
- return;
-
- kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
+ //pr_info("got event rssi=%d\n", rssi);
- /* Alloc the SKB for vendor_event */
- skb = rtw_cfg80211_vendor_event_alloc(wiphy, wdev, tot_len, GOOGLE_RSSI_MONITOR_EVENT, kflags);
- if (!skb) {
- goto exit;
+ /*
+ * If last event was NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH and RSSI is
+ * lower than the threshold, raise the signal LOW event.
+ */
+ if (pwdev_priv->rssi_monitor_state >= 0 && rssi <= pwdev_priv->rssi_monitor_th - pwdev_priv->rssi_monitor_hyst) {
+ cfg80211_cqm_rssi_notify(wdev->netdev, NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, rssi, kflags);
+ pwdev_priv->rssi_monitor_state = -1;
+ //pr_info("rssi <= %d\n", pwdev_priv->rssi_monitor_th - pwdev_priv->rssi_monitor_hyst);
}
- _rtw_memset(&data, 0, sizeof(data));
-
- data.version = RSSI_MONITOR_EVT_VERSION;
- data.cur_rssi = rssi;
- _rtw_memcpy(data.BSSID, pcur_network->network.MacAddress, sizeof(mac_addr));
-
- nla_append(skb, sizeof(data), &data);
-
- rtw_cfg80211_vendor_event(skb, kflags);
-exit:
- return;
-
- #endif /* original code */
+ /*
+ * If last event was NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW and RSSI is
+ * lower than the threshold, raise the signal HIGH event.
+ */
+ if (pwdev_priv->rssi_monitor_state < 0 && rssi > pwdev_priv->rssi_monitor_th + pwdev_priv->rssi_monitor_hyst) {
+ cfg80211_cqm_rssi_notify(wdev->netdev, NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, rssi, kflags);
+ pwdev_priv->rssi_monitor_state = 1;
+ //pr_info("rssi > %d\n", pwdev_priv->rssi_monitor_th + pwdev_priv->rssi_monitor_hyst);
+ }
}
#endif /* CONFIG_RTW_CFGVENDOR_RSSIMONITR */
@@ -1946,19 +1878,6 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = {
.doit = rtw_cfgvendor_lstats_clear_info
},
#endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */
-#ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR
- {
- {
- .vendor_id = OUI_GOOGLE,
- .subcmd = WIFI_SUBCMD_SET_RSSI_MONITOR
- },
- .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
- .policy = VENDOR_CMD_RAW_DATA,
-#endif
- .doit = rtw_cfgvendor_set_rssi_monitor
- },
-#endif /* CONFIG_RTW_CFGVENDOR_RSSIMONITOR */
#ifdef CONFIG_RTW_CFGVENDOR_WIFI_LOGGER
{
{
--
2.34.1