diff --git a/umac/tdls/core/src/wlan_tdls_cmds_process.c b/umac/tdls/core/src/wlan_tdls_cmds_process.c index 49784df9bd19..51361b65c18f 100644 --- a/umac/tdls/core/src/wlan_tdls_cmds_process.c +++ b/umac/tdls/core/src/wlan_tdls_cmds_process.c @@ -1759,3 +1759,60 @@ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, /*TODO connection tracker update*/ return QDF_STATUS_SUCCESS; } + +/** + * tdls_process_set_responder() - Set/clear TDLS peer's responder role + * @set_req: set responder request + * + * Return: 0 for success or -EINVAL otherwise + */ +static +int tdls_process_set_responder(struct tdls_set_responder_req *set_req) +{ + struct tdls_peer *curr_peer; + struct tdls_vdev_priv_obj *tdls_vdev; + + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(set_req->vdev); + if (!tdls_vdev) { + tdls_err("tdls vdev obj is NULL"); + return -EINVAL; + } + curr_peer = tdls_get_peer(tdls_vdev, set_req->peer_mac); + if (curr_peer == NULL) { + tdls_err("curr_peer is NULL"); + return -EINVAL; + } + + curr_peer->is_responder = set_req->responder; + return 0; +} + + +/** + * tdls_set_responder() - Set/clear TDLS peer's responder role + * @set_req: set responder request + * + * Return: 0 for success or -EINVAL otherwise + */ +int tdls_set_responder(struct tdls_set_responder_req *set_req) +{ + QDF_STATUS status; + + if (!set_req || !set_req->vdev) { + tdls_err("Invalid input params %p", set_req); + return -EINVAL; + } + + status = wlan_objmgr_vdev_try_get_ref(set_req->vdev, WLAN_TDLS_NB_ID); + if (QDF_STATUS_SUCCESS != status) { + tdls_err("vdev object is deleted"); + return -EINVAL; + } + + status = tdls_process_set_responder(set_req); + + wlan_objmgr_vdev_release_ref(set_req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(set_req); + return status; +} + diff --git a/umac/tdls/core/src/wlan_tdls_cmds_process.h b/umac/tdls/core/src/wlan_tdls_cmds_process.h index 32e8cba01ac0..8c17dfebd454 100644 --- a/umac/tdls/core/src/wlan_tdls_cmds_process.h +++ b/umac/tdls/core/src/wlan_tdls_cmds_process.h @@ -259,4 +259,12 @@ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, */ int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); +/** + * tdls_set_responder() - Set/clear TDLS peer's responder role + * @set_req: set responder request + * + * Return: 0 for success or -EINVAL otherwise + */ +int tdls_set_responder(struct tdls_set_responder_req *set_req); + #endif diff --git a/umac/tdls/core/src/wlan_tdls_main.c b/umac/tdls/core/src/wlan_tdls_main.c index 6faeb5dd925e..879290e56b4d 100644 --- a/umac/tdls/core/src/wlan_tdls_main.c +++ b/umac/tdls/core/src/wlan_tdls_main.c @@ -241,6 +241,23 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) break; case TDLS_CMD_CONFIG_UPDATE: break; + case TDLS_CMD_SET_RESPONDER: + tdls_set_responder(msg->bodyptr); + break; + case TDLS_NOTIFY_STA_CONNECTION: + tdls_notify_sta_connect(msg->bodyptr); + break; + case TDLS_NOTIFY_STA_DISCONNECTION: + tdls_notify_sta_disconnect(msg->bodyptr); + break; + case TDLS_CMD_SET_TDLS_MODE: + tdls_set_operation_mode(msg->bodyptr); + break; + case TDLS_CMD_SESSION_INCREMENT: + case TDLS_CMD_SESSION_DECREMENT: + tdls_process_policy_mgr_notification(msg->bodyptr); + break; + default: break; } @@ -1053,3 +1070,35 @@ static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc, tdls_soc->tdls_current_mode = tdls_mode; } + +QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode) +{ + struct tdls_soc_priv_obj *tdls_soc; + struct tdls_vdev_priv_obj *tdls_vdev; + QDF_STATUS status; + + if (!tdls_set_mode || !tdls_set_mode->vdev) + return QDF_STATUS_E_INVAL; + + if (QDF_STATUS_SUCCESS != + wlan_objmgr_vdev_try_get_ref(tdls_set_mode->vdev, + WLAN_TDLS_NB_ID)) + return QDF_STATUS_E_INVAL; + + status = tdls_get_vdev_objects(tdls_set_mode->vdev, + &tdls_vdev, &tdls_soc); + + if (status != QDF_STATUS_SUCCESS) + goto release_mode_ref; + + tdls_set_current_mode(tdls_soc, + tdls_set_mode->tdls_mode, + tdls_set_mode->update_last, + tdls_set_mode->source); + +release_mode_ref: + wlan_objmgr_vdev_release_ref(tdls_set_mode->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(tdls_set_mode); + return status; +} + diff --git a/umac/tdls/core/src/wlan_tdls_main.h b/umac/tdls/core/src/wlan_tdls_main.h index e6929facff01..769f2533c52d 100644 --- a/umac/tdls/core/src/wlan_tdls_main.h +++ b/umac/tdls/core/src/wlan_tdls_main.h @@ -533,42 +533,39 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, */ void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc); +/** + * tdls_set_operation_mode() - set tdls operating mode + * @tdls_set_mode: tdls mode set params + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode); + /** * tdls_notify_sta_connect() - Update tdls state for every * connect event. - * @vdev: vdev object manager - * @tdls_prohibited: flag to tell whether tdls prohibited in this bss - * @tdls_chan_swit_prohibited: flag to tell whether tdls channel switch - * prohibited in this bss - * @session_id: session id + * @notify: sta connect params * * After every connect event in the system, check whether TDLS * can be enabled in the system. If TDLS can be enabled, update the * TDLS state as needed. * - * Return: None + * Return: QDF_STATUS */ -void tdls_notify_sta_connect(struct wlan_objmgr_vdev *vdev, - bool tdls_prohibited, - bool tdls_chan_swit_prohibited, - uint8_t session_id); +QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); /** * tdls_notify_sta_disconnect() - Update tdls state for every * disconnect event. - * @vdev: vdev object manager - * @lfr_roam: roaming case - * @session_id: session id + * @notify: sta disconnect params * * After every disconnect event in the system, check whether TDLS * can be disabled/enabled in the system and update the * TDLS state as needed. * - * Return: None + * Return: QDF_STATUS */ -void tdls_notify_sta_disconnect(struct wlan_objmgr_vdev *vdev, - bool lfr_roam, - uint8_t session_id); +QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); /** * tdls_notify_decrement_session() - Notify the session decrement diff --git a/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h b/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h index 39e9ddebe7a4..4d4b7be4168f 100644 --- a/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h +++ b/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h @@ -178,7 +178,14 @@ enum tdls_command_type { TDLS_CMD_CONFIG_FORCE_PEER, TDLS_CMD_REMOVE_FORCE_PEER, TDLS_CMD_STATS_UPDATE, - TDLS_CMD_CONFIG_UPDATE + TDLS_CMD_CONFIG_UPDATE, + TDLS_CMD_SCAN_DONE, + TDLS_CMD_SET_RESPONDER, + TDLS_NOTIFY_STA_CONNECTION, + TDLS_NOTIFY_STA_DISCONNECTION, + TDLS_CMD_SET_TDLS_MODE, + TDLS_CMD_SESSION_INCREMENT, + TDLS_CMD_SESSION_DECREMENT, }; /** @@ -350,21 +357,21 @@ enum tdls_feature_bit { }; #define TDLS_IS_OFF_CHANNEL_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_OFF_CHANNEL, flags) + CHECK_BIT(flags, TDLS_FEATURE_OFF_CHANNEL) #define TDLS_IS_WMM_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_WMM, flags) + CHECK_BIT(flags, TDLS_FEATURE_WMM) #define TDLS_IS_BUFFER_STA_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_BUFFER_STA, flags) + CHECK_BIT(flags, TDLS_FEATURE_BUFFER_STA) #define TDLS_IS_SLEEP_STA_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_SLEEP_STA, flags) + CHECK_BIT(flags, TDLS_FEATURE_SLEEP_STA) #define TDLS_IS_SCAN_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_SCAN, flags) + CHECK_BIT(flags, TDLS_FEATURE_SCAN) #define TDLS_IS_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_ENABLE, flags) + CHECK_BIT(flags, TDLS_FEATURE_ENABLE) #define TDLS_IS_IMPLICIT_TRIG_ENABLED(flags) \ - CHECK_BIT(TDLS_FEAUTRE_IMPLICIT_TRIGGER, flags) + CHECK_BIT(flags, TDLS_FEAUTRE_IMPLICIT_TRIGGER) #define TDLS_IS_EXTERNAL_CONTROL_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_EXTERNAL_CONTROL, flags) + CHECK_BIT(flags, TDLS_FEATURE_EXTERNAL_CONTROL) /** * struct tdls_user_config - TDLS user configuration @@ -448,6 +455,47 @@ struct tdls_tx_cnf { int status; }; +/** + * struct tdls_rx_mgmt_frame - rx mgmt frame structure + * @frame_len: frame length + * @rx_chan: rx channel + * @vdev_id: vdev id + * @frm_type: frame type + * @rx_rssi: rx rssi + * @buf: buffer address + */ +struct tdls_rx_mgmt_frame { + uint32_t frame_len; + uint32_t rx_chan; + uint32_t vdev_id; + uint32_t frm_type; + uint32_t rx_rssi; + uint8_t buf[1]; +}; + +/** + * tdls_rx_callback() - Callback for rx mgmt frame + * @user_data: user data associated to this rx mgmt frame. + * @rx_frame: RX mgmt frame + * + * This callback will be used to give rx frames to hdd. + * + * Return: None + */ +typedef void (*tdls_rx_callback)(void *user_data, + struct tdls_rx_mgmt_frame *rx_frame); + +/** + * tdls_wmm_check() - Callback for wmm info + * @psoc: psoc object + * + * This callback will be used to check wmm information + * + * Return: true or false + */ +typedef bool (*tdls_wmm_check)(struct wlan_objmgr_vdev **vdev); + + /* This callback is used to report state change of peer to wpa_supplicant */ typedef int (*tdls_state_change_callback)(const uint8_t *mac, uint32_t opclass, @@ -497,6 +545,10 @@ struct tdls_start_params { uint16_t tdls_add_sta_req; uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; + tdls_rx_callback tdls_rx_cb; + void *tdls_rx_cb_data; + tdls_wmm_check tdls_wmm_cb; + void *tdls_wmm_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; tdls_tx_ack_cnf_callback ack_cnf_cb; @@ -848,6 +900,7 @@ struct tdls_event_notify { * @dialog: dialog token used in the frame. * @status_code: status to be incuded in the frame * @responder: Tdls request type + * @len: lenght of additional Ies * @peer_capability: peer cpabilities * @len: lenght of additional Ies * @buf: additional IEs to be included @@ -864,15 +917,39 @@ struct tdls_send_mgmt { uint8_t *buf; }; +/** + * struct tdls_validate_action_req - tdls validate mgmt request + * @vdev: vdev object + * @action_code: action code + * @peer_mac: peer mac address + * @dialog_token: dialog code + * @status_code: status code to add + * @len: len of the frame + * @responder: whether to respond or not + * @max_sta_failed: mgmt failure reason + */ +struct tdls_validate_action_req { + struct wlan_objmgr_vdev *vdev; + uint8_t action_code; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + uint8_t dialog_token; + uint8_t status_code; + size_t len; + int responder; + int max_sta_failed; +}; + /** * struct tdls_send_action_frame_request - tdls send mgmt request * @vdev: vdev object + * @chk_frame: frame validation structure * @session_id: session id * @vdev_id: vdev id * @tdls_mgmt: tdls managment */ struct tdls_action_frame_request { struct wlan_objmgr_vdev *vdev; + struct tdls_validate_action_req *chk_frame; uint8_t session_id; uint8_t vdev_id; const uint8_t *cmd_buf; @@ -880,4 +957,46 @@ struct tdls_action_frame_request { struct tdls_send_mgmt tdls_mgmt; }; +/** + * struct tdls_set_responder_req - tdls set responder in peer + * @vdev: vdev object + * @peer_mac: peer mac address + * @responder: whether to respond or not + */ +struct tdls_set_responder_req { + struct wlan_objmgr_vdev *vdev; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + uint8_t responder; +}; + +/** + * struct tdls_sta_notify_params - STA connection notify info + * @vdev: vdev object + * @tdls_prohibited: peer mac addr + * @tdls_chan_swit_prohibited: peer type + * @lfr_roam: is trigger due to lfr + * @session_id: session id + */ +struct tdls_sta_notify_params { + struct wlan_objmgr_vdev *vdev; + bool tdls_prohibited; + bool tdls_chan_swit_prohibited; + bool lfr_roam; + uint8_t session_id; +}; + +/** + * struct tdls_set_mode_params - TDLS set mode params + * @vdev: vdev object + * @tdls_mode: tdls mode to set + * @update_last: inform to update last tdls mode + * @source: mode change requester + */ +struct tdls_set_mode_params { + struct wlan_objmgr_vdev *vdev; + enum tdls_feature_mode tdls_mode; + bool update_last; + enum tdls_disable_sources source; +}; + #endif diff --git a/umac/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h b/umac/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h index 302043fff731..6c7d117b44d9 100644 --- a/umac/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/umac/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -130,4 +130,59 @@ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, QDF_STATUS ucfg_tdls_send_mgmt_frame( struct tdls_action_frame_request *mgmt_req); +/** + * ucfg_tdls_responder() - set responder in TDLS peer + * @msg_req: responder msg + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *msg_req); + +/** + * ucfg_tdls_notify_sta_connect() - notify sta connect + * @notify_info: sta notification info + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_notify_sta_connect( + struct tdls_sta_notify_params *notify_info); + +/** + * ucfg_tdls_notify_sta_disconnect() - notify sta disconnect + * @notify_info: sta notification info + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_notify_sta_disconnect( + struct tdls_sta_notify_params *notify_info); + +/** + * ucfg_tdls_set_operating_mode() - set operating mode + * @set_mode_params: set mode params + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_set_operating_mode( + struct tdls_set_mode_params *set_mode_params); + +/** + * ucfg_tdls_update_rx_pkt_cnt() - update rx pkt count + * @vdev: tdls vdev object + * @mac_addr: peer mac address + * + * Return: None + */ +void ucfg_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr); + +/** + * ucfg_tdls_update_tx_pkt_cnt() - update tx pkt count + * @vdev: tdls vdev object + * @mac_addr: peer mac address + * + * Return: None + */ +void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr); + #endif diff --git a/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c b/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c index be63fbdbd87c..ce21c05bf406 100644 --- a/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c @@ -26,6 +26,7 @@ #include #include "../../core/src/wlan_tdls_main.h" #include "../../core/src/wlan_tdls_cmds_process.h" +#include "../../core/src/wlan_tdls_ct.h" #include #include #include "wlan_policy_mgr_api.h" @@ -486,3 +487,152 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( return QDF_STATUS_SUCCESS; } + +QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) +{ + struct scheduler_msg msg = {0, }; + struct tdls_set_responder_req *msg_req; + QDF_STATUS status; + + if (!req || !req->vdev) { + tdls_err("invalid input %p", req); + return QDF_STATUS_E_NULL_VALUE; + } + + msg_req = qdf_mem_malloc(sizeof(*msg_req)); + if (!msg_req) + return QDF_STATUS_E_NULL_VALUE; + + msg_req->responder = req->responder; + msg_req->vdev = req->vdev; + qdf_mem_copy(msg_req->peer_mac, req->peer_mac, QDF_MAC_ADDR_SIZE); + + msg.bodyptr = msg_req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_RESPONDER; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + return status; +} + +QDF_STATUS ucfg_tdls_notify_sta_connect( + struct tdls_sta_notify_params *notify_info) +{ + struct scheduler_msg msg = {0, }; + struct tdls_sta_notify_params *notify; + + if (!notify_info || !notify_info->vdev) { + tdls_err("notify_info->vdev: %p, notify_info %p", + notify_info->vdev, notify_info); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_notice("Enter "); + + notify = qdf_mem_malloc(sizeof(*notify)); + if (!notify) + return QDF_STATUS_E_NULL_VALUE; + + notify->session_id = notify_info->session_id; + notify->tdls_chan_swit_prohibited = + notify_info->tdls_chan_swit_prohibited; + notify->tdls_prohibited = notify_info->tdls_prohibited; + notify->vdev = notify_info->vdev; + + msg.bodyptr = notify; + msg.callback = tdls_process_cmd; + msg.type = TDLS_NOTIFY_STA_CONNECTION; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + tdls_notice("Exit "); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_notify_sta_disconnect( + struct tdls_sta_notify_params *notify_info) +{ + struct scheduler_msg msg = {0, }; + struct tdls_sta_notify_params *notify; + + if (!notify_info || !notify_info->vdev) { + tdls_err("notify_info->vdev: %p, notify_info %p", + notify_info->vdev, notify_info); + return QDF_STATUS_E_NULL_VALUE; + } + + tdls_notice("Enter "); + + notify = qdf_mem_malloc(sizeof(*notify)); + if (!notify) + return QDF_STATUS_E_NULL_VALUE; + + notify->session_id = notify_info->session_id; + notify->tdls_chan_swit_prohibited = false; + notify->tdls_prohibited = false; + notify->vdev = notify_info->vdev; + + msg.bodyptr = notify; + msg.callback = tdls_process_cmd; + msg.type = TDLS_NOTIFY_STA_DISCONNECTION; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + tdls_notice("Exit "); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_set_operating_mode( + struct tdls_set_mode_params *set_mode_params) +{ + struct scheduler_msg msg = {0, }; + struct tdls_set_mode_params *set_mode; + + if (!set_mode_params || !set_mode_params->vdev) { + tdls_err("vdev: %p, set_mode_params %p", + set_mode_params->vdev, set_mode_params); + return QDF_STATUS_E_NULL_VALUE; + } + + tdls_notice("Enter "); + + set_mode = qdf_mem_malloc(sizeof(*set_mode)); + if (!set_mode) + return QDF_STATUS_E_NULL_VALUE; + + set_mode->source = set_mode_params->source; + set_mode->tdls_mode = set_mode_params->tdls_mode; + set_mode->update_last = set_mode_params->update_last; + set_mode->vdev = set_mode_params->vdev; + + msg.bodyptr = set_mode; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_TDLS_MODE; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + tdls_notice("Exit "); + + return QDF_STATUS_SUCCESS; +} + +void ucfg_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr) +{ + QDF_STATUS status; + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (status != QDF_STATUS_SUCCESS) + return; + tdls_update_rx_pkt_cnt(vdev, mac_addr); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +} + +void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr) +{ + QDF_STATUS status; + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (status != QDF_STATUS_SUCCESS) + return; + tdls_update_tx_pkt_cnt(vdev, mac_addr); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +}