qcacld-3.0: Handle legacy connect request

Handle legacy connect request and create pe_session
for the same.

Change-Id: Ie1e801c42f90d79d613f9d0233ec9a00a2b0d58b
CRs-Fixed: 2808000
This commit is contained in:
gaurank kathpalia
2020-10-29 12:21:52 +05:30
committed by snandini
parent 2dc00ea324
commit e5fb361504
4 changed files with 297 additions and 2 deletions

View File

@@ -29,7 +29,7 @@
#include "scheduler_api.h"
/**
* struct cm_vdev_join_req - connect req from legacy CM to peer manager
* struct cm_vdev_join_req - connect req from legacy CM to vdev manager
* @vdev_id: vdev id
* @cm_id: Connect manager id
* @force_rsne_override: force the arbitrary rsne received in connect req to be
@@ -49,6 +49,16 @@ struct cm_vdev_join_req {
struct scan_cache_entry *entry;
};
/**
* struct cm_vdev_join_rsp - connect rsp from vdev mgr to connection mgr
* @psoc: psoc object
* @connect_rsp: Connect response to be sent to CM
*/
struct cm_vdev_join_rsp {
struct wlan_objmgr_psoc *psoc;
struct wlan_cm_connect_rsp connect_rsp;
};
/**
* cm_handle_connect_req() - Connection manager ext connect request to start
* vdev and peer assoc state machine
@@ -156,6 +166,25 @@ QDF_STATUS cm_process_join_req(struct scheduler_msg *msg);
*/
QDF_STATUS cm_process_disconnect_req(struct scheduler_msg *msg);
/**
* wlan_cm_send_connect_rsp() - Process vdev join rsp and send to CM
* @msg: scheduler message
*
* Process connect response and send it to CM SM.
*
* Return: QDF_STATUS
*/
QDF_STATUS wlan_cm_send_connect_rsp(struct scheduler_msg *msg);
/**
* wlan_cm_free_connect_rsp() - Function to free all params in join rsp
* @rsp: CM join response
*
* Function to free up all the memory in join rsp.
*
* Return: void
*/
void wlan_cm_free_connect_rsp(struct cm_vdev_join_rsp *rsp);
#endif /* FEATURE_CM_ENABLE */
#endif /* __WLAN_CM_VDEV_API_H__ */

View File

