Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a62f674 authored by Vinay Gannevaram's avatar Vinay Gannevaram Committed by nshrivas
Browse files

qcacmn: Add support for NLA type CAP_RESP in LOWI

Host driver processes cld80211 vendor sub command
CLD80211_VENDOR_SUB_CMD_GET_CAPS and respond with
NLA type CAP response

CRs-Fixed: 2595140
Change-Id: I5a6aa1fac537ca618404520b81c541a20dafd6fb
parent 53faf688
Loading
Loading
Loading
Loading
+70 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2017, 2020 The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
@@ -105,4 +105,73 @@ static inline int os_if_wifi_pos_populate_caps(struct wlan_objmgr_psoc *psoc,
}
#endif

#ifdef CNSS_GENL
/**
 * enum cld80211_vendor_sub_cmds
 * @CLD80211_VENDOR_SUB_CMD_INVALID: invalid cmd type
 * @CLD80211_VENDOR_SUB_CMD_REGISTRATION: app registration
 * @CLD80211_VENDOR_SUB_CMD_SET_CAPS: set driver capabilities
 * @CLD80211_VENDOR_SUB_CMD_GET_CAPS: get driver capabilities
 * @CLD80211_VENDOR_SUB_CMD_GET_CH_INFO: get channel info
 * @CLD80211_VENDOR_SUB_CMD_OEM_DATA: oem data req/rsp
 * @CLD80211_VENDOR_SUB_CMD_OEM_ERROR: oem error rsp
 * @CLD80211_VENDOR_SUB_CMD_PEER_STATUS_IND: peer status indication
 * @CLD80211_VENDOR_SUB_CMD_MAX: Max cld80211 vendor sub cmds
 */
enum cld80211_vendor_sub_cmds {
	CLD80211_VENDOR_SUB_CMD_INVALID = 0,
	CLD80211_VENDOR_SUB_CMD_REGISTRATION = 1,
	CLD80211_VENDOR_SUB_CMD_SET_CAPS = 2,
	CLD80211_VENDOR_SUB_CMD_GET_CAPS = 3,
	CLD80211_VENDOR_SUB_CMD_GET_CH_INFO = 4,
	CLD80211_VENDOR_SUB_CMD_OEM_DATA = 5,
	CLD80211_VENDOR_SUB_CMD_OEM_ERROR = 6,
	CLD80211_VENDOR_SUB_CMD_PEER_STATUS_IND = 7,
	/* keep last */
	CLD80211_VENDOR_SUB_CMD__AFTER_LAST,
	CLD80211_VENDOR_SUB_CMD_MAX =
		CLD80211_VENDOR_SUB_CMD__AFTER_LAST - 1
};

/**
 * enum cld80211_sub_attr_cap_rsp - Capability response sub attribute
 * @CLD80211_SUB_ATTR_CAPS_INVALID: Invalid capability
 * @CLD80211_SUB_ATTR_CAPS_OEM_TARGET_SIGNATURE: OEM target signature
 * @CLD80211_SUB_ATTR_CAPS_OEM_TARGET_TYPE: OEM target type
 * @CLD80211_SUB_ATTR_CAPS_OEM_FW_VERSION: OEM firmware version
 * @CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MAJOR: Driver version major
 * @CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MINOR: Driver version minor
 * @CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_PATCH: Driver version patch
 * @CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_BUILD: Driver version build
 * @CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MIN: Allowed dwell time min
 * @CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MAX: Allowed dwell time max
 * @CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MIN: Current dwell time min
 * @CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MAX: Current dwell time max
 * @CLD80211_SUB_ATTR_CAPS_SUPPORTED_BANDS: Supported bands
 * @CLD80211_SUB_ATTR_CAPS_USER_DEFINED_CAPS: User defined capabilities
 * @CLD80211_SUB_ATTR_CAPS_MAX: Max number for CAP sub attribute
 *
 */
