From 88a2a41bbf8c6ed004397e59bbdd5392204b1fa3 Mon Sep 17 00:00:00 2001 From: Sreelakshmi Konamki Date: Fri, 14 Apr 2017 15:11:55 +0530 Subject: [PATCH] qcacld-3.0: Add support to get the status for Roam Scan Offload command Add support to handle the event for the Roam Scan Offload[RSO] command status. Inform the same to user space. Change-Id: I2758103e8ca3c49c0fecd3323b619542dbbabf0c CRs-Fixed: 1111809 --- core/hdd/inc/wlan_hdd_main.h | 4 ++ core/hdd/src/wlan_hdd_cfg80211.c | 42 +++++++++++++++++-- core/hdd/src/wlan_hdd_cfg80211.h | 12 ++++++ core/hdd/src/wlan_hdd_main.c | 3 ++ core/mac/inc/sir_api.h | 20 +++++++++ core/mac/inc/wni_api.h | 1 + .../src/sys/legacy/src/utils/src/mac_trace.c | 1 + core/sme/inc/sme_api.h | 12 ++++++ core/sme/inc/sme_internal.h | 2 + core/sme/src/common/sme_api.c | 16 +++++++ core/wma/inc/wma_internal.h | 10 +++++ core/wma/src/wma_scan_roam.c | 3 ++ core/wma/src/wma_utils.c | 30 +++++++++++++ 13 files changed, 153 insertions(+), 3 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 6d9836165a1c..637523ec3dfc 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -167,6 +167,9 @@ #define WLAN_WAIT_TIME_BPF 1000 +/* Maximum time(ms) to wait for RSO CMD status event */ +#define WAIT_TIME_RSO_CMD_STATUS 2000 + #define MAX_NUMBER_OF_ADAPTERS 4 #define MAX_CFG_STRING_LEN 255 @@ -1143,6 +1146,7 @@ struct hdd_adapter_s { * disconnect is being deferred. */ uint8_t cfg80211_disconnect_reason; + struct lfr_firmware_status lfr_fw_status; }; /* diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 2d9f2b9f0ff9..ea8a9782c8ff 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -9177,6 +9177,21 @@ nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] = { .len = QDF_MAC_ADDR_SIZE}, }; +void wlan_hdd_rso_cmd_status_cb(void *ctx, struct rso_cmd_status *rso_status) +{ + hdd_context_t *hdd_ctx = (hdd_context_t *)ctx; + hdd_adapter_t *adapter; + + adapter = hdd_get_adapter_by_vdev(hdd_ctx, rso_status->vdev_id); + if (!adapter) { + hdd_err("adapter NULL"); + return; + } + + adapter->lfr_fw_status.is_disabled = rso_status->status; + complete(&adapter->lfr_fw_status.disable_lfr_event); +} + /** * __wlan_hdd_cfg80211_set_fast_roaming() - enable/disable roaming * @wiphy: Pointer to wireless phy @@ -9196,9 +9211,10 @@ static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy, struct net_device *dev = wdev->netdev; hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1]; - uint32_t is_fast_roam_enabled; + uint32_t is_fast_roam_enabled, enable_lfr_fw; int ret; QDF_STATUS qdf_status; + unsigned long rc; ENTER_DEV(dev); @@ -9235,14 +9251,34 @@ static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy, return -EINVAL; } /* Update roaming */ + enable_lfr_fw = (is_fast_roam_enabled && adapter->fast_roaming_allowed); qdf_status = sme_config_fast_roaming(hdd_ctx->hHal, adapter->sessionId, - (is_fast_roam_enabled && - adapter->fast_roaming_allowed)); + enable_lfr_fw); if (qdf_status != QDF_STATUS_SUCCESS) hdd_err("sme_config_fast_roaming failed with status=%d", qdf_status); ret = qdf_status_to_os_return(qdf_status); + INIT_COMPLETION(adapter->lfr_fw_status.disable_lfr_event); + if (QDF_IS_STATUS_SUCCESS(qdf_status) && !enable_lfr_fw) { + /* + * wait only for LFR disable in fw as LFR enable + * is always success + */ + rc = wait_for_completion_timeout( + &adapter->lfr_fw_status.disable_lfr_event, + msecs_to_jiffies(WAIT_TIME_RSO_CMD_STATUS)); + if (!rc) { + hdd_err("Timed out waiting for RSO CMD status"); + return -ETIMEDOUT; + } + + if (!adapter->lfr_fw_status.is_disabled) { + hdd_err("Roam disable attempt in FW fails"); + return -EBUSY; + } + } + EXIT(); return ret; } diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index f21dc924ebc9..79ac66dad1a2 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -297,6 +297,18 @@ void wlan_hdd_cfg80211_extscan_callback(void *ctx, const uint16_t evType, void *pMsg); #endif /* FEATURE_WLAN_EXTSCAN */ +/** + * wlan_hdd_rso_cmd_status_cb() - HDD callback to read RSO command status + * @ctx: void pointer to hdd context + * @rso_status: rso command status + * + * This callback function is invoked by firmware to update + * the RSO(ROAM SCAN OFFLOAD) command status. + * + * Return: None + */ +void wlan_hdd_rso_cmd_status_cb(void *ctx, struct rso_cmd_status *rso_status); + void hdd_rssi_threshold_breached(void *hddctx, struct rssi_breach_event *data); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 343530ed2aed..55a90a91bcca 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2816,6 +2816,7 @@ static hdd_adapter_t *hdd_alloc_station_adapter(hdd_context_t *hdd_ctx, init_completion(&adapter->scan_info.abortscan_event_var); + init_completion(&adapter->lfr_fw_status.disable_lfr_event); adapter->offloads_configured = false; adapter->isLinkUpSvcNeeded = false; @@ -9350,6 +9351,8 @@ int hdd_register_cb(hdd_context_t *hdd_ctx) sme_set_link_layer_stats_ind_cb(hdd_ctx->hHal, wlan_hdd_cfg80211_link_layer_stats_callback); + sme_rso_cmd_status_cb(hdd_ctx->hHal, wlan_hdd_rso_cmd_status_cb); + status = sme_set_lost_link_info_cb(hdd_ctx->hHal, hdd_lost_link_info_cb); /* print error and not block the startup process */ diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index a311683b6a69..a94cc210934d 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -4617,6 +4617,26 @@ struct power_stats_response { }; #endif +/** + * struct lfr_firmware_status - LFR status in firmware + * @is_disabled: Is LFR disabled in FW + * @disable_lfr_event: Disable attempt done in FW + */ +struct lfr_firmware_status { + uint32_t is_disabled; + struct completion disable_lfr_event; +}; + +/** + * struct rso_cmd_status - RSO Command status + * @vdev_id: Vdev ID for which RSO command sent + * @status: Status of RSO command sent to FW + */ +struct rso_cmd_status { + uint32_t vdev_id; + bool status; +}; + typedef struct { uint8_t oui[WIFI_SCANNING_MAC_OUI_LENGTH]; } tSirScanMacOui, *tpSirScanMacOui; diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index 0ff408e80512..c17b08ad66d8 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -256,6 +256,7 @@ enum eWniMsgTypes { eWNI_SME_ROAM_SCAN_OFFLOAD_REQ, eWNI_SME_LOST_LINK_INFO_IND, eWNI_SME_DEL_ALL_TDLS_PEERS, + eWNI_SME_RSO_CMD_STATUS_IND, eWNI_SME_MSG_TYPES_END }; diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c index 81a2be378e35..37fdbc180a88 100644 --- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c +++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c @@ -415,6 +415,7 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg) CASE_RETURN_STRING(eWNI_SME_DEFAULT_SCAN_IE); CASE_RETURN_STRING(eWNI_SME_ROAM_SCAN_OFFLOAD_REQ); CASE_RETURN_STRING(eWNI_SME_LOST_LINK_INFO_IND); + CASE_RETURN_STRING(eWNI_SME_RSO_CMD_STATUS_IND); CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END); default: return (uint8_t *) "UNKNOWN"; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index e6a01884399b..d74914f7d1c3 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1437,6 +1437,18 @@ QDF_STATUS sme_get_beacon_frm(tHalHandle hal, tCsrRoamProfile *profile, QDF_STATUS sme_delete_all_tdls_peers(tHalHandle hal, uint8_t session_id); +/** + * sme_rso_cmd_status_cb() - Set RSO cmd status callback + * @hal: HAL Handle + * @cb: HDD Callback to rso comman status read + * + * This function is used to save HDD RSO Command status callback in MAC + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_rso_cmd_status_cb(tHalHandle hal, + void (*cb)(void *, struct rso_cmd_status *)); + /** * sme_register_set_connection_info_cb() - Register connection * info callback diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index b416a7e94dfa..eb8cd9281b3f 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -244,6 +244,8 @@ typedef struct tagSmeStruct { bool (*set_connection_info_cb)(bool); bool (*get_connection_info_cb)(uint8_t *session_id, enum scan_reject_states *reason); + void (*rso_cmd_status_cb)(void *hdd_context, + struct rso_cmd_status *rso_status); } tSmeStruct, *tpSmeStruct; #endif /* #if !defined( __SMEINTERNAL_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 8dddb5710f58..1476126ebacd 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -2630,6 +2630,11 @@ QDF_STATUS sme_process_msg(tHalHandle hHal, struct scheduler_msg *pMsg) (struct sir_lost_link_info *)pMsg->bodyptr); qdf_mem_free(pMsg->bodyptr); break; + case eWNI_SME_RSO_CMD_STATUS_IND: + if (pMac->sme.rso_cmd_status_cb) + pMac->sme.rso_cmd_status_cb(pMac->hHdd, pMsg->bodyptr); + qdf_mem_free(pMsg->bodyptr); + break; default: if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN) @@ -16093,3 +16098,14 @@ QDF_STATUS sme_register_set_connection_info_cb(tHalHandle hHal, } return status; } + +QDF_STATUS sme_rso_cmd_status_cb(tHalHandle hal, + void (*cb)(void *, struct rso_cmd_status *)) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + + mac->sme.rso_cmd_status_cb = cb; + sms_log(mac, LOG1, FL("Registered RSO command status callback")); + return status; +} diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index c83f6cd44b32..fa8e81f4372f 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -840,6 +840,16 @@ void wma_post_link_status(tAniGetLinkStatus *pGetLinkStatus, int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info, uint32_t len); +/** + * wma_rso_cmd_status_event_handler() - RSO Command status event handler + * @wmi_event: WMI event + * + * This function is used to send RSO command status to upper layer + * + * Return: 0 for success + */ +int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event); + int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info, uint32_t len); diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index f694e02bcdab..1e800dd9ef75 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -5432,6 +5432,9 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf, roam_synch_data, NULL, op_code); qdf_mem_free(roam_synch_data); break; + case WMI_ROAM_REASON_RSO_STATUS: + wma_rso_cmd_status_event_handler(wmi_event); + break; default: WMA_LOGD("%s:Unhandled Roam Event %x for vdevid %x", __func__, wmi_event->reason, wmi_event->vdev_id); diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 99e8dab109d0..8bd435a16bfa 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -1750,6 +1750,36 @@ int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info, return 0; } +int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event) +{ + struct rso_cmd_status *rso_status; + struct scheduler_msg sme_msg; + QDF_STATUS qdf_status; + + rso_status = qdf_mem_malloc(sizeof(*rso_status)); + if (!rso_status) { + WMA_LOGE("%s: malloc fails for rso cmd status", __func__); + return -ENOMEM; + } + + rso_status->vdev_id = wmi_event->vdev_id; + if (WMI_ROAM_NOTIF_SCAN_MODE_SUCCESS == wmi_event->notif) + rso_status->status = true; + else if (WMI_ROAM_NOTIF_SCAN_MODE_FAIL == wmi_event->notif) + rso_status->status = false; + sme_msg.type = eWNI_SME_RSO_CMD_STATUS_IND; + sme_msg.bodyptr = rso_status; + sme_msg.bodyval = 0; + WMA_LOGI("%s: Post RSO cmd status to SME", __func__); + + qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + WMA_LOGE("%s: fail to post RSO cmd status to SME", __func__); + qdf_mem_free(rso_status); + } + return 0; +} + /** * wma_stats_event_handler() - stats event handler * @handle: wma handle