@@ -22,6 +22,7 @@
#include "wlan_cm_vdev_api.h"
#include "wlan_scan_utils_api.h"
#include "wlan_mlme_dbg.h"
#include "wlan_cm_api.h"
void cm_free_join_req(struct cm_vdev_join_req *join_req)
{
@@ -84,6 +85,35 @@ cm_copy_join_params(struct cm_vdev_join_req *join_req,
return QDF_STATUS_SUCCESS;
}
QDF_STATUS wlan_cm_send_connect_rsp(struct scheduler_msg *msg)
{
struct cm_vdev_join_rsp *rsp;
struct wlan_objmgr_vdev *vdev;
QDF_STATUS status;
if (!msg || !msg->bodyptr)
return QDF_STATUS_E_FAILURE;
rsp = msg->bodyptr;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(rsp->psoc,
rsp->connect_rsp.vdev_id,
WLAN_MLME_CM_ID);
if (!vdev) {
mlme_err("vdev_id: %d cm_id 0x%x : vdev not found",
rsp->connect_rsp.vdev_id, rsp->connect_rsp.cm_id);
wlan_cm_free_connect_rsp(rsp);
return QDF_STATUS_E_INVAL;
}
status = wlan_cm_connect_rsp(vdev, &rsp->connect_rsp);
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
wlan_cm_free_connect_rsp(rsp);
return status;
}
QDF_STATUS
cm_handle_connect_req(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_vdev_connect_req *req)
@@ -134,3 +164,37 @@ cm_handle_connect_complete(struct wlan_objmgr_vdev *vdev,
{
return QDF_STATUS_SUCCESS;
}
#ifdef WLAN_FEATURE_FILS_SK
static inline void wlan_cm_free_fils_ie(struct wlan_connect_rsp_ies *connect_ie)
{
if (!connect_ie->fils_ie)
return;
if (connect_ie->fils_ie->fils_pmk) {
qdf_mem_zero(connect_ie->fils_ie->fils_pmk,
connect_ie->fils_ie->fils_pmk_len);
qdf_mem_free(connect_ie->fils_ie->fils_pmk);
}
qdf_mem_zero(connect_ie->fils_ie, sizeof(*connect_ie->fils_ie));
qdf_mem_free(connect_ie->fils_ie);
}
#else
static inline void wlan_cm_free_fils_ie(struct wlan_connect_rsp_ies *connect_ie)
{
}
#endif
void wlan_cm_free_connect_rsp(struct cm_vdev_join_rsp *rsp)
{
struct wlan_connect_rsp_ies *connect_ie =
&rsp->connect_rsp.connect_ies;
qdf_mem_free(connect_ie->assoc_req.ptr);
qdf_mem_free(connect_ie->bcn_probe_rsp.ptr);
qdf_mem_free(connect_ie->assoc_rsp.ptr);
qdf_mem_free(connect_ie->ric_resp_ie.ptr);
wlan_cm_free_fils_ie(connect_ie);
qdf_mem_zero(rsp, sizeof(*rsp));
qdf_mem_free(rsp);
}

View File

@@ -19,6 +19,7 @@
#if !defined(__LIM_SESSION_H)
#define __LIM_SESSION_H
#include "wlan_cm_public_struct.h"
/**=========================================================================
\file lim_session.h
@@ -140,6 +141,9 @@ struct obss_detection_cfg {
struct pe_session {
/* To check session table is in use or free */
uint8_t available;
#ifdef FEATURE_CM_ENABLE
wlan_cm_id cm_id;
#endif
uint16_t peSessionId;
union {
uint8_t smeSessionId;

View File

@@ -1339,10 +1339,209 @@ lim_get_vdev_rmf_capable(struct mac_context *mac, struct pe_session *session)
#endif
#ifdef FEATURE_CM_ENABLE
static QDF_STATUS
lim_cm_prepare_join_rsp_from_pe_session(struct pe_session *pe_session,
struct cm_vdev_join_rsp *rsp,
enum wlan_cm_connect_fail_reason reason,
QDF_STATUS connect_status,
enum wlan_status_code status_code)
{
struct wlan_cm_connect_rsp *connect_rsp = &rsp->connect_rsp;
struct wlan_connect_rsp_ies *connect_ie = &rsp->connect_rsp.connect_ies;
connect_rsp->cm_id = pe_session->cm_id;
connect_rsp->vdev_id = pe_session->vdev_id;
qdf_mem_copy(connect_rsp->bssid.bytes, pe_session->bssId,
QDF_MAC_ADDR_SIZE);
connect_rsp->freq = pe_session->curr_op_freq;
connect_rsp->connect_status = connect_status;
connect_rsp->reason = reason;
connect_rsp->reason_code = status_code;
connect_rsp->ssid.length =
QDF_MIN(WLAN_SSID_MAX_LEN, pe_session->ssId.length);
qdf_mem_copy(connect_rsp->ssid.ssid, pe_session->ssId.ssId,
connect_rsp->ssid.length);
connect_rsp->aid = pe_session->limAID;
if (pe_session->assoc_req) {
connect_ie->assoc_req.len = pe_session->assocReqLen;
connect_ie->assoc_req.ptr =
qdf_mem_malloc(sizeof(connect_ie->assoc_req.len));
if (!connect_ie->assoc_req.ptr)
return QDF_STATUS_E_NOMEM;
qdf_mem_copy(connect_ie->assoc_req.ptr, pe_session->assoc_req,
connect_ie->assoc_req.len);
}
if (pe_session->assocRsp) {
connect_ie->assoc_rsp.len = pe_session->assocRspLen;
connect_ie->assoc_rsp.ptr =
qdf_mem_malloc(sizeof(connect_ie->assoc_rsp.len));
if (!connect_ie->assoc_rsp.ptr)
return QDF_STATUS_E_NOMEM;
qdf_mem_copy(connect_ie->assoc_rsp.ptr, pe_session->assocRsp,
connect_ie->assoc_rsp.len);
}
return QDF_STATUS_SUCCESS;
}
static void
lim_cm_fill_join_rsp_from_connect_req(struct cm_vdev_join_req *req,
struct cm_vdev_join_rsp *rsp,
enum wlan_cm_connect_fail_reason reason)
{
struct wlan_cm_connect_rsp *connect_rsp = &rsp->connect_rsp;
connect_rsp->cm_id = req->cm_id;
connect_rsp->vdev_id = req->vdev_id;
qdf_copy_macaddr(&connect_rsp->bssid, &req->entry->bssid);
connect_rsp->freq = req->entry->channel.chan_freq;
connect_rsp->connect_status = QDF_STATUS_E_FAILURE;
connect_rsp->reason = reason;
connect_rsp->ssid = req->entry->ssid;
}
static QDF_STATUS lim_cm_flush_connect_rsp(struct scheduler_msg *msg)
{
struct cm_vdev_join_rsp *rsp;
if (!msg || !msg->bodyptr)
return QDF_STATUS_E_INVAL;
rsp = msg->bodyptr;
wlan_cm_free_connect_rsp(rsp);
return QDF_STATUS_SUCCESS;
}
static void
lim_cm_send_connect_rsp(struct mac_context *mac_ctx,
struct pe_session *pe_session,
struct cm_vdev_join_req *req,
enum wlan_cm_connect_fail_reason reason,
QDF_STATUS connect_status,
enum wlan_status_code status_code)
{
struct cm_vdev_join_rsp *rsp;
QDF_STATUS status;
struct scheduler_msg msg;
if (!pe_session && !req)
return;
rsp = qdf_mem_malloc(sizeof(*rsp));
if (!rsp)
return;
rsp->psoc = mac_ctx->psoc;
if (!pe_session) {
lim_cm_fill_join_rsp_from_connect_req(req, rsp, reason);
} else {
status =
lim_cm_prepare_join_rsp_from_pe_session(pe_session,
rsp,
reason,
connect_status,
status_code);
if (QDF_IS_STATUS_ERROR(status)) {
wlan_cm_free_connect_rsp(rsp);
return;
}
}
qdf_mem_zero(&msg, sizeof(msg));
msg.bodyptr = rsp;
msg.callback = wlan_cm_send_connect_rsp;
msg.flush_callback = lim_cm_flush_connect_rsp;
status = scheduler_post_message(QDF_MODULE_ID_PE,
QDF_MODULE_ID_SME,
QDF_MODULE_ID_SME, &msg);
if (QDF_IS_STATUS_ERROR(status)) {
pe_err("vdev_id: %d cm_id 0x%x : msg post fails",
rsp->connect_rsp.vdev_id, rsp->connect_rsp.cm_id);
wlan_cm_free_connect_rsp(rsp);
}
}
static struct pe_session *
lim_cm_create_session(struct mac_context *mac_ctx, struct cm_vdev_join_req *req)
{
struct pe_session *pe_session;
uint8_t session_id;
struct wlan_objmgr_vdev *vdev;
pe_session = pe_find_session_by_bssid(mac_ctx, req->entry->bssid.bytes,
&session_id);
if (pe_session) {
pe_err("vdev_id: %d cm_id 0x%x :pe-session(%d (vdev %d)) already exists for BSSID: "
QDF_MAC_ADDR_FMT " in lim_sme_state = %X",
req->vdev_id, req->cm_id, session_id,
pe_session->vdev_id,
QDF_MAC_ADDR_REF(req->entry->bssid.bytes),
pe_session->limSmeState);
return NULL;
}
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
req->vdev_id,
WLAN_MLME_CM_ID);
if (!vdev) {
pe_err("vdev_id: %d cm_id 0x%x : vdev not found", req->vdev_id,
req->cm_id);
return NULL;
}
pe_session = pe_create_session(mac_ctx, req->entry->bssid.bytes,
&session_id,
mac_ctx->lim.max_sta_of_pe_session,
eSIR_INFRASTRUCTURE_MODE,
req->vdev_id,
wlan_vdev_mlme_get_opmode(vdev));
if (!pe_session)
pe_err("vdev_id: %d cm_id 0x%x : pe_session create failed BSSID"
QDF_MAC_ADDR_FMT, req->vdev_id, req->cm_id,
QDF_MAC_ADDR_REF(req->entry->bssid.bytes));
pe_session->cm_id = req->cm_id;
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
return pe_session;
}
static QDF_STATUS
lim_cm_handle_join_req(struct cm_vdev_join_req *req)
{
struct mac_context *mac_ctx;
struct pe_session *pe_session;
if (!req)
return QDF_STATUS_E_INVAL;
mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
if (!mac_ctx)
return QDF_STATUS_E_INVAL;
pe_session = lim_cm_create_session(mac_ctx, req);
if (!pe_session)
goto fail;
return QDF_STATUS_SUCCESS;
fail:
lim_cm_send_connect_rsp(mac_ctx, pe_session, req, CM_GENERIC_FAILURE,
QDF_STATUS_E_FAILURE, 0);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS cm_process_join_req(struct scheduler_msg *msg)
@@ -1679,7 +1878,6 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf)
ret_code = eSIR_SME_INVALID_PARAMETERS;
goto end;
}
}
if (sme_join_req->addIEScan.length)
qdf_mem_copy(&session->lim_join_req->addIEScan,