summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSungjoon Park <sungjoon.park@broadcom.corp-partner.google.com>2023-08-30 17:41:16 +0900
committerIsaac Chiou <isaacchiou@google.com>2023-08-31 06:24:34 +0000
commita65b5be81a9acb5eb514f8b7272f940d53d74ca4 (patch)
tree56645639c2bc8fec41f458989e14729c5c7e9d6e
parent00197099c050b986b7740b623dc30da04d8723ad (diff)
downloadbcm4389-a65b5be81a9acb5eb514f8b7272f940d53d74ca4.tar.gz
Signature: Ramdump UUID = 024bd63b-d9aa-31f7-8fda-47ace057d662, Signature = wlan: SCAN_Busy;, Type = wlan Scan_busy happend due to scan trigger while CSA in progress. DHD has logic to do trigger socram/memdump on continuous scan failures (threshold based). However, with CSA having long duration, it is possible that the threshold count could be hit triggering false alarms. so avoid incrementing the failure count while CSA is in progress. Bug: 293478730 Test: Verified in internal test Change-Id: Iea6f34a70f9289e39f4e46bef8a0b08a34cd049f Signed-off-by: Sungjoon Park <sungjoon.park@broadcom.corp-partner.google.com>
-rw-r--r--wl_cfg80211.c2
-rw-r--r--wl_cfg80211.h5
-rw-r--r--wl_cfgscan.c8
-rw-r--r--wl_cfgvif.c34
-rw-r--r--wl_cfgvif.h2
5 files changed, 44 insertions, 7 deletions
diff --git a/wl_cfg80211.c b/wl_cfg80211.c
index b9811d1..d655e1b 100644
--- a/wl_cfg80211.c
+++ b/wl_cfg80211.c
@@ -15875,6 +15875,7 @@ static void wl_init_event_handler(struct bcm_cfg80211 *cfg)
cfg->evt_handler[WLC_E_NAN_CRITICAL] = wl_cfgnan_notify_nan_status;
cfg->evt_handler[WLC_E_NAN_NON_CRITICAL] = wl_cfgnan_notify_nan_status;
#endif /* WL_NAN */
+ cfg->evt_handler[WLC_E_CSA_START_IND] = wl_cfgvif_csa_start_ind;
cfg->evt_handler[WLC_E_CSA_COMPLETE_IND] = wl_csa_complete_ind;
cfg->evt_handler[WLC_E_AP_STARTED] = wl_ap_start_ind;
#ifdef CUSTOM_EVENT_PM_WAKE
@@ -18849,6 +18850,7 @@ static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg)
wl_clr_drv_status(cfg, AP_CREATING, iter->ndev);
wl_clr_drv_status(cfg, NESTED_CONNECT, iter->ndev);
wl_clr_drv_status(cfg, CFG80211_CONNECT, iter->ndev);
+ wl_clr_drv_status(cfg, CSA_ACTIVE, iter->ndev);
}
#ifdef WL_CFG80211_MONITOR
if (ndev->ieee80211_ptr->iftype != NL80211_IFTYPE_MONITOR)
diff --git a/wl_cfg80211.h b/wl_cfg80211.h
index 7c59b26..06a02a6 100644
--- a/wl_cfg80211.h
+++ b/wl_cfg80211.h
@@ -996,8 +996,9 @@ enum wl_status {
#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
WL_STATUS_NESTED_CONNECT,
WL_STATUS_CFG80211_CONNECT,
- WL_STATUS_AUTHORIZED
-
+ WL_STATUS_AUTHORIZED,
+ WL_STATUS_ROAMING,
+ WL_STATUS_CSA_ACTIVE
};
typedef enum wl_iftype {
diff --git a/wl_cfgscan.c b/wl_cfgscan.c
index 799e0f1..7c3ea3c 100644
--- a/wl_cfgscan.c
+++ b/wl_cfgscan.c
@@ -2315,6 +2315,14 @@ wl_cfgscan_handle_scanbusy(struct bcm_cfg80211 *cfg, struct net_device *ndev, s3
scanbusy_err = -EAGAIN;
}
+ if (wl_get_drv_status_all(cfg, CSA_ACTIVE)) {
+ /* override error to EGAIN to avoid forcing panic as CSA can
+ * take upto 25secs. Don't limit on number of scans in this case.
+ */
+ scanbusy_err = -EAGAIN;
+ WL_ERR(("scan busy due to csa in progress\n"));
+ }
+
/* if continuous busy state, clear assoc type in FW by disassoc cmd */
if (scanbusy_err == -EBUSY) {
/* Flush FW preserve buffer logs for checking failure */
diff --git a/wl_cfgvif.c b/wl_cfgvif.c
index 48a820f..e74d7b5 100644
--- a/wl_cfgvif.c
+++ b/wl_cfgvif.c
@@ -5567,6 +5567,25 @@ const wl_event_msg_t *e, void *data)
}
s32
+wl_cfgvif_csa_start_ind(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
+const wl_event_msg_t *e, void *data)
+{
+ struct net_device *ndev = NULL;
+
+ if (!cfgdev) {
+ WL_ERR(("invalid arg\n"));
+ return BCME_ERROR;
+ }
+
+ ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);
+ WL_INFORM_MEM(("[%s] csa started\n", ndev->name));
+
+ wl_set_drv_status(cfg, CSA_ACTIVE, ndev);
+
+ return BCME_OK;
+}
+
+s32
wl_csa_complete_ind(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
const wl_event_msg_t *e, void *data)
{
@@ -5574,15 +5593,21 @@ const wl_event_msg_t *e, void *data)
u32 chanspec = 0;
struct net_device *ndev = NULL;
struct ether_addr bssid;
+ u32 status = dtoh32(e->status);
WL_DBG(("Enter\n"));
- if (unlikely(e->status)) {
- WL_ERR(("status:0x%x \n", e->status));
- return -1;
- }
if (likely(cfgdev)) {
ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);
+ wl_clr_drv_status(cfg, CSA_ACTIVE, ndev);
+
+ WL_INFORM_MEM(("[%s] CSA ind. ch:0x%x status:%d\n",
+ ndev->name, chanspec, status));
+ if (status != WLC_E_STATUS_SUCCESS) {
+ WL_ERR(("csa complete error. status:0x%x\n", e->status));
+ return BCME_ERROR;
+ }
+
/* Get association state if not AP and then query chanspec */
if (!((wl_get_mode_by_netdev(cfg, ndev)) == WL_MODE_AP)) {
error = wldev_ioctl_get(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN);
@@ -5599,7 +5624,6 @@ const wl_event_msg_t *e, void *data)
return -1;
}
- WL_INFORM_MEM(("[%s] CSA ind. ch:0x%x\n", ndev->name, chanspec));
if (wl_get_mode_by_netdev(cfg, ndev) == WL_MODE_AP) {
/* For AP/GO role */
wl_ap_channel_ind(cfg, ndev, chanspec);
diff --git a/wl_cfgvif.h b/wl_cfgvif.h
index 86ab7cc..7e9e898 100644
--- a/wl_cfgvif.h
+++ b/wl_cfgvif.h
@@ -197,6 +197,8 @@ extern s32 wl_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev);
extern s32 wl_ap_start_ind(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
const wl_event_msg_t *e, void *data);
+extern s32 wl_cfgvif_csa_start_ind(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
+ const wl_event_msg_t *e, void *data);
extern s32 wl_csa_complete_ind(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
const wl_event_msg_t *e, void *data);
extern s32 wl_cfg80211_set_ap_role(struct bcm_cfg80211 *cfg, struct net_device *dev);