qcacmn: NDP_INITIATOR_REQ implementation

Add implementation for NDP_INITIATOR_REQ.

Change-Id: Ieb4cb79d500fd75b23b4a3f8bfa414d14eb6fe18
CRs-Fixed: 2014795
This commit is contained in:
Naveen Rawat
2017-04-05 17:26:18 -07:00
committed by Sandeep Puligilla
父節點 e830e98bcf
當前提交 06a5eb5071
共有 8 個文件被更改,包括 1402 次插入8 次删除

查看文件

@@ -492,6 +492,12 @@ struct nan_callbacks {
void (*drv_ndi_create_rsp_handler)(uint8_t,
struct nan_datapath_inf_create_rsp *);
void (*drv_ndi_delete_rsp_handler)(uint8_t);
int (*new_peer_ind)(uint8_t, uint16_t, struct qdf_mac_addr *, bool);
int (*get_peer_idx)(uint8_t, struct qdf_mac_addr *);
QDF_STATUS (*add_ndi_peer)(uint32_t, struct qdf_mac_addr);
void (*delete_peers_by_addr)(uint8_t, struct qdf_mac_addr);
};
#endif

查看文件

@@ -256,3 +256,161 @@ QDF_STATUS nan_scheduled_msg_handler(struct scheduler_msg *msg)
}
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS nan_handle_confirm(
struct nan_datapath_confirm_event *confirm)
{
uint8_t vdev_id;
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct wlan_objmgr_psoc *psoc;
struct nan_psoc_priv_obj *psoc_nan_obj;
vdev_id = wlan_vdev_get_id(confirm->vdev);
psoc = wlan_vdev_get_psoc(confirm->vdev);
if (!psoc) {
nan_err("psoc is null");
status = QDF_STATUS_E_NULL_VALUE;
goto free_resource;
}
psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
if (!psoc_nan_obj) {
nan_err("psoc_nan_obj is null");
status = QDF_STATUS_E_NULL_VALUE;
goto free_resource;
}
if (confirm->rsp_code != NAN_DATAPATH_RESPONSE_ACCEPT &&
confirm->num_active_ndps_on_peer == 0) {
/*
* This peer was created at ndp_indication but
* confirm failed, so it needs to be deleted
*/
nan_err("NDP confirm with reject and no active ndp sessions. deleting peer: "QDF_MAC_ADDRESS_STR" on vdev_id: %d",
QDF_MAC_ADDR_ARRAY(confirm->peer_ndi_mac_addr.bytes),
vdev_id);
psoc_nan_obj->cb_obj.delete_peers_by_addr(vdev_id,
confirm->peer_ndi_mac_addr);
}
psoc_nan_obj->cb_obj.os_if_event_handler(psoc, confirm->vdev,
NDP_CONFIRM, confirm);
free_resource:
qdf_mem_free(confirm->ndp_info.ndp_app_info);
return status;
}
static QDF_STATUS nan_handle_initiator_rsp(
struct nan_datapath_initiator_rsp *rsp,
struct wlan_objmgr_vdev **vdev)
{
struct wlan_objmgr_psoc *psoc;
struct nan_psoc_priv_obj *psoc_nan_obj;
*vdev = rsp->vdev;
psoc = wlan_vdev_get_psoc(rsp->vdev);
if (!psoc) {
nan_err("psoc is null");
return QDF_STATUS_E_NULL_VALUE;
}
psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
if (!psoc_nan_obj) {
nan_err("psoc_nan_obj is null");
return QDF_STATUS_E_NULL_VALUE;
}
psoc_nan_obj->cb_obj.os_if_event_handler(psoc, rsp->vdev,
NDP_INITIATOR_RSP, rsp);
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS nan_handle_ndp_ind(
struct nan_datapath_indication_event *ndp_ind)
{
uint8_t vdev_id;
struct wlan_objmgr_psoc *psoc;
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct nan_psoc_priv_obj *psoc_nan_obj;
vdev_id = wlan_vdev_get_id(ndp_ind->vdev);
psoc = wlan_vdev_get_psoc(ndp_ind->vdev);
if (!psoc) {
nan_err("psoc is null");
status = QDF_STATUS_E_NULL_VALUE;
goto ndp_indication_failed;
}
psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
if (!psoc_nan_obj) {
nan_err("psoc_nan_obj is null");
status = QDF_STATUS_E_NULL_VALUE;
goto ndp_indication_failed;
}
nan_debug("role: %d, vdev: %d, csid: %d, peer_mac_addr "
QDF_MAC_ADDRESS_STR,
ndp_ind->role, vdev_id, ndp_ind->ncs_sk_type,
QDF_MAC_ADDR_ARRAY(ndp_ind->peer_mac_addr.bytes));
if ((ndp_ind->role == NAN_DATAPATH_ROLE_INITIATOR) ||
((NAN_DATAPATH_ROLE_RESPONDER == ndp_ind->role) &&
(NAN_DATAPATH_ACCEPT_POLICY_ALL == ndp_ind->policy))) {
status = psoc_nan_obj->cb_obj.add_ndi_peer(vdev_id,
ndp_ind->peer_mac_addr);
if (QDF_IS_STATUS_ERROR(status)) {
nan_err("Couldn't add ndi peer, ndp_role: %d",
ndp_ind->role);
goto ndp_indication_failed;
}
}
if (NAN_DATAPATH_ROLE_RESPONDER == ndp_ind->role)
psoc_nan_obj->cb_obj.os_if_event_handler(psoc, ndp_ind->vdev,
NDP_INDICATION, ndp_ind);
ndp_indication_failed:
qdf_mem_free(ndp_ind->ndp_config.ndp_cfg);
qdf_mem_free(ndp_ind->ndp_info.ndp_app_info);
qdf_mem_free(ndp_ind->scid.scid);
return status;
}
QDF_STATUS nan_event_handler(struct scheduler_msg *pe_msg)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct wlan_serialization_queued_cmd_info cmd;
cmd.requestor = WLAN_UMAC_COMP_NAN;
cmd.cmd_id = 0;
cmd.req_type = WLAN_SER_CANCEL_NON_SCAN_CMD;
cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE;
if (!pe_msg->bodyptr) {
nan_err("msg body is null");
return QDF_STATUS_E_NULL_VALUE;
}
switch (pe_msg->type) {
case NDP_CONFIRM: {
nan_handle_confirm(pe_msg->bodyptr);
break;
}
case NDP_INITIATOR_RSP: {
nan_handle_initiator_rsp(pe_msg->bodyptr, &cmd.vdev);
cmd.cmd_type = WLAN_SER_CMD_NDP_INIT_REQ;
wlan_serialization_remove_cmd(&cmd);
break;
}
case NDP_INDICATION: {
nan_handle_ndp_ind(pe_msg->bodyptr);
break;
}
default:
nan_alert("Unhandled NDP event: %d", pe_msg->type);
status = QDF_STATUS_E_NOSUPPORT;
break;
}
return status;
}

