123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- /*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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: Implement API's specific to CoAP component.
- */
- #include <wmi_unified_priv.h>
- #include "wmi.h"
- #include "ol_defines.h"
- /*
- * send_coap_add_pattern_cmd_tlv() - Send wmi cmd for adding CoAP pattern
- * @wmi_handle: wmi handle
- * @param: parameter for CoAP add pattern
- *
- * Return: QDF_STATUS
- */
- static QDF_STATUS
- send_coap_add_pattern_cmd_tlv(wmi_unified_t wmi_handle,
- struct coap_offload_reply_param *param)
- {
- WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param *cmd;
- wmi_buf_t buf;
- QDF_STATUS status;
- uint8_t *buf_ptr;
- uint32_t len, coapmsg_len_align, verify_len_align;
- wmi_debug("vdev id %d pattern id %d timeout %d src ip 0x%x:%d coap msg len %d",
- param->vdev_id, param->pattern_id, param->cache_timeout,
- param->src_ip_v4, param->src_udp_port,
- param->coapmsg_len);
- wmi_debug("filter: dest ip 0x%x:%d is bc %d verify offset %d len %d",
- param->dest_ip_v4, param->dest_udp_port,
- param->dest_ip_v4_is_bc, param->verify_offset,
- param->verify_len);
- if (!param->verify || !param->verify_len ||
- !param->coapmsg || !param->coapmsg_len) {
- wmi_err("invalid param");
- return QDF_STATUS_E_INVAL;
- }
- coapmsg_len_align = qdf_align(param->coapmsg_len, 4);
- verify_len_align = qdf_align(param->verify_len, 4);
- len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + coapmsg_len_align +
- WMI_TLV_HDR_SIZE + verify_len_align;
- buf = wmi_buf_alloc(wmi_handle, len);
- if (!buf)
- return QDF_STATUS_E_NOMEM;
- buf_ptr = wmi_buf_data(buf);
- cmd = (WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param *)buf_ptr;
- WMITLV_SET_HDR(&cmd->tlv_header,
- WMITLV_TAG_STRUC_WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param,
- WMITLV_GET_STRUCT_TLVLEN(
- WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param));
- cmd->vdev_id = param->vdev_id;
- cmd->pattern_id = param->pattern_id;
- cmd->timeout = param->cache_timeout;
- WMI_COAP_IPV6_SET(cmd->pattern_type, 0);
- WMI_COAP_ADDR_TYPE_SET(cmd->pattern_type,
- param->dest_ip_v4_is_bc ? 1 : 0);
- qdf_mem_copy(cmd->match_udp_ip.ipv4_addr, ¶m->dest_ip_v4,
- sizeof(param->dest_ip_v4));
- cmd->match_udp_port = param->dest_udp_port;
- qdf_mem_copy(cmd->udp_local_ip.ipv4_addr, ¶m->src_ip_v4,
- sizeof(param->src_ip_v4));
- cmd->udp_local_port = param->src_udp_port;
- cmd->verify_offset = param->verify_offset;
- cmd->verify_len = param->verify_len;
- cmd->coapmsg_len = param->coapmsg_len;
- buf_ptr += sizeof(*cmd);
- WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, verify_len_align);
- buf_ptr += WMI_TLV_HDR_SIZE;
- qdf_mem_copy(buf_ptr, param->verify, param->verify_len);
- buf_ptr += verify_len_align;
- WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, coapmsg_len_align);
- buf_ptr += WMI_TLV_HDR_SIZE;
- qdf_mem_copy(buf_ptr, param->coapmsg, param->coapmsg_len);
- buf_ptr += coapmsg_len_align;
- wmi_mtrace(WMI_WOW_COAP_ADD_PATTERN_CMDID,
- cmd->vdev_id, cmd->pattern_id);
- status = wmi_unified_cmd_send(wmi_handle, buf, len,
- WMI_WOW_COAP_ADD_PATTERN_CMDID);
- if (status != QDF_STATUS_SUCCESS) {
- wmi_err("Failed to send wow coap add pattern command %d",
- status);
- wmi_buf_free(buf);
- }
- return status;
- }
- /*
- * send_coap_del_pattern_cmd_tlv() - Send wmi cmd for deleting CoAP pattern
- * @wmi_handle: wmi handle
- * @vdev_id: vdev id
- * @pattern_id: pattern id
- *
- * Return: QDF_STATUS
- */
- static QDF_STATUS
- send_coap_del_pattern_cmd_tlv(wmi_unified_t wmi_handle,
- uint8_t vdev_id, uint32_t pattern_id)
- {
- WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param *cmd;
- wmi_buf_t buf;
- QDF_STATUS status;
- uint32_t len = sizeof(*cmd);
- wmi_debug("vdev id %d pattern id %d", vdev_id, pattern_id);
- buf = wmi_buf_alloc(wmi_handle, len);
- if (!buf)
- return QDF_STATUS_E_NOMEM;
- cmd = (WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param *)wmi_buf_data(buf);
- WMITLV_SET_HDR(&cmd->tlv_header,
- WMITLV_TAG_STRUC_WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param,
- WMITLV_GET_STRUCT_TLVLEN(
- WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param));
- cmd->vdev_id = vdev_id;
- cmd->pattern_id = pattern_id;
- wmi_mtrace(WMI_WOW_COAP_DEL_PATTERN_CMDID,
- cmd->vdev_id, cmd->pattern_id);
- status = wmi_unified_cmd_send(wmi_handle, buf, len,
- WMI_WOW_COAP_DEL_PATTERN_CMDID);
- if (status != QDF_STATUS_SUCCESS) {
- wmi_err("Failed to send wow coap del pattern command %d",
- status);
- wmi_buf_free(buf);
- }
- return status;
- }
- /*
- * send_coap_add_pattern_cmd_tlv() - Send wmi cmd for adding CoAP keepalive
- * pattern
- * @wmi_handle: wmi handle
- * @param: parameter for CoAP add pattern
- *
- * Return: QDF_STATUS
- */
- static QDF_STATUS
- send_coap_add_keepalive_pattern_cmd_tlv(wmi_unified_t wmi_handle,
- struct coap_offload_periodic_tx_param *param)
- {
- WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param *cmd;
- wmi_buf_t buf;
- QDF_STATUS status;
- uint8_t *buf_ptr;
- uint32_t len, coapmsg_len_align;
- wmi_debug("vdev id %d pattern id %d ip src 0x%x:%d dest 0x%x:%d bc %d timeout %d",
- param->vdev_id, param->pattern_id, param->src_ip_v4,
- param->src_udp_port, param->dest_ip_v4,
- param->dest_udp_port, param->dest_ip_v4_is_bc,
- param->timeout);
- if (!param->coapmsg || !param->coapmsg_len) {
- wmi_err("invalid CoAP message");
- return QDF_STATUS_E_INVAL;
- }
- coapmsg_len_align = qdf_align(param->coapmsg_len, 4);
- len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + coapmsg_len_align;
- buf = wmi_buf_alloc(wmi_handle, len);
- if (!buf)
- return QDF_STATUS_E_NOMEM;
- buf_ptr = wmi_buf_data(buf);
- cmd = (WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param *)buf_ptr;
- WMITLV_SET_HDR(&cmd->tlv_header,
- WMITLV_TAG_STRUC_WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param,
- WMITLV_GET_STRUCT_TLVLEN(
- WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param));
- cmd->vdev_id = param->vdev_id;
- cmd->pattern_id = param->pattern_id;
- /* only support IPv4 in current stage */
- WMI_COAP_IPV6_SET(cmd->pattern_type, 0);
- WMI_COAP_ADDR_TYPE_SET(cmd->pattern_type,
- param->dest_ip_v4_is_bc ? 1 : 0);
- qdf_mem_copy(cmd->udp_remote_ip.ipv4_addr, ¶m->dest_ip_v4,
- sizeof(param->dest_ip_v4));
- cmd->udp_remote_port = param->dest_udp_port;
- qdf_mem_copy(cmd->udp_local_ip.ipv4_addr, ¶m->src_ip_v4,
- sizeof(param->src_ip_v4));
- cmd->udp_local_port = param->src_udp_port;
- cmd->timeout = param->timeout;
- cmd->coapmsg_len = param->coapmsg_len;
- buf_ptr += sizeof(*cmd);
- WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, coapmsg_len_align);
- buf_ptr += WMI_TLV_HDR_SIZE;
- qdf_mem_copy(buf_ptr, param->coapmsg, param->coapmsg_len);
- buf_ptr += coapmsg_len_align;
- wmi_mtrace(WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMDID,
- cmd->vdev_id, cmd->pattern_id);
- status = wmi_unified_cmd_send(wmi_handle, buf, len,
- WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMDID);
- if (status != QDF_STATUS_SUCCESS) {
- wmi_err("Failed to send wow coap add keepalive pattern command %d",
- status);
- wmi_buf_free(buf);
- }
- return status;
- }
- /*
- * send_coap_del_pattern_cmd_tlv() - Send wmi cmd for deleting CoAP
- * keepalive pattern
- * @wmi_handle: wmi handle
- * @vdev_id: vdev id
- * @pattern_id: pattern id
- *
- * Return: QDF_STATUS
- */
- static QDF_STATUS
- send_coap_del_keepalive_pattern_cmd_tlv(wmi_unified_t wmi_handle,
- uint8_t vdev_id, uint32_t pattern_id)
- {
- WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMD_fixed_param *cmd;
- wmi_buf_t buf;
- QDF_STATUS status;
- uint8_t *buf_ptr;
- uint32_t len = sizeof(*cmd);
- wmi_debug("vdev id %d pattern id %d", vdev_id, pattern_id);
- buf = wmi_buf_alloc(wmi_handle, len);
- if (!buf)
- return QDF_STATUS_E_NOMEM;
- buf_ptr = wmi_buf_data(buf);
- cmd = (WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMD_fixed_param *)buf_ptr;
- WMITLV_SET_HDR(&cmd->tlv_header,
- WMITLV_TAG_STRUC_WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMD_fixed_param,
- WMITLV_GET_STRUCT_TLVLEN(
- WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param));
- cmd->vdev_id = vdev_id;
- cmd->pattern_id = pattern_id;
- wmi_mtrace(WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMDID,
- cmd->vdev_id, cmd->pattern_id);
- status = wmi_unified_cmd_send(wmi_handle, buf, len,
- WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMDID);
- if (status != QDF_STATUS_SUCCESS) {
- wmi_err("Failed to send wow coap del keepalive pattern command %d",
- status);
- wmi_buf_free(buf);
- }
- return status;
- }
- /*
- * send_coap_cache_get_cmd_tlv() - Send wmi cmd for getting cached CoAP
- * messages
- * @wmi_handle: wmi handle
- * @vdev_id: vdev id
- * @pattern_id: pattern id
- *
- * Return: QDF_STATUS
- */
- static QDF_STATUS
- send_coap_cache_get_cmd_tlv(wmi_unified_t wmi_handle,
- uint8_t vdev_id, uint32_t pattern_id)
- {
- WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param *cmd;
- wmi_buf_t buf;
- QDF_STATUS status;
- uint32_t len = sizeof(*cmd);
- wmi_debug("vdev id %d pattern id %d", vdev_id, pattern_id);
- buf = wmi_buf_alloc(wmi_handle, len);
- if (!buf)
- return QDF_STATUS_E_NOMEM;
- cmd = (WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param *)wmi_buf_data(buf);
- WMITLV_SET_HDR(&cmd->tlv_header,
- WMITLV_TAG_STRUC_WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param,
- WMITLV_GET_STRUCT_TLVLEN(
- WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param));
- cmd->vdev_id = vdev_id;
- cmd->pattern_id = pattern_id;
- wmi_mtrace(WMI_WOW_COAP_GET_BUF_INFO_CMDID,
- cmd->vdev_id, cmd->pattern_id);
- status = wmi_unified_cmd_send(wmi_handle, buf, len,
- WMI_WOW_COAP_GET_BUF_INFO_CMDID);
- if (status != QDF_STATUS_SUCCESS) {
- wmi_err("Failed to send wow coap get buf info command %d",
- status);
- wmi_buf_free(buf);
- }
- return status;
- }
- /**
- * coap_extract_buf_info_tlv() - Extract CoAP buf info event
- * @wmi_handle: wmi handle
- * @evt_buf: Pointer to the event buffer
- * @info: pointer to CoAP buf info
- *
- * The caller needs to free any possible nodes in info->info_list
- * regardless of failure or success.
- *
- * Return: QDF_STATUS
- */
- static QDF_STATUS
- coap_extract_buf_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
- struct coap_buf_info *info)
- {
- WMI_WOW_COAP_BUF_INFO_EVENT_fixed_param *buf_info_ev;
- WMI_WOW_COAP_BUF_INFO_EVENTID_param_tlvs *param_buf = evt_buf;
- wmi_coap_tuple *tuple;
- uint8_t *payload;
- uint32_t num_tuple, num_payload;
- struct coap_buf_node *buf_node;
- int i, j;
- buf_info_ev = param_buf->fixed_param;
- if (!buf_info_ev) {
- wmi_debug("received null event data from target");
- return QDF_STATUS_E_INVAL;
- }
- if (buf_info_ev->vdev_id > WLAN_MAX_VDEVS) {
- wmi_debug("received invalid vdev_id %d",
- buf_info_ev->vdev_id);
- return QDF_STATUS_E_INVAL;
- }
- info->vdev_id = buf_info_ev->vdev_id;
- info->req_id = buf_info_ev->pattern_id;
- info->more_info = buf_info_ev->more_tuples;
- num_tuple = param_buf->num_coap_tuple;
- num_payload = param_buf->num_payloads;
- for (i = 0, j = 0; i < num_tuple && j < num_payload; i++) {
- tuple = ¶m_buf->coap_tuple[i];
- if (!tuple->payload_len) {
- wmi_err("idx %d: invalid payload len 0", i);
- continue;
- }
- payload = ¶m_buf->payloads[j];
- j += qdf_align(tuple->payload_len, 4);
- if (j > num_payload) {
- wmi_err("idx %d: payload len overflow, pos %d - total %d",
- i, j, num_payload);
- return QDF_STATUS_E_INVAL;
- }
- buf_node = qdf_mem_malloc(sizeof(*buf_node));
- if (!buf_node)
- return QDF_STATUS_E_NOMEM;
- buf_node->payload = qdf_mem_malloc(tuple->payload_len);
- if (!buf_node->payload) {
- qdf_mem_free(buf_node);
- return QDF_STATUS_E_NOMEM;
- }
- buf_node->tsf = tuple->tsf;
- qdf_mem_copy(&buf_node->src_ip, tuple->src_ip.ipv4_addr,
- sizeof(buf_node->src_ip));
- buf_node->len = tuple->payload_len;
- qdf_mem_copy(buf_node->payload, payload, buf_node->len);
- qdf_list_insert_back(&info->info_list, &buf_node->node);
- wmi_debug("idx %d: src ip 0x%x tsf 0x%llx payload len %d",
- i, buf_node->src_ip, buf_node->tsf, buf_node->len);
- }
- wmi_debug("vdev_id %d req_id %d num_tuple %d payload len %d more info %d",
- info->vdev_id, info->req_id, num_tuple,
- num_payload, info->more_info);
- return QDF_STATUS_SUCCESS;
- }
- /**
- * wmi_coap_attach_tlv() - attach CoAP tlv handlers
- * @wmi_handle: wmi handle
- *
- * Return: void
- */
- void wmi_coap_attach_tlv(wmi_unified_t wmi_handle)
- {
- struct wmi_ops *ops = wmi_handle->ops;
- ops->send_coap_add_pattern_cmd = send_coap_add_pattern_cmd_tlv;
- ops->send_coap_del_pattern_cmd = send_coap_del_pattern_cmd_tlv;
- ops->send_coap_add_keepalive_pattern_cmd =
- send_coap_add_keepalive_pattern_cmd_tlv;
- ops->send_coap_del_keepalive_pattern_cmd =
- send_coap_del_keepalive_pattern_cmd_tlv;
- ops->send_coap_cache_get_cmd = send_coap_cache_get_cmd_tlv;
- ops->extract_coap_buf_info = coap_extract_buf_info_tlv;
- }
|