summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSreelakshmi Konamki <skonam@codeaurora.org>2017-02-09 12:20:48 +0530
committerqcabuildsw <qcabuildsw@localhost>2017-02-24 02:39:28 -0800
commit6e44db0b71acfb9324b1598a95a589c832564582 (patch)
tree4d5a65f52cdced882823425321653a52e8cdbe10
parenta9dcab581675e9d7cb8381d5b2160742d4187f20 (diff)
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
-rw-r--r--core/hdd/inc/wlan_hdd_main.h3
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c44
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.h12
-rw-r--r--core/hdd/src/wlan_hdd_main.c3
-rw-r--r--core/mac/inc/sir_api.h20
-rw-r--r--core/mac/inc/wni_api.h3
-rw-r--r--core/sme/inc/sme_api.h12
-rw-r--r--core/sme/inc/sme_internal.h4
-rw-r--r--core/sme/src/common/sme_api.c16
-rw-r--r--core/wma/inc/wma_internal.h10
-rw-r--r--core/wma/src/wma_scan_roam.c3
-rw-r--r--core/wma/src/wma_utils.c30
12 files changed, 154 insertions, 6 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 2bd3d5a394dc..9f01aa114808 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -154,6 +154,8 @@
/* rcpi request timeout in milli seconds */
#define WLAN_WAIT_TIME_RCPI 500
+/* Maximum time(ms) to wait for RSO CMD status event */
+#define WAIT_TIME_RSO_CMD_STATUS 2000
#define MAX_NUMBER_OF_ADAPTERS 4
@@ -1187,6 +1189,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 d9d5e041bf49..51354a33f2c6 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -8378,6 +8378,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
@@ -8397,9 +8412,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);
@@ -8435,15 +8451,37 @@ static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
adapter->dev->name);
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 54c61b517f6a..30c1ef5707d5 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.h
+++ b/core/hdd/src/wlan_hdd_cfg80211.h
@@ -3383,6 +3383,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 9cc38d1bd94b..05c256273b34 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -2543,6 +2543,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;
@@ -8616,6 +8617,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 00f61b5a8127..0e808e2519a6 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -4954,6 +4954,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];
uint32_t vdev_id;
diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h
index 969327c3900f..521d8542b350 100644
--- a/core/mac/inc/wni_api.h
+++ b/core/mac/inc/wni_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -263,6 +263,7 @@ enum eWniMsgTypes {
eWNI_SME_DEFAULT_SCAN_IE,
eWNI_SME_ROAM_SCAN_OFFLOAD_REQ,
eWNI_SME_LOST_LINK_INFO_IND,
+ eWNI_SME_RSO_CMD_STATUS_IND,
eWNI_SME_MSG_TYPES_END
};
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index f53ecf6c1270..0fa9c7ea6b1b 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -1465,4 +1465,16 @@ QDF_STATUS sme_get_beacon_frm(tHalHandle hal, tCsrRoamProfile *profile,
const tSirMacAddr bssid,
uint8_t **frame_buf, uint32_t *frame_len);
+/**
+ * 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 *));
+
#endif /* #if !defined( __SME_API_H ) */
diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h
index b44340416eea..9eac66b2ee48 100644
--- a/core/sme/inc/sme_internal.h
+++ b/core/sme/inc/sme_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -254,6 +254,8 @@ typedef struct tagSmeStruct {
struct sir_encrypt_decrypt_rsp_params *);
void (*lost_link_info_cb)(void *context,
struct sir_lost_link_info *lost_link_info);
+ 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 94672085b43b..ab35e40036bc 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -3082,6 +3082,11 @@ QDF_STATUS sme_process_msg(tHalHandle hHal, cds_msg_t *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)
@@ -17249,6 +17254,7 @@ QDF_STATUS sme_set_udp_resp_offload(struct udp_resp_offload *pudp_resp_cmd)
return status;
}
+
#endif
QDF_STATUS sme_get_rcpi(tHalHandle hal, struct sme_rcpi_req *rcpi)
@@ -17284,7 +17290,17 @@ QDF_STATUS sme_get_rcpi(tHalHandle hal, struct sme_rcpi_req *rcpi)
FL("sme_acquire_global_lock failed"));
qdf_mem_free(rcpi_req);
}
+ 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 c6eae54b1c1b..bf7b0975f67d 100644
--- a/core/wma/inc/wma_internal.h
+++ b/core/wma/inc/wma_internal.h
@@ -863,7 +863,15 @@ 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 86bf93d6135b..05297745abd0 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -5788,6 +5788,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 00ed392dff75..e2a655f82c15 100644
--- a/core/wma/src/wma_utils.c
+++ b/core/wma/src/wma_utils.c
@@ -1774,6 +1774,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;
+ cds_msg_t 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 = cds_mq_post_message(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