diff --git a/components/mlme/core/src/wlan_mlme_twt_api.c b/components/mlme/core/src/wlan_mlme_twt_api.c index 8d2e93e69b4d..5661e07e0b7a 100644 --- a/components/mlme/core/src/wlan_mlme_twt_api.c +++ b/components/mlme/core/src/wlan_mlme_twt_api.c @@ -127,7 +127,7 @@ void mlme_set_twt_setup_done(struct wlan_objmgr_psoc *psoc, for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) { if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) { peer_priv->twt_ctx.session_info[i].setup_done = is_set; - mlme_legacy_debug("setup done dialog:%d", + mlme_legacy_debug("setup done:%d dialog:%d", is_set, dialog_id); break; } diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c index babd238dee7d..45d2cacbe1e1 100644 --- a/core/hdd/src/wlan_hdd_twt.c +++ b/core/hdd/src/wlan_hdd_twt.c @@ -99,6 +99,10 @@ qca_wlan_vendor_twt_nudge_dialog_policy[QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAX + 1] [QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR] = VENDOR_NLA_POLICY_MAC_ADDR, }; +static +int hdd_send_twt_del_dialog_cmd(struct hdd_context *hdd_ctx, + struct wmi_twt_del_dialog_param *twt_params); + /** * hdd_twt_setup_req_type_to_cmd() - Converts twt setup request type to twt cmd * @req_type: twt setup request type @@ -1277,17 +1281,52 @@ static QDF_STATUS hdd_send_twt_setup_response( return status; } +/** + * hdd_twt_handle_renego_failure() - Upon re-nego failure send TWT teardown + * + * @adapter: Adapter pointer + * @add_dialog_event: Pointer to Add dialog complete event structure + * + * Upon re-negotiation failure, this function constructs TWT teardown + * message to the target. + * + * Return: None + */ +static void +hdd_twt_handle_renego_failure(struct hdd_adapter *adapter, + struct twt_add_dialog_complete_event *add_dialog_event) +{ + struct wmi_twt_del_dialog_param params = {0}; + + if (!add_dialog_event) + return; + + qdf_mem_copy(params.peer_macaddr, + add_dialog_event->params.peer_macaddr, + QDF_MAC_ADDR_SIZE); + params.vdev_id = add_dialog_event->params.vdev_id; + params.dialog_id = add_dialog_event->params.dialog_id; + + hdd_debug("renego: twt_terminate: vdev_id:%d dialog_id:%d peer mac_addr " + QDF_MAC_ADDR_FMT, params.vdev_id, params.dialog_id, + QDF_MAC_ADDR_REF(params.peer_macaddr)); + + hdd_send_twt_del_dialog_cmd(adapter->hdd_ctx, ¶ms); +} + /** * hdd_twt_add_dialog_comp_cb() - HDD callback for twt add dialog * complete event * @psoc: Pointer to global psoc * @add_dialog_event: Pointer to Add dialog complete event structure + * @renego_fail: Flag to indicate if its re-negotiation failure case * * Return: None */ static void hdd_twt_add_dialog_comp_cb(struct wlan_objmgr_psoc *psoc, - struct twt_add_dialog_complete_event *add_dialog_event) + struct twt_add_dialog_complete_event *add_dialog_event, + bool renego_fail) { struct hdd_adapter *adapter; uint8_t vdev_id = add_dialog_event->params.vdev_id; @@ -1298,11 +1337,15 @@ hdd_twt_add_dialog_comp_cb(struct wlan_objmgr_psoc *psoc, return; } - hdd_debug("TWT: add dialog_id:%d, status:%d vdev_id %d peer mac_addr " + hdd_debug("TWT: add dialog_id:%d, status:%d vdev_id:%d renego_fail:%d peer mac_addr " QDF_MAC_ADDR_FMT, add_dialog_event->params.dialog_id, - add_dialog_event->params.status, vdev_id, + add_dialog_event->params.status, vdev_id, renego_fail, QDF_MAC_ADDR_REF(add_dialog_event->params.peer_macaddr)); + hdd_send_twt_setup_response(adapter, add_dialog_event); + + if (renego_fail) + hdd_twt_handle_renego_failure(adapter, add_dialog_event); } /** diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index 2660e5070c4a..6750a8b94aa0 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -164,10 +164,12 @@ typedef void (*twt_disable_cb)(hdd_handle_t hdd_handle); * typedef twt_add_dialog_cb - TWT add dialog callback signature. * @psoc: Pointer to global psoc * @add_dialog_evt: pointer to event buf containing twt response parameters + * @renego_fail: Flag to indicate if its re-negotiation failure case */ typedef void (*twt_add_dialog_cb)(struct wlan_objmgr_psoc *psoc, - struct twt_add_dialog_complete_event *add_dialog_evt); + struct twt_add_dialog_complete_event *add_dialog_evt, + bool renego_fail); /** * typedef twt_del_dialog_cb - TWT delete dialog callback signature. @@ -229,7 +231,8 @@ struct twt_callbacks { struct wmi_twt_enable_complete_event_param *params); void (*twt_disable_cb)(hdd_handle_t hdd_handle); void (*twt_add_dialog_cb)(struct wlan_objmgr_psoc *psoc, - struct twt_add_dialog_complete_event *add_dialog_event); + struct twt_add_dialog_complete_event *add_dialog_event, + bool renego); void (*twt_del_dialog_cb)(struct wlan_objmgr_psoc *psoc, struct wmi_twt_del_dialog_complete_event_param *params); void (*twt_pause_dialog_cb)(struct wlan_objmgr_psoc *psoc, diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 1c145d614b61..ec10f762dc87 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -2053,33 +2053,47 @@ static QDF_STATUS sme_process_antenna_mode_resp(struct mac_context *mac, #ifdef WLAN_SUPPORT_TWT /** - * sme_process_twt_add_dialog_event() - Process twt add dialog event - * response from firmware + * sme_process_twt_add_renego_failure() - Process TWT re-negotiation failure + * * @mac: Global MAC pointer * @add_dialog_event: pointer to event buf containing twt response parameters * * Return: None */ static void -sme_process_twt_add_dialog_event(struct mac_context *mac, +sme_process_twt_add_renego_failure(struct mac_context *mac, struct twt_add_dialog_complete_event *add_dialog_event) { twt_add_dialog_cb callback; - bool is_evt_allowed; - is_evt_allowed = mlme_twt_is_command_in_progress( + /* Reset the active TWT command to none */ + mlme_set_twt_command_in_progress( mac->psoc, (struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr, - add_dialog_event->params.dialog_id, WLAN_TWT_SETUP); - if (!is_evt_allowed) { - sme_debug("add dialog event dropped for id:%d", - add_dialog_event->params.dialog_id); - return; - } + add_dialog_event->params.dialog_id, WLAN_TWT_NONE); callback = mac->sme.twt_add_dialog_cb; if (callback) - callback(mac->psoc, add_dialog_event); + callback(mac->psoc, add_dialog_event, true); +} + +/** + * sme_process_twt_add_initial_nego() - Process initial TWT setup or + * re-negotiation successful setup + * @mac: Global MAC pointer + * @add_dialog_event: pointer to event buf containing twt response parameters + * + * Return: None + */ +static void +sme_process_twt_add_initial_nego(struct mac_context *mac, + struct twt_add_dialog_complete_event *add_dialog_event) +{ + twt_add_dialog_cb callback; + + callback = mac->sme.twt_add_dialog_cb; + if (callback) + callback(mac->psoc, add_dialog_event, false); /* Reset the active TWT command to none */ mlme_set_twt_command_in_progress( @@ -2106,6 +2120,46 @@ sme_process_twt_add_dialog_event(struct mac_context *mac, WLAN_TWT_SETUP_STATE_ACTIVE); } +/** + * sme_process_twt_add_dialog_event() - Process twt add dialog event + * response from firmware + * @mac: Global MAC pointer + * @add_dialog_event: pointer to event buf containing twt response parameters + * + * Return: None + */ +static void +sme_process_twt_add_dialog_event(struct mac_context *mac, + struct twt_add_dialog_complete_event *add_dialog_event) +{ + bool is_evt_allowed; + bool setup_done; + enum WMI_HOST_ADD_TWT_STATUS status; + + is_evt_allowed = mlme_twt_is_command_in_progress( + mac->psoc, + (struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr, + add_dialog_event->params.dialog_id, WLAN_TWT_SETUP); + if (!is_evt_allowed) { + sme_debug("add dialog event dropped for id:%d", + add_dialog_event->params.dialog_id); + return; + } + + setup_done = ucfg_mlme_is_twt_setup_done(mac->psoc, + (struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr, + add_dialog_event->params.dialog_id); + status = add_dialog_event->params.status; + sme_debug("setup_done: %d status: %d", setup_done, status); + + if (setup_done && status) { + /* This is re-negotiation failure case */ + sme_process_twt_add_renego_failure(mac, add_dialog_event); + } else { + sme_process_twt_add_initial_nego(mac, add_dialog_event); + } +} + static bool sme_is_twt_teardown_failed(enum WMI_HOST_DEL_TWT_STATUS teardown_status) { @@ -14467,7 +14521,7 @@ QDF_STATUS sme_add_dialog_cmd(mac_handle_t mac_handle, twt_params->dialog_id, WLAN_TWT_ANY); if (is_twt_cmd_in_progress) { sme_debug("Already TWT command is in progress"); - return QDF_STATUS_E_AGAIN; + return QDF_STATUS_E_PENDING; } wma_handle = cds_get_context(QDF_MODULE_ID_WMA); @@ -14552,7 +14606,7 @@ QDF_STATUS sme_del_dialog_cmd(mac_handle_t mac_handle, twt_params->dialog_id, WLAN_TWT_TERMINATE); if (is_twt_cmd_in_progress) { sme_debug("Already TWT command is in progress"); - return QDF_STATUS_E_AGAIN; + return QDF_STATUS_E_PENDING; } wma_handle = cds_get_context(QDF_MODULE_ID_WMA); @@ -14622,7 +14676,7 @@ sme_pause_dialog_cmd(mac_handle_t mac_handle, twt_params->dialog_id, WLAN_TWT_ANY); if (is_twt_cmd_in_progress) { sme_debug("Already TWT command is in progress"); - return QDF_STATUS_E_AGAIN; + return QDF_STATUS_E_PENDING; } wma_handle = cds_get_context(QDF_MODULE_ID_WMA); @@ -14691,7 +14745,7 @@ sme_nudge_dialog_cmd(mac_handle_t mac_handle, twt_params->dialog_id, WLAN_TWT_ANY); if (is_twt_cmd_in_progress) { sme_debug("Already TWT command is in progress"); - return QDF_STATUS_E_AGAIN; + return QDF_STATUS_E_PENDING; } wma_handle = cds_get_context(QDF_MODULE_ID_WMA); if (!wma_handle) { @@ -14759,7 +14813,7 @@ sme_resume_dialog_cmd(mac_handle_t mac_handle, twt_params->dialog_id, WLAN_TWT_ANY); if (is_twt_cmd_in_progress) { sme_debug("Already TWT command is in progress"); - return QDF_STATUS_E_AGAIN; + return QDF_STATUS_E_PENDING; } wma_handle = cds_get_context(QDF_MODULE_ID_WMA);