summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManjeet Singh <manjee@codeaurora.org>2017-02-15 13:38:11 +0530
committerqcabuildsw <qcabuildsw@localhost>2017-02-21 02:32:15 -0800
commit02139ec8056ad6343b3c09edde8bf0b75a2c9954 (patch)
tree86c28a316f4c1645fc67901c724abda34639300e
parentebfb5a71c4b38ea3447edbd71d0000cf4755f965 (diff)
qcacld-2.0: Auto Detect SoC Power Collapse Failure changes
Add host support for detecting SOC power collapse failures in FW and communicating the same to framework. Change-Id: Icee39c896802c4d7136e0b8ef442a33feeb4799c CRs-Fixed: 1112979
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg80211.h35
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h4
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c70
-rw-r--r--CORE/HDD/src/wlan_hdd_early_suspend.c4
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c4
-rw-r--r--CORE/MAC/inc/sirApi.h11
-rw-r--r--CORE/SERVICES/WMA/wma.c118
-rw-r--r--CORE/SERVICES/WMA/wma.h6
-rw-r--r--CORE/SME/inc/smeInternal.h2
-rw-r--r--CORE/SME/inc/sme_Api.h3
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c29
11 files changed, 272 insertions, 14 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 33d6c01c99b1..cf6d0c9d7d87 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -280,6 +280,7 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT = 127,
/* subcommand to get chain rssi value */
QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI = 138,
+ QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE = 148,
};
enum qca_nl80211_vendor_subcmds_index {
@@ -348,6 +349,7 @@ enum qca_nl80211_vendor_subcmds_index {
#ifdef WLAN_FEATURE_NAN_DATAPATH
QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
#endif /* WLAN_FEATURE_NAN_DATAPATH */
+ QCA_NL80211_VENDOR_SUBCMD_PWR_SAVE_FAIL_DETECTED_INDEX,
};
/* EXT TDLS */
@@ -1870,6 +1872,39 @@ enum qca_wlan_vendor_attr_rssi_monitoring {
};
/**
+ * qca_chip_power_save_failure_reason: Power save failure reason
+ * @QCA_CHIP_POWER_SAVE_FAILURE_REASON_PROTOCOL: Indicates power save failure
+ * due to protocol/module.
+ * @QCA_CHIP_POWER_SAVE_FAILURE_REASON_HARDWARE: power save failure
+ * due to hardware
+ */
+enum qca_chip_power_save_failure_reason {
+ QCA_CHIP_POWER_SAVE_FAILURE_REASON_PROTOCOL = 0,
+ QCA_CHIP_POWER_SAVE_FAILURE_REASON_HARDWARE = 1,
+};
+
+/**
+ * qca_attr_chip_power_save_failure: attributes to vendor subcmd
+ * @QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE. This carry the requisite
+ * information leading to the power save failure.
+ * @QCA_ATTR_CHIP_POWER_SAVE_FAILURE_INVALID : invalid
+ * @QCA_ATTR_CHIP_POWER_SAVE_FAILURE_REASON : power save failure reason
+ * represented by enum qca_chip_power_save_failure_reason
+ * @QCA_ATTR_CHIP_POWER_SAVE_FAILURE_LAST : Last
+ * @QCA_ATTR_CHIP_POWER_SAVE_FAILURE_MAX : Max value
+ */
+enum qca_attr_chip_power_save_failure {
+ QCA_ATTR_CHIP_POWER_SAVE_FAILURE_INVALID = 0,
+
+ QCA_ATTR_CHIP_POWER_SAVE_FAILURE_REASON = 1,
+
+ /* keep last */
+ QCA_ATTR_CHIP_POWER_SAVE_FAILURE_LAST,
+ QCA_ATTR_CHIP_POWER_SAVE_FAILURE_MAX =
+ QCA_ATTR_CHIP_POWER_SAVE_FAILURE_LAST - 1,
+};
+
+/**
* enum set_reset_packet_filter - set packet filter control commands
* @QCA_WLAN_SET_PACKET_FILTER: Set Packet Filter
* @QCA_WLAN_GET_PACKET_FILTER: Get Packet filter
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 4c0ca17cd175..9691a30368c0 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -2590,4 +2590,8 @@ void hdd_svc_fw_shutdown_ind(struct device *dev);
void wlan_hdd_stop_enter_lowpower(hdd_context_t *hdd_ctx);
void wlan_hdd_init_chan_info(hdd_context_t *hdd_ctx);
void wlan_hdd_deinit_chan_info(hdd_context_t *hdd_ctx);
+
+void hdd_chip_pwr_save_fail_detected_cb(void *hddctx,
+ struct chip_pwr_save_fail_detected_params
+ *data);
#endif // end #if !defined( WLAN_HDD_MAIN_H )
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index f1f1c05ba40f..d154513a2265 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -1323,6 +1323,10 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
.subcmd = QCA_NL80211_VENDOR_SUBCMD_NDP
},
#endif /* WLAN_FEATURE_NAN_DATAPATH */
+ [QCA_NL80211_VENDOR_SUBCMD_PWR_SAVE_FAIL_DETECTED_INDEX] = {
+ .vendor_id = QCA_NL80211_VENDOR_ID,
+ .subcmd = QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE
+ }
};
/**
@@ -11209,6 +11213,72 @@ fail:
kfree_skb(skb);
return;
}
+#define PWR_SAVE_FAIL_CMD_INDEX \
+ QCA_NL80211_VENDOR_SUBCMD_PWR_SAVE_FAIL_DETECTED_INDEX
+/**
+ * hdd_chip_pwr_save_fail_detected() - chip power save failure detected
+ * NL event
+ * @hddctx: HDD context
+ * @data: chip power save failure detected data
+ *
+ * This function reads the chip power save failure detected data and fill in
+ * the skb with NL attributes and send up the NL event.
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
+ * Return: none
+ */
+void hdd_chip_pwr_save_fail_detected_cb(void *hddctx,
+ struct chip_pwr_save_fail_detected_params
+ *data)
+{
+ hdd_context_t *hdd_ctx = hddctx;
+ struct sk_buff *skb;
+ int flags = vos_get_gfp_flags();
+
+ ENTER();
+
+ if (wlan_hdd_validate_context(hdd_ctx))
+ return;
+
+ if (!data) {
+ hddLog(LOGE, FL("data is null"));
+ return;
+ }
+
+ skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+ NULL, NLMSG_HDRLEN +
+ sizeof(data-> failure_reason_code) +
+ NLMSG_HDRLEN, PWR_SAVE_FAIL_CMD_INDEX,
+ flags);
+
+ if (!skb) {
+ hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
+ return;
+ }
+
+ hddLog(LOG1, "failure reason code: %u, wake lock bitmap : %u %u %u %u",
+ data->failure_reason_code,
+ data->wake_lock_bitmap[0],
+ data->wake_lock_bitmap[1],
+ data->wake_lock_bitmap[2],
+ data->wake_lock_bitmap[3]);
+
+ if (nla_put_u32(skb,
+ QCA_ATTR_CHIP_POWER_SAVE_FAILURE_REASON,
+ data->failure_reason_code))
+ goto fail;
+
+ cfg80211_vendor_event(skb, flags);
+ EXIT();
+ return;
+
+fail:
+ kfree_skb(skb);
+ EXIT();
+ return;
+}
+#undef PWR_SAVE_FAIL_CMD_INDEX
static const struct nla_policy
ns_offload_set_policy[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX + 1] = {
diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c
index 6fc1158af487..091d1b16db1d 100644
--- a/CORE/HDD/src/wlan_hdd_early_suspend.c
+++ b/CORE/HDD/src/wlan_hdd_early_suspend.c
@@ -2449,6 +2449,10 @@ VOS_STATUS hdd_wlan_re_init(void *hif_sc)
pHddCtx->target_hw_version,
pHddCtx->target_hw_name);
#endif
+ /* set chip power save failure detected callback */
+ sme_set_chip_pwr_save_fail_cb(pHddCtx->hHal,
+ hdd_chip_pwr_save_fail_detected_cb);
+
ol_pktlog_init(hif_sc);
goto success;
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 00844505efd7..6c63415b5bfe 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -16068,6 +16068,10 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
if (hdd_wlan_enable_egap(pHddCtx))
hddLog(LOGE, FL("enhance green ap is not enabled"));
+ /* set chip power save failure detected callback */
+ sme_set_chip_pwr_save_fail_cb(pHddCtx->hHal,
+ hdd_chip_pwr_save_fail_detected_cb);
+
wlan_comp.status = 0;
complete(&wlan_comp.wlan_start_comp);
goto success;
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index a82d47b63d83..990d4885241c 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -7377,6 +7377,17 @@ struct rssi_breach_event {
};
/**
+ * struct chip_pwr_save_fail_detected_params - chip power save failure detected
+ * event params
+ * @failure_reason_code:failure reason code
+ * @wake_lock_bitmap:bitmap for modules voting against sleep for long duration.
+ */
+struct chip_pwr_save_fail_detected_params {
+ uint32_t failure_reason_code;
+ uint32_t wake_lock_bitmap[4];
+};
+
+/**
* struct sir_sme_ext_change_chan_req - channel change request
* @message_type: message id
* @length: msg length
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index a3b3efc0c0db..115a4d6f10ec 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -7984,6 +7984,63 @@ static int wma_rssi_breached_event_handler(void *handle,
return 0;
}
+/**
+ * wma_chip_power_save_failure_detected_handler() - chip pwr save fail detected
+ * event handler
+ * @handle: wma handle
+ * @cmd_param_info: event handler data
+ * @len: length of @cmd_param_info
+ *
+ * Return: VOS_STATUS_SUCCESS on success; error code otherwise
+ */
+static int wma_chip_power_save_failure_detected_handler(void *handle,
+ u_int8_t *cmd_param_info, u_int32_t len)
+{
+ tp_wma_handle wma = (tp_wma_handle)handle;
+ WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID_param_tlvs *param_buf;
+ wmi_chip_power_save_failure_detected_fixed_param *event;
+ struct chip_pwr_save_fail_detected_params pwr_save_fail_params;
+ tpAniSirGlobal mac = (tpAniSirGlobal)vos_get_context(
+ VOS_MODULE_ID_PE, wma->vos_context);
+
+ if (NULL == wma) {
+ WMA_LOGE("%s: wma_handle is NULL", __func__);
+ return VOS_STATUS_E_INVAL;
+ }
+ if (!mac) {
+ WMA_LOGE("%s: Invalid mac context", __func__);
+ return VOS_STATUS_E_INVAL;
+ }
+ if (!mac->sme.chip_power_save_fail_cb) {
+ WMA_LOGE("%s: Callback not registered", __func__);
+ return VOS_STATUS_E_INVAL;
+ }
+ param_buf =
+ (WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID_param_tlvs *)
+ cmd_param_info;
+ if (!param_buf) {
+ WMA_LOGE("%s: Invalid pwr_save_fail_params breached event",
+ __func__);
+ return VOS_STATUS_E_INVAL;
+ }
+ event = param_buf->fixed_param;
+
+ pwr_save_fail_params.failure_reason_code =
+ event->power_save_failure_reason_code;
+ pwr_save_fail_params.wake_lock_bitmap[0] =
+ event->protocol_wake_lock_bitmap[0];
+ pwr_save_fail_params.wake_lock_bitmap[1] =
+ event->protocol_wake_lock_bitmap[1];
+ pwr_save_fail_params.wake_lock_bitmap[2] =
+ event->protocol_wake_lock_bitmap[2];
+ pwr_save_fail_params.wake_lock_bitmap[3] =
+ event->protocol_wake_lock_bitmap[3];
+
+ mac->sme.chip_power_save_fail_cb(mac->hHdd,
+ &pwr_save_fail_params);
+ WMA_LOGD("%s: Invoke HDD pwr_save_fail callback", __func__);
+ return VOS_STATUS_SUCCESS;
+}
/*
* Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or
* WMI_DFS_PHYERR_FILTER_DIS_CMDID command
@@ -9146,6 +9203,10 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID,
wma_action_frame_filter_mac_event_handler);
+ wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID,
+ wma_chip_power_save_failure_detected_handler);
+
wma_register_debug_callback();
wma_ndp_register_all_event_handlers(wma_handle);
@@ -22149,6 +22210,9 @@ static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason, tp_wma_handle wma)
case WOW_REASON_RSSI_BREACH_EVENT:
return "WOW_REASON_RSSI_BREACH_EVENT";
+ case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
+ return "WOW_REASON_CHIP_POWER_FAILURE_DETECT";
+
case WOW_REASON_NLO_SCAN_COMPLETE:
return "WOW_REASON_NLO_SCAN_COMPLETE";
case WOW_REASON_BPF_ALLOW:
@@ -22666,7 +22730,7 @@ static void wma_extscan_wow_event_callback(void *handle, void *event,
*/
static void wma_wow_wake_up_stats_display(tp_wma_handle wma)
{
- WMA_LOGA("uc %d bc %d v4_mc %d v6_mc %d ra %d ns %d na %d pno_match %d pno_complete %d gscan %d low_rssi %d rssi_breach %d icmp %d icmpv6 %d oem %d",
+ WMA_LOGA("uc %d bc %d v4_mc %d v6_mc %d ra %d ns %d na %d pno_match %d pno_complete %d gscan %d low_rssi %d rssi_breach %d icmp %d icmpv6 %d oem %d chip pwr save fail : %d",
wma->wow_ucast_wake_up_count,
wma->wow_bcast_wake_up_count,
wma->wow_ipv4_mcast_wake_up_count,
@@ -22681,7 +22745,8 @@ static void wma_wow_wake_up_stats_display(tp_wma_handle wma)
wma->wow_rssi_breach_wake_up_count,
wma->wow_icmpv4_count,
wma->wow_icmpv6_count,
- wma->wow_oem_response_wake_up_count);
+ wma->wow_oem_response_wake_up_count,
+ wma->wow_pwr_save_fail_detected_wake_up_count);
return;
}
@@ -22811,6 +22876,10 @@ static void wma_wow_wake_up_stats(tp_wma_handle wma, uint8_t *data,
wma->wow_oem_response_wake_up_count++;
break;
+ case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
+ wma->wow_pwr_save_fail_detected_wake_up_count++;
+ break;
+
default:
WMA_LOGE("Unknown wake up reason");
break;
@@ -23632,7 +23701,14 @@ static int wma_wow_wakeup_host_event(void *handle, u_int8_t *event,
WMA_LOGD(FL("No wow_packet_buffer for OEM response"));
}
break;
-
+ case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
+ {
+ /* Just update stats and exit */
+ wma_wow_wake_up_stats(wma, NULL, 0,
+ WOW_REASON_CHIP_POWER_FAILURE_DETECT);
+ WMA_LOGD("Host woken up because of chip power save failure");
+ }
+ break;
default:
break;
}
@@ -23724,6 +23800,8 @@ static const u8 *wma_wow_wakeup_event_str(WOW_WAKE_EVENT_TYPE event)
return "WOW_TDLS_CONN_TRACKER_EVENT";
case WOW_OEM_RESPONSE_EVENT:
return "WOW_OEM_RESPONSE_EVENT";
+ case WOW_CHIP_POWER_FAILURE_DETECT_EVENT:
+ return "WOW_CHIP_POWER_FAILURE_DETECT_EVENT";
default:
return "UNSPECIFIED_EVENT";
}
@@ -23744,12 +23822,22 @@ void wma_add_wow_wakeup_event(tp_wma_handle wma,
WOW_WAKE_EVENT_TYPE event,
bool enable)
{
+ uint32_t idx, bit_idx;
+
+ if (event == 0) {
+ idx = bit_idx = 0;
+ }
+ else {
+ idx = event / WOW_BITMAP_FIELD_SIZE;
+ bit_idx = event % WOW_BITMAP_FIELD_SIZE;
+ }
+
if (enable) {
- wma->wow_wakeup_enable_mask |= 1 << event;
- wma->wow_wakeup_disable_mask &= ~(1 << event);
+ wma->wow_wakeup_enable_mask[idx] |= 1 << bit_idx;
+ wma->wow_wakeup_disable_mask[idx] &= ~(1 << bit_idx);
} else {
- wma->wow_wakeup_disable_mask |= 1 << event;
- wma->wow_wakeup_enable_mask &= ~(1 << event);
+ wma->wow_wakeup_disable_mask[idx] |= 1 << bit_idx;
+ wma->wow_wakeup_enable_mask[idx] &= ~(1 << bit_idx);
}
WMA_LOGD(FL("%s event %s"),
@@ -23793,9 +23881,11 @@ static VOS_STATUS wma_send_wakeup_mask(tp_wma_handle wma, bool enable)
cmd->is_add = enable;
if (cmd->is_add)
- cmd->event_bitmap = wma->wow_wakeup_enable_mask;
+ vos_mem_copy(cmd->event_bitmaps, wma->wow_wakeup_enable_mask,
+ WMI_WOW_MAX_EVENT_BM_LEN * sizeof(uint32_t));
else
- cmd->event_bitmap = wma->wow_wakeup_disable_mask;
+ vos_mem_copy(cmd->event_bitmaps, wma->wow_wakeup_disable_mask,
+ WMI_WOW_MAX_EVENT_BM_LEN * sizeof(uint32_t));
ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
@@ -24596,8 +24686,10 @@ static void wma_update_free_wow_ptrn_id(tp_wma_handle wma)
* wakeup patterns properly to FW.
*/
- wma->wow_wakeup_enable_mask = 0;
- wma->wow_wakeup_disable_mask = 0;
+ vos_mem_zero(wma->wow_wakeup_enable_mask,
+ sizeof(wma->wow_wakeup_enable_mask));
+ vos_mem_zero(wma->wow_wakeup_disable_mask,
+ sizeof(wma->wow_wakeup_enable_mask));
WMA_LOGD("Total free wow pattern id for default patterns: %d",
wma->wow.total_free_ptrn_id );
}
@@ -24933,7 +25025,6 @@ static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma,
#endif
wma_ndp_add_wow_wakeup_event(wma, true);
-
#ifdef FEATURE_WLAN_TDLS
/* configure TDLS based wakeup */
wma_add_wow_wakeup_event(wma, WOW_TDLS_CONN_TRACKER_EVENT, TRUE);
@@ -24941,6 +25032,9 @@ static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma,
wma_add_wow_wakeup_event(wma, WOW_OEM_RESPONSE_EVENT, TRUE);
+ wma_add_wow_wakeup_event(wma, WOW_CHIP_POWER_FAILURE_DETECT_EVENT,
+ TRUE);
+
/* Enable wow wakeup events in FW */
ret = wma_send_wakeup_mask(wma, TRUE);
if (ret) {
diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h
index f88400115418..4622bcbd1fce 100644
--- a/CORE/SERVICES/WMA/wma.h
+++ b/CORE/SERVICES/WMA/wma.h
@@ -911,6 +911,7 @@ typedef struct wma_handle {
uint32_t wow_gscan_wake_up_count;
uint32_t wow_low_rssi_wake_up_count;
uint32_t wow_rssi_breach_wake_up_count;
+ uint32_t wow_pwr_save_fail_detected_wake_up_count;
uint32_t wow_ucast_wake_up_count;
uint32_t wow_bcast_wake_up_count;
uint32_t wow_ipv4_mcast_wake_up_count;
@@ -921,8 +922,8 @@ typedef struct wma_handle {
uint32_t wow_icmpv4_count;
uint32_t wow_icmpv6_count;
uint32_t wow_oem_response_wake_up_count;
- uint32_t wow_wakeup_enable_mask;
- uint32_t wow_wakeup_disable_mask;
+ uint32_t wow_wakeup_enable_mask[4];
+ uint32_t wow_wakeup_disable_mask[4];
uint16_t max_mgmt_tx_fail_count;
uint32_t ccmp_replays_attack_cnt;
@@ -1898,6 +1899,7 @@ void wma_remove_peer(tp_wma_handle wma, u_int8_t *bssid,
u_int8_t vdev_id, ol_txrx_peer_handle peer,
v_BOOL_t roam_synch_in_progress);
+#define WOW_BITMAP_FIELD_SIZE 32
void wma_add_wow_wakeup_event(tp_wma_handle wma, WOW_WAKE_EVENT_TYPE event,
bool enable);
VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev,
diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h
index 07871ee526c2..8317e739606f 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -260,6 +260,8 @@ typedef struct tagSmeStruct
void *mib_stats_context;
void (*csr_mib_stats_callback) (struct mib_stats_metrics*, void*);
void (*stats_ext2_cb)(void *, struct stats_ext2_event *);
+ void (*chip_power_save_fail_cb)(void *,
+ struct chip_pwr_save_fail_detected_params *);
} tSmeStruct, *tpSmeStruct;
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index b9a6c028cdf2..f296d6d18c55 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -4798,4 +4798,7 @@ eHalStatus sme_set_random_mac(tHalHandle hal,
eHalStatus sme_clear_random_mac(tHalHandle hal, uint32_t session_id,
uint8_t *random_mac);
+eHalStatus sme_set_chip_pwr_save_fail_cb(tHalHandle hal, void (*cb)( void *,
+ struct chip_pwr_save_fail_detected_params *));
+
#endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index d2fa3d2c2d37..99d2fd8b1812 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -16452,6 +16452,35 @@ eHalStatus sme_set_rssi_threshold_breached_cb(tHalHandle hal,
sme_ReleaseGlobalLock(&mac->sme);
return status;
}
+/**
+ * sme_set_chip_pwr_save_fail_cb() - set chip power save failure callback
+ * @hal: global hal handle
+ * @cb: callback function pointer
+ *
+ * This function stores the chip power save failure callback function.
+ *
+ * Return: eHalStatus enumeration.
+ */
+eHalStatus sme_set_chip_pwr_save_fail_cb(tHalHandle hal,
+ void (*cb)(
+ void *,
+ struct chip_pwr_save_fail_detected_params *))
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+ status = sme_AcquireGlobalLock(&mac->sme);
+ if (status != eHAL_STATUS_SUCCESS) {
+ smsLog(mac, LOGE,
+ FL("sme_AcquireGlobalLock failed!(status=%d)"),
+ status);
+ return status;
+ }
+
+ mac->sme.chip_power_save_fail_cb = cb;
+ sme_ReleaseGlobalLock(&mac->sme);
+ return status;
+}
/**
* sme_set_rssi_monitoring() - set rssi monitoring