查看文件

@@ -124,4 +124,12 @@ void nan_release_cmd(void *in_req, uint32_t req_type);
*/
QDF_STATUS nan_scheduled_msg_handler(struct scheduler_msg *msg);
/*
* nan_event_handler: function to process events from firmware
* @msg: message received from lmac
*
* Return: status of operation
*/
QDF_STATUS nan_event_handler(struct scheduler_msg *msg);
#endif

查看文件

@@ -196,6 +196,20 @@ struct wlan_objmgr_vdev *ucfg_nan_get_ndi_vdev(struct wlan_objmgr_psoc *psoc,
QDF_STATUS ucfg_nan_req_processor(struct wlan_objmgr_vdev *vdev,
void *in_req, uint32_t req_type);
/**
* ucfg_nan_event_handler: ucfg API to be called from legacy code to
* post events to os_if/hdd layer
* @psoc: pointer to psoc object
* @vdev: pointer to vdev object
* @type: message type
* @msg: msg buffer
*
* Return: None
*/
void ucfg_nan_event_handler(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev,
uint32_t type, void *msg);
/**
* ucfg_nan_register_hdd_callbacks: ucfg API to set hdd callbacks
* @psoc: pointer to psoc object
@@ -211,6 +225,16 @@ int ucfg_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *,
uint32_t, void *));
/*
* ucfg_nan_register_lim_callbacks: ucfg API to set lim callbacks
* @psoc: pointer to psoc object
* @cb_obj: structs containing callbacks
*
* Return: status of operation
*/
int ucfg_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc,
struct nan_callbacks *cb_obj);
/**
* ucfg_nan_get_callbacks: ucfg API to return callbacks
* @psoc: pointer to psoc object

查看文件

@@ -322,9 +322,69 @@ struct wlan_objmgr_vdev *ucfg_nan_get_ndi_vdev(struct wlan_objmgr_psoc *psoc,
return psoc_obj->vdev;
}
static struct nan_datapath_initiator_req *ucfg_nan_copy_intiator_req(
struct wlan_objmgr_vdev *vdev,
struct nan_datapath_initiator_req *in_req)
{
struct nan_datapath_initiator_req *out_req;
out_req = qdf_mem_malloc(sizeof(*out_req));
if (!out_req) {
nan_alert("malloc failed");
return NULL;
}
qdf_mem_copy(out_req, in_req, sizeof(*out_req));
if (in_req->ndp_config.ndp_cfg_len) {
out_req->ndp_config.ndp_cfg =
qdf_mem_malloc(in_req->ndp_config.ndp_cfg_len);
if (!out_req->ndp_config.ndp_cfg) {
nan_alert("malloc failed");
goto free_resources;
}
qdf_mem_copy(out_req->ndp_config.ndp_cfg,
in_req->ndp_config.ndp_cfg,
in_req->ndp_config.ndp_cfg_len);
}
if (in_req->ndp_info.ndp_app_info_len) {
out_req->ndp_info.ndp_app_info =
qdf_mem_malloc(in_req->ndp_info.ndp_app_info_len);
if (!out_req->ndp_info.ndp_app_info) {
nan_alert("malloc failed");
goto free_resources;
}
qdf_mem_copy(out_req->ndp_info.ndp_app_info,
in_req->ndp_info.ndp_app_info,
in_req->ndp_info.ndp_app_info_len);
}
if (in_req->pmk.pmk_len) {
out_req->pmk.pmk = qdf_mem_malloc(in_req->pmk.pmk_len);
if (!out_req->pmk.pmk) {
nan_alert("malloc failed");
goto free_resources;
}
qdf_mem_copy(out_req->pmk.pmk, in_req->pmk.pmk,
in_req->pmk.pmk_len);
}
/* do not get ref here, rather take ref when request is activated */
out_req->vdev = vdev;
return out_req;
free_resources:
qdf_mem_free(out_req->pmk.pmk);
qdf_mem_free(out_req->ndp_info.ndp_app_info);
qdf_mem_free(out_req->ndp_config.ndp_cfg);
qdf_mem_free(out_req);
return NULL;
}
QDF_STATUS ucfg_nan_req_processor(struct wlan_objmgr_vdev *vdev,
void *in_req, uint32_t req_type)
{
void *req;
QDF_STATUS status;
struct scheduler_msg msg = {0};
@@ -333,8 +393,22 @@ QDF_STATUS ucfg_nan_req_processor(struct wlan_objmgr_vdev *vdev,
return QDF_STATUS_E_NULL_VALUE;
}
switch (req_type) {
case NDP_INITIATOR_REQ:
req = ucfg_nan_copy_intiator_req(vdev, in_req);
break;
default:
nan_err("in correct message req type: %d", req_type);
return QDF_STATUS_E_INVAL;
}
if (!req) {
nan_err("failed to create local copy");
return QDF_STATUS_E_INVAL;
}
msg.type = req_type;
msg.bodyptr = in_req;
msg.bodyptr = req;
msg.callback = nan_scheduled_msg_handler;
status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
if (QDF_IS_STATUS_ERROR(status)) {
@@ -345,6 +419,20 @@ QDF_STATUS ucfg_nan_req_processor(struct wlan_objmgr_vdev *vdev,
return status;
}
void ucfg_nan_event_handler(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev,
uint32_t type, void *msg)
{
struct nan_psoc_priv_obj *psoc_obj = nan_get_psoc_priv_obj(psoc);
if (!psoc_obj) {
nan_err("nan psoc priv object is NULL");
return;
}
psoc_obj->cb_obj.os_if_event_handler(psoc, vdev, type, msg);
}
int ucfg_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
struct nan_callbacks *cb_obj,
void (os_if_event_handler)(
@@ -370,5 +458,24 @@ int ucfg_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
psoc_obj->cb_obj.drv_ndi_delete_rsp_handler =
cb_obj->drv_ndi_delete_rsp_handler;
psoc_obj->cb_obj.get_peer_idx = cb_obj->get_peer_idx;
psoc_obj->cb_obj.new_peer_ind = cb_obj->new_peer_ind;
return 0;
}
int ucfg_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc,
struct nan_callbacks *cb_obj)
{
struct nan_psoc_priv_obj *psoc_obj = nan_get_psoc_priv_obj(psoc);
if (!psoc_obj) {
nan_err("nan psoc priv object is NULL");
return -EINVAL;
}
psoc_obj->cb_obj.add_ndi_peer = cb_obj->add_ndi_peer;
psoc_obj->cb_obj.delete_peers_by_addr = cb_obj->delete_peers_by_addr;
return 0;
}