diff options
| author | zhangq <zhangq@qti.qualcomm.com> | 2016-01-11 17:02:15 +0800 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-01-28 13:44:02 +0530 |
| commit | da4e22f7e01406ab1f503e967423b415e4726dab (patch) | |
| tree | 4bb2bc8d526dde6523803353d8775c53775affbc | |
| parent | ce7c6c623c915b0f9c6dea10e2391b738748ade0 (diff) | |
qcacld-2.0: ADD SCPC feature
This feature will save new calibrated data in the RAM instead of
an on board OTP.
Once SCPC feature is enabled, new calibrated data indicated by FW
in FTM mode will be cached in RAM. The cached calibrated data will
be patched to the board data before it is downloaded to target.
Change-Id: I07400d0edbae3e2013ee47373d120716013450c0
CRs-Fixed: 967577
| -rw-r--r-- | CORE/SERVICES/BMI/ol_fw.c | 7 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/wma_api.h | 2 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 84 | ||||
| -rw-r--r-- | CORE/SERVICES/WMI/wmi_unified.c | 8 | ||||
| -rw-r--r-- | CORE/VOSS/inc/vos_cnss.h | 36 | ||||
| -rw-r--r-- | Kbuild | 4 |
6 files changed, 141 insertions, 0 deletions
diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c index 86cc91899136..d2e103db6f0e 100644 --- a/CORE/SERVICES/BMI/ol_fw.c +++ b/CORE/SERVICES/BMI/ol_fw.c @@ -747,6 +747,13 @@ static int __ol_transfer_bin_file(struct ol_softc *scn, ATH_BIN_FILE file, OS_MEMCPY(tempEeprom, (u_int8_t *)fw_entry->data, fw_entry_size); + status = vos_update_boarddata(tempEeprom, fw_entry_size); + if (EOK != status) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("wlan: update boarddata failed, status=%d.\n", + status)); + } + switch (scn->target_type) { default: board_data_size = 0; diff --git a/CORE/SERVICES/COMMON/wma_api.h b/CORE/SERVICES/COMMON/wma_api.h index 4d3073b13ce3..2f820835defa 100644 --- a/CORE/SERVICES/COMMON/wma_api.h +++ b/CORE/SERVICES/COMMON/wma_api.h @@ -172,4 +172,6 @@ static inline VOS_STATUS wma_send_egap_conf_params(WMA_HANDLE handle, } #endif +extern int wma_scpc_event_handler(void *handle, u_int8_t *event, u_int32_t len); + #endif diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index df65c6541d1e..ba0ff1115650 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -86,6 +86,8 @@ #include "wdi_out.h" #include "wdi_in.h" +#include "vos_cnss.h" + #include "vos_utils.h" #include "tl_shim.h" #if defined(QCA_WIFI_FTM) @@ -30208,6 +30210,88 @@ static int wma_echo_event_handler(void *handle, u_int8_t *event_buf, return 0; } +#if defined(QCA_WIFI_FTM) && defined(WLAN_SCPC_FEATURE) +/** + * wma_scpc_event_handler() - handler for scpc event from firmware + * @handle: wma context + * @event_buf: pointer to the event buffer + * @len: length of the event buffer + * + * Once SCPC feature is enabled in FTM mode, firmware will do calibration + * and indicates calibrated data in an SCPC message. + * + * This function is used to parse SCPC message. Calibrated data in an SCPC + * message is formated like this: + * patch1 offset(byte3~0), patch1 length(byte7~4), patch1 data + * ...... + * patchn offset(byte3~0), patchn length(byte7~4), patchn data + * All data patches are 4bytes aligned. But the length indicated here is + * not multiple of 4. + * + * Return: 0 on success. + */ +int wma_scpc_event_handler(void *handle, u_int8_t *event_buf, u_int32_t len) +{ + u_int8_t *buf; + u_int32_t length; + u_int32_t i; + u_int32_t n; + WMI_PDEV_UTF_SCPC_EVENTID_param_tlvs *param_buf; + wmi_scpc_event_fixed_param *scpc_event; + struct _bd { + u_int32_t offset; + u_int32_t length; + u_int8_t data[0]; + } *bd_data; + + WMA_LOGD("WMA event <---- SCPC\n"); + if ((event_buf == NULL) || (len < sizeof(wmi_scpc_event_fixed_param))) { + WMA_LOGE("%s: invalid pointer", __func__); + return -EINVAL; + } + + param_buf = (WMI_PDEV_UTF_SCPC_EVENTID_param_tlvs *)event_buf; + scpc_event = param_buf->fixed_param; + length = len - sizeof(wmi_scpc_event_fixed_param); + + + buf = (u_int8_t *)scpc_event + sizeof(wmi_scpc_event_fixed_param); + + WMA_LOGD("%s: section count is %d, data length is %d, tag is 0x%x.\n", + __func__, scpc_event->num_patch, length, *(u_int32_t *)buf); + + /* skip the tag */ + buf += sizeof(u_int32_t); + + i = n = 0; + bd_data = (struct _bd *)&buf[n]; + n += roundup((sizeof(struct _bd) + bd_data->length), 4); + + while ((n < length) && (i < scpc_event->num_patch)) { + bd_data = (struct _bd *)&buf[n]; + + WMA_LOGD("%s: board data patch%i, offset= %d, length= %d.\n", + __func__, i, bd_data->offset, bd_data->length); + /* cache the data section */ + vos_cache_boarddata(bd_data->offset, + bd_data->length, bd_data->data); + + n += roundup((sizeof(struct _bd) + bd_data->length), 4); + i++; + } + + WMA_LOGD("%s: %d patches in message, %d cached.\n", + __func__, scpc_event->num_patch, i); + + return 0; +} +#else +int wma_scpc_event_handler(void *handle, u_int8_t *event_buf, u_int32_t len) +{ + return 0; +} +#endif + /* function : wma_start * Description : * Args : diff --git a/CORE/SERVICES/WMI/wmi_unified.c b/CORE/SERVICES/WMI/wmi_unified.c index 667a41461433..732321e8b413 100644 --- a/CORE/SERVICES/WMI/wmi_unified.c +++ b/CORE/SERVICES/WMI/wmi_unified.c @@ -1012,6 +1012,14 @@ void __wmi_control_rx(struct wmi_unified *wmi_handle, wmi_buf_t evt_buf) pr_debug("%s: WMI event ID is 0x%x\n", __func__, id); #endif + /* This event will be earlier than WMI ready. */ + if (id == WMI_PDEV_UTF_SCPC_EVENTID) { + WMA_LOGD("%s: get WMI_PDEV_UTF_SCPC_EVENTID\n", __func__); + wma_scpc_event_handler(wmi_handle->scn_handle, + wmi_cmd_struct_ptr, len); + goto end; + } + if (id >= WMI_EVT_GRP_START_ID(WMI_GRP_START)) { u_int32_t idx = 0; diff --git a/CORE/VOSS/inc/vos_cnss.h b/CORE/VOSS/inc/vos_cnss.h index ac51e18f2cb8..bdee9fa91544 100644 --- a/CORE/VOSS/inc/vos_cnss.h +++ b/CORE/VOSS/inc/vos_cnss.h @@ -186,6 +186,17 @@ static inline bool vos_is_ssr_fw_dump_required(void) { return true; } + +static inline int vos_update_boarddata(unsigned char *buf, unsigned int len) +{ + return 0; +} + +static inline int vos_cache_boarddata(unsigned int offset, + unsigned int len, unsigned char *buf) +{ + return 0; +} #else static inline void vos_init_work(struct work_struct *work, work_func_t func) { @@ -467,5 +478,30 @@ static inline int vos_pcie_shadow_control(struct pci_dev *dev, bool enable) return cnss_pcie_shadow_control(dev, enable); } #endif + +#if defined(CONFIG_CNSS_SDIO) && defined(WLAN_SCPC_FEATURE) +static inline int vos_update_boarddata(unsigned char *buf, unsigned int len) +{ + return cnss_update_boarddata(buf, len); +} + +static inline int vos_cache_boarddata(unsigned int offset, + unsigned int len, unsigned char *buf) +{ + return cnss_cache_boarddata(buf, len, offset); +} +#else +static inline int vos_update_boarddata(unsigned char *buf, unsigned int len) +{ + return 0; +} + +static inline int vos_cache_boarddata(unsigned int offset, + unsigned int len, unsigned char *buf) +{ + return 0; +} +#endif #endif + #endif/* _VOS_CNSS_H */ @@ -952,6 +952,10 @@ CDEFINES := -DANI_LITTLE_BYTE_ENDIAN \ -DFEATURE_WLAN_CH144 \ -DHTC_CRP_DEBUG +ifeq ($(CONFIG_SCPC_FEATURE), y) +CDEFINES += -DWLAN_SCPC_FEATURE +endif + ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) CDEFINES += -DCONFIG_HL_SUPPORT \ -DCONFIG_AR6320_SUPPORT \ |