enum cld80211_sub_attr_cap_rsp {
	CLD80211_SUB_ATTR_CAPS_INVALID = 0,
	CLD80211_SUB_ATTR_CAPS_OEM_TARGET_SIGNATURE = 1,
	CLD80211_SUB_ATTR_CAPS_OEM_TARGET_TYPE = 2,
	CLD80211_SUB_ATTR_CAPS_OEM_FW_VERSION = 3,
	CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MAJOR = 4,
	CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MINOR = 5,
	CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_PATCH = 6,
	CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_BUILD = 7,
	CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MIN = 8,
	CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MAX = 9,
	CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MIN = 10,
	CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MAX = 11,
	CLD80211_SUB_ATTR_CAPS_SUPPORTED_BANDS = 12,
	CLD80211_SUB_ATTR_CAPS_USER_DEFINED_CAPS = 13,

	/* keep last */
	CLD80211_SUB_ATTR_CAPS_AFTER_LAST,
	CLD80211_SUB_ATTR_CAPS_MAX =
		CLD80211_SUB_ATTR_CAPS_AFTER_LAST - 1
};
#endif
#endif /* _OS_IF_WIFI_POS_H_ */
+294 −36
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
@@ -33,6 +33,206 @@
#include "wlan_objmgr_psoc_obj.h"
#ifdef CNSS_GENL
#include <net/cnss_nl.h>
#include "linux/genetlink.h"
#include "wifi_pos_utils_pub.h"
#endif

#ifdef CNSS_GENL
#define WLAN_CLD80211_MAX_SIZE SKB_WITH_OVERHEAD(8192UL)

#define CLD80211_ATTR_CMD 4
#define CLD80211_ATTR_CMD_TAG_DATA 5
#define CLD80211_ATTR_MAX 5

static const uint32_t
cap_resp_sub_attr_len[CLD80211_SUB_ATTR_CAPS_MAX + 1] = {
	[CLD80211_SUB_ATTR_CAPS_OEM_TARGET_SIGNATURE] =
				OEM_TARGET_SIGNATURE_LEN,
	[CLD80211_SUB_ATTR_CAPS_OEM_TARGET_TYPE] = sizeof(uint32_t),
	[CLD80211_SUB_ATTR_CAPS_OEM_FW_VERSION] = sizeof(uint32_t),
	[CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MAJOR] = sizeof(uint8_t),
	[CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MINOR] = sizeof(uint8_t),
	[CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_PATCH] = sizeof(uint8_t),
	[CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_BUILD] = sizeof(uint8_t),
	[CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MIN] = sizeof(uint16_t),
	[CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MAX] = sizeof(uint16_t),
	[CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MIN] = sizeof(uint16_t),
	[CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MAX] = sizeof(uint16_t),
	[CLD80211_SUB_ATTR_CAPS_SUPPORTED_BANDS] = sizeof(uint16_t),
	[CLD80211_SUB_ATTR_CAPS_USER_DEFINED_CAPS] =
				sizeof(struct wifi_pos_user_defined_caps),
};
#endif

static int map_wifi_pos_cmd_to_ani_msg_rsp(
		enum wifi_pos_cmd_ids cmd)
{
	switch (cmd) {
	case WIFI_POS_CMD_REGISTRATION:
		return ANI_MSG_APP_REG_RSP;
	case WIFI_POS_CMD_SET_CAPS:
		return ANI_MSG_SET_OEM_CAP_RSP;
	case WIFI_POS_CMD_GET_CAPS:
		return ANI_MSG_GET_OEM_CAP_RSP;
	case WIFI_POS_CMD_GET_CH_INFO:
		return ANI_MSG_CHANNEL_INFO_RSP;
	case WIFI_POS_CMD_OEM_DATA:
		return ANI_MSG_OEM_DATA_RSP;
	case WIFI_POS_CMD_ERROR:
		return ANI_MSG_OEM_ERROR;
	case WIFI_POS_PEER_STATUS_IND:
		return ANI_MSG_PEER_STATUS_IND;
	default:
		osif_err("response message is invalid :%d", cmd);
		return -EINVAL;
	}
}

static enum wifi_pos_cmd_ids
map_ani_msg_req_to_wifi_pos_cmd(uint32_t cmd)
{
	switch (cmd) {
	case ANI_MSG_APP_REG_REQ:
		return WIFI_POS_CMD_REGISTRATION;
	case ANI_MSG_SET_OEM_CAP_REQ:
		return WIFI_POS_CMD_SET_CAPS;
	case ANI_MSG_GET_OEM_CAP_REQ:
		return WIFI_POS_CMD_GET_CAPS;
	case ANI_MSG_CHANNEL_INFO_REQ:
		return WIFI_POS_CMD_GET_CH_INFO;
	case ANI_MSG_OEM_DATA_REQ:
		return WIFI_POS_CMD_OEM_DATA;
	default:
		osif_err("ani req is invalid :%d", cmd);
		return WIFI_POS_CMD_INVALID;
	}
}

#ifdef CNSS_GENL
static enum wifi_pos_cmd_ids
map_cld_vendor_sub_cmd_to_wifi_pos_cmd(
		enum cld80211_vendor_sub_cmds cmd)
{
	switch (cmd) {
	case CLD80211_VENDOR_SUB_CMD_REGISTRATION:
		return WIFI_POS_CMD_REGISTRATION;
	case CLD80211_VENDOR_SUB_CMD_SET_CAPS:
		return WIFI_POS_CMD_SET_CAPS;
	case CLD80211_VENDOR_SUB_CMD_GET_CAPS:
		return WIFI_POS_CMD_GET_CAPS;
	case CLD80211_VENDOR_SUB_CMD_GET_CH_INFO:
		return WIFI_POS_CMD_GET_CH_INFO;
	case CLD80211_VENDOR_SUB_CMD_OEM_DATA:
		return WIFI_POS_CMD_OEM_DATA;
	default:
		osif_err("cld vendor subcmd is invalid :%d", cmd);
		return WIFI_POS_CMD_INVALID;
	}
}

static enum cld80211_vendor_sub_cmds
map_wifi_pos_cmd_to_cld_vendor_sub_cmd(
		enum wifi_pos_cmd_ids cmd)
{
	switch (cmd) {
	case WIFI_POS_CMD_REGISTRATION:
		return CLD80211_VENDOR_SUB_CMD_REGISTRATION;
	case WIFI_POS_CMD_SET_CAPS:
		return CLD80211_VENDOR_SUB_CMD_SET_CAPS;
	case WIFI_POS_CMD_GET_CAPS:
		return CLD80211_VENDOR_SUB_CMD_GET_CAPS;
	case WIFI_POS_CMD_GET_CH_INFO:
		return CLD80211_VENDOR_SUB_CMD_GET_CH_INFO;
	case WIFI_POS_CMD_OEM_DATA:
		return CLD80211_VENDOR_SUB_CMD_OEM_DATA;
	case WIFI_POS_CMD_ERROR:
		return ANI_MSG_OEM_ERROR;
	case WIFI_POS_PEER_STATUS_IND:
		return ANI_MSG_PEER_STATUS_IND;
	default:
		osif_err("response message is invalid :%d", cmd);
		return CLD80211_VENDOR_SUB_CMD_INVALID;
	}
}

