diff --git a/umac/wifi_pos/inc/wifi_pos_api.h b/umac/wifi_pos/inc/wifi_pos_api.h index 9841b15433bc..72665e1b7ddf 100644 --- a/umac/wifi_pos/inc/wifi_pos_api.h +++ b/umac/wifi_pos/inc/wifi_pos_api.h @@ -412,4 +412,33 @@ QDF_STATUS wifi_pos_register_get_phy_mode_cb( struct wlan_objmgr_psoc *psoc, void (*handler)(uint8_t, uint32_t, uint32_t *)); +/** + * wifi_pos_register_send_action: API to register callback to send + * action frames + * @psoc: pointer to psoc object + * @handler: callback to be registered + * + * Return: QDF_STATUS_SUCCESS in case of success, error codes in + * case of failure + */ +QDF_STATUS wifi_pos_register_send_action( + struct wlan_objmgr_psoc *psoc, + void (*handler)(struct wlan_objmgr_psoc *psoc, + uint32_t sub_type, + uint8_t *buf, + uint32_t buf_len)); + +/** + * wifi_pos_send_report_resp: Send report to osif + * @psoc: pointer to psoc object + * @req_id: Request id + * @dest_mac: destination mac address + * @err_code: Error code to be sent + * + * Return: QDF_STATUS_SUCCESS in case of success, error codes in + * case of failure + */ +QDF_STATUS wifi_pos_send_report_resp(struct wlan_objmgr_psoc *psoc, + int req_id, uint8_t *dest_mac, + int err_code); #endif diff --git a/umac/wifi_pos/src/wifi_pos_api.c b/umac/wifi_pos/src/wifi_pos_api.c index c421fa38bdc8..cbcf95cedd84 100644 --- a/umac/wifi_pos/src/wifi_pos_api.c +++ b/umac/wifi_pos/src/wifi_pos_api.c @@ -350,3 +350,31 @@ QDF_STATUS wifi_pos_register_get_phy_mode_cb( return QDF_STATUS_SUCCESS; } +QDF_STATUS wifi_pos_register_send_action( + struct wlan_objmgr_psoc *psoc, + void (*handler)(struct wlan_objmgr_psoc *psoc, + uint32_t sub_type, + uint8_t *buf, + uint32_t buf_len)) +{ + struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; + + if (!psoc) { + wifi_pos_err("psoc is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!handler) { + wifi_pos_err("Null callback"); + return QDF_STATUS_E_NULL_VALUE; + } + wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); + if (!wifi_pos_psoc) { + wifi_pos_err("wifi_pos priv obj is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + wifi_pos_psoc->wifi_pos_send_action = handler; + + return QDF_STATUS_SUCCESS; +} diff --git a/umac/wifi_pos/src/wifi_pos_main.c b/umac/wifi_pos/src/wifi_pos_main.c index de5951062112..b298cbf69b31 100644 --- a/umac/wifi_pos/src/wifi_pos_main.c +++ b/umac/wifi_pos/src/wifi_pos_main.c @@ -99,6 +99,13 @@ static QDF_STATUS wifi_pos_process_data_req(struct wlan_objmgr_psoc *psoc, struct oem_data_req data_req; struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; struct wlan_objmgr_pdev *pdev; + struct wifi_pos_psoc_priv_obj *wifi_pos_obj = + wifi_pos_get_psoc_priv_obj(psoc); + + if (!wifi_pos_obj) { + wifi_pos_err("wifi_pos priv obj is null"); + return QDF_STATUS_E_INVAL; + } wifi_pos_debug("Received data req pid(%d), len(%d)", req->pid, req->buf_len); @@ -151,10 +158,18 @@ static QDF_STATUS wifi_pos_process_data_req(struct wlan_objmgr_psoc *psoc, /* TBD */ break; case TARGET_OEM_CONFIGURE_FTMRR: - /* TBD */ + wifi_pos_debug("FTMRR request"); + if (wifi_pos_obj->wifi_pos_send_action) + wifi_pos_obj->wifi_pos_send_action(psoc, sub_type, + req->buf, + req->buf_len); break; case TARGET_OEM_CONFIGURE_WRU: - /* TBD */ + wifi_pos_debug("WRU request"); + if (wifi_pos_obj->wifi_pos_send_action) + wifi_pos_obj->wifi_pos_send_action(psoc, sub_type, + req->buf, + req->buf_len); break; default: wifi_pos_debug("invalid sub type or not passed"); @@ -234,6 +249,40 @@ static QDF_STATUS wifi_pos_process_get_cap_req(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS wifi_pos_send_report_resp(struct wlan_objmgr_psoc *psoc, + int req_id, uint8_t *dest_mac, + int err_code) +{ + struct wifi_pos_err_msg_report err_report = {0}; + struct wifi_pos_psoc_priv_obj *wifi_pos_obj = + wifi_pos_get_psoc_priv_obj(psoc); + + if (!wifi_pos_obj) { + wifi_pos_err("wifi_pos priv obj is null"); + return QDF_STATUS_E_INVAL; + } + + err_report.msg_tag_len = OEM_MSG_RSP_HEAD_TAG_ID << 16; + err_report.msg_tag_len |= (sizeof(err_report) - + sizeof(err_report.err_rpt)) & 0x0000FFFF; + err_report.msg_subtype = TARGET_OEM_ERROR_REPORT_RSP; + err_report.req_id = req_id & 0xFFFF; + err_report.req_id |= ((err_code & 0xFF) << 16); + err_report.req_id |= (0x1 << 24); + err_report.time_left = 0xFFFFFFFF; + err_report.err_rpt.tag_len = OEM_MEAS_RSP_HEAD_TAG_ID << 16; + err_report.err_rpt.tag_len |= + (sizeof(struct wifi_pos_err_rpt)) & 0x0000FFFF; + memcpy(&err_report.err_rpt.dest_mac, dest_mac, QDF_MAC_ADDR_SIZE); + + wifi_pos_obj->wifi_pos_send_rsp(wifi_pos_obj->app_pid, + ANI_MSG_OEM_DATA_RSP, + sizeof(err_report), + (uint8_t *)&err_report); + + return QDF_STATUS_SUCCESS; +} + static void wifi_update_channel_bw_info(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_pdev *pdev, uint16_t chan, diff --git a/umac/wifi_pos/src/wifi_pos_utils_i.h b/umac/wifi_pos/src/wifi_pos_utils_i.h index 4c23460b1b4c..c94269b51e56 100644 --- a/umac/wifi_pos/src/wifi_pos_utils_i.h +++ b/umac/wifi_pos/src/wifi_pos_utils_i.h @@ -188,6 +188,42 @@ struct qdf_packed wifi_pos_oem_get_cap_rsp { struct wifi_pos_user_defined_caps user_defined_cap; }; +/** + * struct wifi_pos_err_rpt - Error report response for userspace. + * @tag_len: tlv header of the message. + * @info: Report info. Reserved for error report. + * @dest_mac: Mac address of the sta in the request. + * @reserved: Reserved in error report. + */ +struct qdf_packed wifi_pos_err_rpt { + uint32_t tag_len; + uint32_t info; + uint8_t dest_mac[QDF_MAC_ADDR_SIZE + 2]; + uint32_t reserved; +}; + +#define OEM_MSG_RSP_HEAD_TAG_ID 33 +#define OEM_MEAS_RSP_HEAD_TAG_ID 41 +/** + * struct wifi_pos_err_msg_report - Error report message + * @msg_tag_len: Message tlv header + * @msg_subtype: Message subtype + * @req_id: id corresponding to the request. + * @fragment_info: Valid only for fragments. + * @pdev_id: pdev_id of radion. + * @time_left: time left in the measurment req. + * @err_rpt: Error report data. + */ +struct qdf_packed wifi_pos_err_msg_report { + uint32_t msg_tag_len; + uint32_t msg_subtype; + uint32_t req_id; + uint32_t fragment_info; + uint32_t pdev_id; + uint32_t time_left; + struct wifi_pos_err_rpt err_rpt; +}; + /** * struct wifi_pos_dma_rings_cap - capabilities requested by firmware. * @pdev_id: pdev_id or mac_id of ring @@ -306,6 +342,9 @@ struct wifi_pos_psoc_priv_obj { struct wifi_pos_req_msg *req); void (*wifi_pos_send_rsp)(uint32_t, uint32_t, uint32_t, uint8_t *); void (*wifi_pos_get_phy_mode)(uint8_t, uint32_t, uint32_t *); + void (*wifi_pos_send_action)(struct wlan_objmgr_psoc *psoc, + uint32_t oem_subtype, uint8_t *buf, + uint32_t len); }; /**