static void os_if_send_cap_nl_resp(uint32_t pid, uint8_t *buf)
{
	void *hdr;
	int flags = GFP_KERNEL;
	struct sk_buff *msg = NULL;
	struct nlattr *nest1, *nest2;
	struct wifi_pos_oem_get_cap_rsp *cap_rsp;

	msg = cld80211_oem_rsp_alloc_skb(pid, &hdr, &nest1, &flags);
	if (!msg) {
		osif_err("alloc_skb failed");
		return;
	}

	nla_put_u32(msg, CLD80211_ATTR_CMD,
	map_wifi_pos_cmd_to_cld_vendor_sub_cmd(WIFI_POS_CMD_GET_CAPS));

	cap_rsp = (struct wifi_pos_oem_get_cap_rsp *)(buf);
	nest2 = nla_nest_start(msg, CLD80211_ATTR_CMD_TAG_DATA);

	if (!nest2) {
		osif_err("nla_nest_start failed");
		dev_kfree_skb(msg);
		return;
	}

	nla_put(msg, CLD80211_SUB_ATTR_CAPS_OEM_TARGET_SIGNATURE,
		OEM_TARGET_SIGNATURE_LEN, OEM_TARGET_SIGNATURE);
	nla_put_u32(msg, CLD80211_SUB_ATTR_CAPS_OEM_TARGET_TYPE,
		    cap_rsp->driver_cap.oem_target_type);
	nla_put_u32(msg, CLD80211_SUB_ATTR_CAPS_OEM_FW_VERSION,
		    cap_rsp->driver_cap.oem_fw_version);
	nla_put_u8(msg, CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MAJOR,
		   cap_rsp->driver_cap.driver_version.major);
	nla_put_u8(msg, CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MINOR,
		   cap_rsp->driver_cap.driver_version.minor);
	nla_put_u8(msg, CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_PATCH,
		   cap_rsp->driver_cap.driver_version.patch);
	nla_put_u8(msg, CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_BUILD,
		   cap_rsp->driver_cap.driver_version.build);
	nla_put_u16(msg, CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MIN,
		    cap_rsp->driver_cap.allowed_dwell_time_min);
	nla_put_u16(msg, CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MAX,
		    cap_rsp->driver_cap.allowed_dwell_time_max);
	nla_put_u16(msg, CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MIN,
		    cap_rsp->driver_cap.curr_dwell_time_min);
	nla_put_u16(msg, CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MAX,
		    cap_rsp->driver_cap.curr_dwell_time_max);
	nla_put_u16(msg, CLD80211_SUB_ATTR_CAPS_SUPPORTED_BANDS,
		    cap_rsp->driver_cap.supported_bands);
	nla_put(msg, CLD80211_SUB_ATTR_CAPS_USER_DEFINED_CAPS,
		sizeof(struct wifi_pos_user_defined_caps),
		&cap_rsp->user_defined_cap);
	nla_nest_end(msg, nest2);

	osif_debug("sending oem rsp: type: %d to pid (%d)",
		    CLD80211_VENDOR_SUB_CMD_GET_CAPS, pid);

	cld80211_oem_send_reply(msg, hdr, nest1, flags);
}


static void os_if_send_nl_resp(uint32_t pid, uint8_t *buf,
			       enum wifi_pos_cmd_ids cmd)
{
	switch (cmd) {
	case WIFI_POS_CMD_GET_CAPS:
		os_if_send_cap_nl_resp(pid, buf);
		break;
	default:
		osif_err("response message is invalid :%d", cmd);
	}
}
#else
static void os_if_send_nl_resp(uint32_t pid, uint8_t *buf,
			       enum wifi_pos_cmd_ids cmd)
{
}
#endif

/**
@@ -42,12 +242,13 @@
 *
 * Return:  none
 */
static void os_if_wifi_pos_send_rsp(uint32_t pid, uint32_t rsp_msg_type,
static void os_if_wifi_pos_send_rsp(uint32_t pid, enum wifi_pos_cmd_ids cmd,
				    uint32_t buf_len, uint8_t *buf)
{
	tAniMsgHdr *aniHdr;
	struct sk_buff *skb;
	struct sk_buff *skb = NULL;
	struct nlmsghdr *nlh;
	struct wlan_objmgr_psoc *psoc = wifi_pos_get_psoc();

	/* OEM msg is always to a specific process and cannot be a broadcast */
	if (pid == 0) {
@@ -55,7 +256,11 @@ static void os_if_wifi_pos_send_rsp(uint32_t pid, uint32_t rsp_msg_type,
		return;
	}

	skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + buf_len), GFP_ATOMIC);
	if (ucfg_wifi_pos_is_nl_rsp(psoc)) {
		os_if_send_nl_resp(pid, buf, cmd);
	} else {
		skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + buf_len),
				GFP_ATOMIC);
		if (!skb) {
			osif_alert("alloc_skb failed");
			return;
@@ -69,32 +274,58 @@ static void os_if_wifi_pos_send_rsp(uint32_t pid, uint32_t rsp_msg_type,
		nlh->nlmsg_len = NLMSG_LENGTH(sizeof(tAniMsgHdr) + buf_len);

		aniHdr = NLMSG_DATA(nlh);
	aniHdr->type = rsp_msg_type;
		aniHdr->type = map_wifi_pos_cmd_to_ani_msg_rsp(cmd);
		qdf_mem_copy(&aniHdr[1], buf, buf_len);
		aniHdr->length = buf_len;

		skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + buf_len));
		osif_debug("sending oem rsp: type: %d len(%d) to pid (%d)",
		   rsp_msg_type, buf_len, pid);
			   aniHdr->type, buf_len, pid);
		nl_srv_ucast_oem(skb, pid, MSG_DONTWAIT);
	}
}

#ifdef CNSS_GENL
static int  wifi_pos_parse_req(const void *data, int len, int pid,

static int  wifi_pos_parse_nla_req(const void *data, int len, int pid,
		    struct wifi_pos_req_msg *req)
{
	tAniMsgHdr *msg_hdr;
	uint8_t *msg;
	struct nlattr *tb[CLD80211_ATTR_MAX + 1];
	uint32_t msg_len, id, nl_field_info_size, expected_field_info_size;
	struct wifi_pos_field_info *field_info;
	uint32_t msg_len;

	if (wlan_cfg80211_nla_parse(tb, CLD80211_ATTR_MAX, data, len, NULL)) {
		osif_err("invalid data in request");
		return OEM_ERR_INVALID_MESSAGE_TYPE;
	}

	if (!tb[CLD80211_ATTR_DATA]) {
		osif_err("CLD80211_ATTR_DATA not present");
	req->pid = pid;
	req->msg_type = map_cld_vendor_sub_cmd_to_wifi_pos_cmd(
				nla_get_u32(tb[CLD80211_ATTR_CMD]));
	req->rsp_version = WIFI_POS_RSP_V2_NL;

	if (tb[CLD80211_ATTR_CMD_TAG_DATA]) {
		msg_len = nla_len(tb[CLD80211_ATTR_CMD_TAG_DATA]);
		msg = nla_data(tb[CLD80211_ATTR_CMD_TAG_DATA]);
		req->buf_len = msg_len;
		req->buf = msg;
	}
	if (tb[CLD80211_ATTR_META_DATA])
		osif_err("meta data dropped. Apps can use CLD80211_ATTR_CMD_TAG_DATA sub attrs");

	return 0;
}

static int  wifi_pos_parse_ani_req(const void *data, int len, int pid,
		    struct wifi_pos_req_msg *req)
{
	tAniMsgHdr *msg_hdr;
	struct nlattr *tb[CLD80211_ATTR_MAX + 1];
	uint32_t msg_len, id, nl_field_info_size, expected_field_info_size;
	struct wifi_pos_field_info *field_info;

	if (wlan_cfg80211_nla_parse(tb, CLD80211_ATTR_MAX, data, len, NULL)) {
		osif_err("invalid data in request");
		return OEM_ERR_INVALID_MESSAGE_TYPE;
	}

@@ -105,7 +336,9 @@ static int wifi_pos_parse_req(const void *data, int len, int pid,
	}

	msg_hdr = nla_data(tb[CLD80211_ATTR_DATA]);
	req->msg_type = msg_hdr->type;
	req->msg_type = map_ani_msg_req_to_wifi_pos_cmd(
				(uint32_t)msg_hdr->type);
	req->rsp_version = WIFI_POS_RSP_V1_FLAT_MEMORY;

	if (msg_len < sizeof(*msg_hdr) + msg_hdr->length) {
		osif_err("Insufficient length for msg_hdr buffer: %u",
@@ -148,6 +381,29 @@ static int wifi_pos_parse_req(const void *data, int len, int pid,

	return 0;
}


static int  wifi_pos_parse_req(const void *data, int len, int pid,
		    struct wifi_pos_req_msg *req)
{
	int status = 0;
	struct nlattr *tb[CLD80211_ATTR_MAX + 1];

	if (wlan_cfg80211_nla_parse(tb, CLD80211_ATTR_MAX, data, len, NULL)) {
		osif_err("invalid data in request");
		return OEM_ERR_INVALID_MESSAGE_TYPE;
	}

	if (tb[CLD80211_ATTR_DATA]) {
		status = wifi_pos_parse_ani_req(data, len, pid, req);
	} else if (tb[CLD80211_ATTR_CMD]) {
		status = wifi_pos_parse_nla_req(data, len, pid, req);
	} else {
		osif_err("Valid CLD80211 ATTR not present");
		return OEM_ERR_INVALID_MESSAGE_TYPE;
	}
	return status;
}
#else
static int wifi_pos_parse_req(struct sk_buff *skb, struct wifi_pos_req_msg *req)
{
@@ -181,7 +437,9 @@ static int wifi_pos_parse_req(struct sk_buff *skb, struct wifi_pos_req_msg *req)
		return OEM_ERR_INVALID_MESSAGE_LENGTH;
	}

	req->msg_type = msg_hdr->type;
	req->msg_type = map_ani_msg_req_to_wifi_pos_cmd(
				(uint32_t)msg_hdr->type);
	req->rsp_version = WIFI_POS_RSP_V1_FLAT_MEMORY;
	req->buf_len = msg_hdr->length;
	req->buf = (uint8_t *)&msg_hdr[1];
	req->pid = nlh->nlmsg_pid;
@@ -225,7 +483,7 @@ static void __os_if_wifi_pos_callback(const void *data, int data_len,
	err = wifi_pos_parse_req(data, data_len, pid, &req);
	if (err) {
		os_if_wifi_pos_send_rsp(wifi_pos_get_app_pid(psoc),
					ANI_MSG_OEM_ERROR, sizeof(err), &err);
					WIFI_POS_CMD_ERROR, sizeof(err), &err);
		status = QDF_STATUS_E_INVAL;
		goto release_psoc_ref;
	}
@@ -268,7 +526,7 @@ static int __os_if_wifi_pos_callback(struct sk_buff *skb)
	err = wifi_pos_parse_req(skb, &req);
	if (err) {
		os_if_wifi_pos_send_rsp(wifi_pos_get_app_pid(psoc),
					ANI_MSG_OEM_ERROR, sizeof(err), &err);
					WIFI_POS_CMD_ERROR, sizeof(err), &err);
		status = QDF_STATUS_E_INVAL;
		goto release_psoc_ref;
	}
@@ -341,7 +599,7 @@ void os_if_wifi_pos_send_peer_status(struct qdf_mac_addr *peer_mac,
				enum QDF_OPMODE dev_mode)
{
	struct wlan_objmgr_psoc *psoc = wifi_pos_get_psoc();
	struct wmi_pos_peer_status_info *peer_info;
	struct wifi_pos_peer_status_info *peer_info;

	if (!psoc) {
		osif_err("global wifi_pos psoc object not registered");
@@ -382,7 +640,7 @@ void os_if_wifi_pos_send_peer_status(struct qdf_mac_addr *peer_mac,
	}

	os_if_wifi_pos_send_rsp(wifi_pos_get_app_pid(psoc),
				ANI_MSG_PEER_STATUS_IND,
				WIFI_POS_PEER_STATUS_IND,
				sizeof(*peer_info), (uint8_t *)peer_info);
	qdf_mem_free(peer_info);
}
+3 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
@@ -22,6 +22,8 @@
 * target if layer.
 */
#include "../../../../umac/wifi_pos/src/wifi_pos_utils_i.h"
#include "wifi_pos_utils_pub.h"

#include "wmi_unified_api.h"
#include "wlan_lmac_if_def.h"
#include "target_if_wifi_pos.h"
+14 −6
Original line number Diff line number Diff line
@@ -24,9 +24,7 @@
#define _WIFI_POS_API_H_

/* Include files */
#include "qdf_types.h"
#include "qdf_status.h"
#include "qdf_trace.h"
#include "wifi_pos_utils_pub.h"

/* forward reference */
struct wlan_objmgr_psoc;
@@ -113,7 +111,7 @@ struct qdf_packed wifi_pos_ch_info_rsp {
};

/**
 * struct wmi_pos_peer_status_info - Status information for a given peer
 * struct wifi_pos_peer_status_info - Status information for a given peer
 * @peer_mac_addr: peer mac address
 * @peer_status: peer status: 1: CONNECTED, 2: DISCONNECTED
 * @vdev_id: vdev_id for the peer mac
@@ -121,7 +119,7 @@ struct qdf_packed wifi_pos_ch_info_rsp {
 * @reserved0: reserved0
 * @peer_chan_info: channel info on which peer is connected
 */
struct qdf_packed wmi_pos_peer_status_info {
struct qdf_packed wifi_pos_peer_status_info {
	uint8_t peer_mac_addr[ETH_ALEN];
	uint8_t peer_status;
	uint8_t vdev_id;
@@ -138,15 +136,17 @@ struct qdf_packed wmi_pos_peer_status_info {
 * @buf_len: request buffer length
 * @field_info_buf: buffer containing field info
 * @field_info_buf_len: length of field info buffer
 * @rsp_version: nl type or ani type
 *
 */
struct wifi_pos_req_msg {
	uint32_t msg_type;
	enum wifi_pos_cmd_ids msg_type;
	uint32_t pid;
	uint8_t *buf;
	uint32_t buf_len;
	struct wifi_pos_field_info *field_info_buf;
	uint32_t field_info_buf_len;
	uint32_t rsp_version;
};

/**
@@ -340,6 +340,14 @@ void ucfg_wifi_pos_set_ftm_cap(struct wlan_objmgr_psoc *psoc, uint32_t val);
void ucfg_wifi_pos_set_oem_6g_supported(struct wlan_objmgr_psoc *psoc,
					bool val);

/**
 * ucfg_wifi_pos_is_nl_rsp: API to check if response is nl or ani type
 * @psoc: psoc object
 *
 * Return: true if response is nl type
 */
bool ucfg_wifi_pos_is_nl_rsp(struct wlan_objmgr_psoc *psoc);

/**
 * wifi_pos_get_app_pid: returns oem app pid.
 * @psoc: pointer to psoc object
+129 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/**
 * DOC: wifi_pos_utils_pub.h
 * This file declares public utils of wifi positioning component
 */
#ifndef _WIFI_POS_UTILS_PUB_H_
#define _WIFI_POS_UTILS_PUB_H_

/* Include files */
#include "qdf_types.h"
#include "qdf_status.h"
#include "qdf_trace.h"

#define WIFIPOS_RESERVE_BYTES      100
#define OEM_TARGET_SIGNATURE_LEN   8
#define OEM_TARGET_SIGNATURE       "QUALCOMM"

#define OEM_CAP_MAX_NUM_CHANNELS   128

#define WIFI_POS_RSP_V1_FLAT_MEMORY  0x00000001
#define WIFI_POS_RSP_V2_NL  0x00000002

/**
 * enum wifi_pos_cmd_ids
 * @WIFI_POS_CMD_REGISTRATION: app registration
 * @WIFI_POS_CMD_GET_CAPS: get driver capabilities
 * @WIFI_POS_CMD_GET_CH_INFO: get channel info
 * @WIFI_POS_CMD_OEM_DATA: oem data req/rsp
 * @WIFI_POS_CMD_MAX: Max cld80211 vendor sub cmds
 */

enum wifi_pos_cmd_ids {
	WIFI_POS_CMD_INVALID = 0,
	WIFI_POS_CMD_REGISTRATION = 1,
	WIFI_POS_CMD_SET_CAPS = 2,
	WIFI_POS_CMD_GET_CAPS = 3,
	WIFI_POS_CMD_GET_CH_INFO = 4,
	WIFI_POS_CMD_OEM_DATA = 5,
	WIFI_POS_CMD_ERROR = 6,
	WIFI_POS_PEER_STATUS_IND = 7,
	/* keep last */
	WIFI_POS_CMD__AFTER_LAST,
	WIFI_POS_CMD_MAX =
		WIFI_POS_CMD__AFTER_LAST - 1
};


/**
 * struct wifi_pos_driver_version - Driver version identifier (w.x.y.z)
 * @major: Version ID major number
 * @minor: Version ID minor number
 * @patch: Version ID patch number
 * @build: Version ID build number
 */
struct qdf_packed wifi_pos_driver_version {
	uint8_t major;
	uint8_t minor;
	uint8_t patch;
	uint8_t build;
};

/**
 * struct wifi_pos_driver_caps - OEM Data Capabilities
 * @oem_target_signature: Signature of chipset vendor
 * @oem_target_type: Chip type
 * @oem_fw_version: Firmware version
 * @driver_version: Host software version
 * @allowed_dwell_time_min: Channel dwell time - allowed minimum
 * @allowed_dwell_time_max: Channel dwell time - allowed maximum
 * @curr_dwell_time_min: Channel dwell time - current minimim
 * @curr_dwell_time_max: Channel dwell time - current maximum
 * @supported_bands: Supported bands, 2.4G or 5G Hz
 * @num_channels: Num of channels IDs to follow
 * @channel_list: List of channel IDs
 */
struct qdf_packed wifi_pos_driver_caps {
	uint8_t oem_target_signature[OEM_TARGET_SIGNATURE_LEN];
	uint32_t oem_target_type;
	uint32_t oem_fw_version;
	struct wifi_pos_driver_version driver_version;
	uint16_t allowed_dwell_time_min;
	uint16_t allowed_dwell_time_max;
	uint16_t curr_dwell_time_min;
	uint16_t curr_dwell_time_max;
	uint16_t supported_bands;
	uint16_t num_channels;
	uint8_t channel_list[OEM_CAP_MAX_NUM_CHANNELS];
};

/**
 * struct wifi_pos_user_defined_caps - OEM capability to be exchanged between
 * host and userspace
 * @ftm_rr: FTM range report capability bit
 * @lci_capability: LCI capability bit
 * @reserved1: reserved
 * @reserved2: reserved
 */
struct wifi_pos_user_defined_caps {
	uint32_t ftm_rr:1;
	uint32_t lci_capability:1;
	uint32_t reserved1:30;
	uint32_t reserved2;
};

/**
 * struct wifi_pos_oem_get_cap_rsp - capabilities set by userspace and target.
 * @driver_cap: target capabilities
 * @user_defined_cap: capabilities set by userspace via set request
 */
struct qdf_packed wifi_pos_oem_get_cap_rsp {
	struct wifi_pos_driver_caps driver_cap;
	struct wifi_pos_user_defined_caps user_defined_cap;
};
#endif
Loading