diff --git a/pmo/core/inc/wlan_pmo_pkt_filter.h b/pmo/core/inc/wlan_pmo_pkt_filter.h new file mode 100644 index 000000000000..0a900e5fe1f3 --- /dev/null +++ b/pmo/core/inc/wlan_pmo_pkt_filter.h @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2017 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: Declare packet filter feature API's + */ + +#ifndef _WLAN_PMO_PKT_FILTER_H_ +#define _WLAN_PMO_PKT_FILTER_ + +#include "wlan_pmo_pkt_filter_public_struct.h" + +struct wlan_objmgr_psoc; + +/** + * pmo_set_pkt_fltr_req() - Set packet filter + * @vdev: objmgr vdev + * @pmo_set_pkt_fltr_req: + * @vdev_id: + * API to set packet filter + * + * Return: QQDF_STATUS_SUCCESS in case of success else return error + */ +QDF_STATUS pmo_core_set_pkt_filter(struct wlan_objmgr_psoc *psoc, + struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req, + uint8_t vdev_id); + +/** + * pmo_core_clear_pkt_filter() - Clear packet filter + * @vdev: objmgr vdev + * @pmo_clr_pkt_fltr_req: + * @vdev_id: + * + * API to clear packet filter + * + * Return: QQDF_STATUS_SUCCESS in case of success else return error + */ +QDF_STATUS pmo_core_clear_pkt_filter(struct wlan_objmgr_psoc *psoc, + struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_req, + uint8_t vdev_id); + +#endif /* end of _WLAN_PMO_PKT_FILTER_H_ */ + diff --git a/pmo/core/src/wlan_pmo_pkt_filter.c b/pmo/core/src/wlan_pmo_pkt_filter.c new file mode 100644 index 000000000000..a59e25dfa80b --- /dev/null +++ b/pmo/core/src/wlan_pmo_pkt_filter.c @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2017 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: Implements Packet filter feature API's + */ + +#include "wlan_pmo_pkt_filter.h" +#include "wlan_pmo_tgt_api.h" +#include "wlan_pmo_main.h" +#include "wlan_pmo_obj_mgmt_public_struct.h" + +QDF_STATUS pmo_core_set_pkt_filter(struct wlan_objmgr_psoc *psoc, + struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req, + uint8_t vdev_id) +{ + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status; + + PMO_ENTER(); + + if (!psoc) { + pmo_err("psoc is null"); + status = QDF_STATUS_E_NULL_VALUE; + goto out; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_PMO_ID); + if (!vdev) { + pmo_err("vdev is NULL"); + status = QDF_STATUS_E_NULL_VALUE; + goto out; + } + + status = pmo_tgt_set_pkt_filter(vdev, pmo_set_pkt_fltr_req, vdev_id); + if (status != QDF_STATUS_SUCCESS) + goto dec_ref; + +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_PMO_ID); +out: + PMO_EXIT(); + + return status; + +} + +QDF_STATUS pmo_core_clear_pkt_filter(struct wlan_objmgr_psoc *psoc, + struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param, + uint8_t vdev_id) +{ + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status; + + PMO_ENTER(); + + if (!psoc) { + pmo_err("psoc is null"); + status = QDF_STATUS_E_NULL_VALUE; + goto out; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_PMO_ID); + if (!vdev) { + pmo_err("vdev is NULL"); + status = QDF_STATUS_E_NULL_VALUE; + goto out; + } + + status = pmo_tgt_clear_pkt_filter(vdev, pmo_clr_pkt_fltr_param, + vdev_id); + if (status != QDF_STATUS_SUCCESS) + goto dec_ref; + +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_PMO_ID); +out: + PMO_EXIT(); + + return status; + +} diff --git a/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h b/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h new file mode 100644 index 000000000000..d067fe1486d7 --- /dev/null +++ b/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h @@ -0,0 +1,141 @@ +/* +* Copyright (c) 2017 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: Declare various struct, macros which shall be used in + * pmo packet filter feature. + * + * Note: This file shall not contain public API's prototype/declarations. + * + */ + +#ifndef _WLAN_PMO_PKT_FILTER_PUBLIC_STRUCT_H_ +#define _WLAN_PMO_PKT_FILTER_PUBLIC_STRUCT_H_ + +#include "qdf_types.h" + +#define PMO_MAX_FILTER_TEST_DATA_LEN 8 +#define PMO_MAX_NUM_TESTS_PER_FILTER 10 + +/** + * enum pmo_rcv_pkt_fltr_type: Receive Filter Parameters + * @PMO_RCV_FILTER_TYPE_INVALID: invalied filter type + * @PMO_RCV_FILTER_TYPE_FILTER_PKT: packet filter + * @PMO_RCV_FILTER_TYPE_BUFFER_PKT: buffer packet + * @PMO_RCV_FILTER_TYPE_MAX_ENUM_SIZE: max filter + */ +enum pmo_rcv_pkt_fltr_type { + PMO_RCV_FILTER_TYPE_INVALID, + PMO_RCV_FILTER_TYPE_FILTER_PKT, + PMO_RCV_FILTER_TYPE_BUFFER_PKT, + PMO_RCV_FILTER_TYPE_MAX_ENUM_SIZE +}; + +/** + * enum pmo_rcv_pkt_fltr_flag_type: Receive Filter flags + * @PMO_FILTER_CMP_TYPE_INVALID: invalied flag + * @PMO_FILTER_CMP_TYPE_EQUAL: equal + * @PMO_FILTER_CMP_TYPE_MASK_EQUAL: mask + * @PMO_FILTER_CMP_TYPE_NOT_EQUAL: not equal + * @PMO_FILTER_CMP_TYPE_MASK_NOT_EQUAL: mask not equal + * @PMO_FILTER_CMP_TYPE_MAX: max size of flag + */ +enum pmo_rcv_pkt_fltr_flag_type { + PMO_FILTER_CMP_TYPE_INVALID, + PMO_FILTER_CMP_TYPE_EQUAL, + PMO_FILTER_CMP_TYPE_MASK_EQUAL, + PMO_FILTER_CMP_TYPE_NOT_EQUAL, + PMO_FILTER_CMP_TYPE_MASK_NOT_EQUAL, + PMO_FILTER_CMP_TYPE_MAX +}; + +/** + * enum pmo_rcv_pkt_fltr_protocol_params: Receive Filter protocal parameters + * @PMO_FILTER_HDR_TYPE_INVALID: invalied type + * @PMO_FILTER_HDR_TYPE_MAC: mac protocol + * @PMO_FILTER_HDR_TYPE_ARP: arp protocol + * @PMO_FILTER_HDR_TYPE_IPV4: ipv4 protocol + * @PMO_FILTER_HDR_TYPE_IPV6: ipv6 protocol + * @PMO_FILTER_HDR_TYPE_UDP: udp protocol + * @PMO_FILTER_HDR_TYPE_MAX: max of type of protocol + */ +enum pmo_rcv_pkt_fltr_protocol_params { + PMO_FILTER_HDR_TYPE_INVALID, + PMO_FILTER_HDR_TYPE_MAC, + PMO_FILTER_HDR_TYPE_ARP, + PMO_FILTER_HDR_TYPE_IPV4, + PMO_FILTER_HDR_TYPE_IPV6, + PMO_FILTER_HDR_TYPE_UDP, + PMO_FILTER_HDR_TYPE_MAX +}; + +/** + * struct pmo_rcv_pkt_fltr_field_params - pmo packet filter field parameters + * @protocol_layer: Protocol layer + * @compare_flag: Comparison flag + * @data_length: Length of the data to compare + * @data_offset: from start of the respective frame header + * @reserved: Reserved field + * @compare_data: Data to compare + * @data_mask: Mask to be applied on the received packet data before compare + */ +struct pmo_rcv_pkt_fltr_field_params { + enum pmo_rcv_pkt_fltr_protocol_params protocol_layer; + enum pmo_rcv_pkt_fltr_flag_type compare_flag; + uint16_t data_length; + uint8_t data_offset; + uint8_t reserved; + uint8_t compare_data[PMO_MAX_FILTER_TEST_DATA_LEN]; + uint8_t data_mask[PMO_MAX_FILTER_TEST_DATA_LEN]; +}; + +/** + * struct pmo_rcv_pkt_fltr_cfg - pmo packet filter config + * @filter_id: filter id + * @filter_type: filter type + * @num_params: number of parameters + * @coalesce_time: time + * @self_macaddr: mac address + * @bssid: Bssid of the connected AP + * @params_data: data + */ +struct pmo_rcv_pkt_fltr_cfg { + uint8_t filter_id; + enum pmo_rcv_pkt_fltr_type filter_type; + uint32_t num_params; + uint32_t coalesce_time; + struct qdf_mac_addr self_macaddr; + struct qdf_mac_addr bssid; + struct pmo_rcv_pkt_fltr_field_params + params_data[PMO_MAX_NUM_TESTS_PER_FILTER]; +}; + +/** + * struct pmo_rcv_pkt_fltr_cfg - pmo receive Filter Clear Parameters + * @status: only valid for response message + * @filter_id: + * @self_macaddr: + * @bssid: peer ap address + */ +struct pmo_rcv_pkt_fltr_clear_param { + uint32_t status; + uint8_t filter_id; + struct qdf_mac_addr self_macaddr; + struct qdf_mac_addr bssid; +}; + +#endif /* end of _WLAN_PMO_PKT_FILTER_PUBLIC_STRUCT_H_ */ diff --git a/pmo/dispatcher/inc/wlan_pmo_tgt_api.h b/pmo/dispatcher/inc/wlan_pmo_tgt_api.h index c0966aa80a91..e9d345cce38b 100644 --- a/pmo/dispatcher/inc/wlan_pmo_tgt_api.h +++ b/pmo/dispatcher/inc/wlan_pmo_tgt_api.h @@ -48,6 +48,34 @@ QDF_STATUS pmo_tgt_enable_non_arp_bcast_filter_req( QDF_STATUS pmo_tgt_disable_non_arp_bcast_filter_req( struct wlan_objmgr_vdev *vdev, uint8_t vdev_id); +/** + * pmo_tgt_set_pkt_filter() - Set packet filter + * @vdev: objmgr vdev + * @pmo_set_pkt_fltr_req: + * @vdev_id: vdev id + * + * API to set packet filter + * + * Return: QDF_STATUS_SUCCESS in case of success else return error + */ +QDF_STATUS pmo_tgt_set_pkt_filter(struct wlan_objmgr_vdev *vdev, + struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req, + uint8_t vdev_id); + +/** + * pmo_tgt_clear_pkt_filter() - Clear packet filter + * @vdev: objmgr vdev + * @pmo_clr_pkt_fltr_param: + * @vdev_id: vdev id + * + * API to clear packet filter + * + * Return: QDF_STATUS_SUCCESS in case of success else return error + */ +QDF_STATUS pmo_tgt_clear_pkt_filter(struct wlan_objmgr_vdev *vdev, + struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param, + uint8_t vdev_id); + /** * pmo_tgt_enable_arp_offload_req() - Enable arp offload req to target * @vdev: objmgr vdev diff --git a/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h index 268c7bcb6045..8360a724eca6 100644 --- a/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h +++ b/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h @@ -29,6 +29,7 @@ #include "wlan_pmo_wow_public_struct.h" #include "wlan_pmo_common_public_struct.h" #include "wlan_pmo_obj_mgmt_api.h" +#include "wlan_pmo_pkt_filter_public_struct.h" /** * pmo_ucfg_is_ap_mode_supports_arp_ns() - Check ap mode support arp&ns offload @@ -300,6 +301,30 @@ QDF_STATUS pmo_ucfg_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev); */ QDF_STATUS pmo_ucfg_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev); +/** + * pmo_ucfg_set_pkt_filter() - Set packet filter + * @psoc: objmgr psoc handle + * @pmo_set_pkt_fltr_req: + * @vdev_id: vdev id + * + * Return QDF_STATUS_SUCCESS -in case of success else return error + */ +QDF_STATUS pmo_ucfg_set_pkt_filter(struct wlan_objmgr_psoc *psoc, + struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req, + uint8_t vdev_id); + +/** + * pmo_ucfg_clear_pkt_filter() - Clear packet filter + * @psoc: objmgr psoc handle + * @pmo_clr_pkt_fltr_req: + * @vdev_id: vdev id + * + * Return QDF_STATUS_SUCCESS -in case of success else return error + */ +QDF_STATUS pmo_ucfg_clear_pkt_filter(struct wlan_objmgr_psoc *psoc, + struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param, + uint8_t vdev_id); + /** * pmo_ucfg_get_gtk_rsp(): API to send gtk response request to fwr * @vdev: objmgr vdev handle diff --git a/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c b/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c new file mode 100644 index 000000000000..8c38239eba76 --- /dev/null +++ b/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c @@ -0,0 +1,155 @@ +/* +* Copyright (c) 2017 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: Implements public API for pmo to interact with target/WMI + */ + +#include "wlan_pmo_tgt_api.h" +#include "wlan_pmo_pkt_filter_public_struct.h" +#include "wlan_pmo_obj_mgmt_public_struct.h" + +QDF_STATUS pmo_tgt_set_pkt_filter(struct wlan_objmgr_vdev *vdev, + struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req, + uint8_t vdev_id) +{ + QDF_STATUS status; + struct pmo_rcv_pkt_fltr_cfg *request_buf = NULL; + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_pmo_tx_ops pmo_tx_ops; + struct qdf_mac_addr peer_bssid; + + PMO_ENTER(); + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + pmo_err("psoc unavailable for vdev %p", vdev); + status = QDF_STATUS_E_NULL_VALUE; + goto out; + } + + pmo_info("filter_type=%d, filter_id = %d", + pmo_set_pkt_fltr_req->filter_type, + pmo_set_pkt_fltr_req->filter_id); + + request_buf = qdf_mem_malloc(sizeof(*request_buf)); + + if (request_buf == NULL) { + pmo_err("Not able to allocate memory for Receive Filter Set Filter request"); + status = QDF_STATUS_E_NOMEM; + goto out; + } + + status = pmo_get_vdev_bss_peer_mac_addr(vdev, + &peer_bssid); + if (status != QDF_STATUS_SUCCESS) { + status = QDF_STATUS_E_INVAL; + goto out; + } + + qdf_mem_copy(request_buf, pmo_set_pkt_fltr_req, sizeof(*request_buf)); + + qdf_mem_copy(&request_buf->self_macaddr.bytes, + wlan_vdev_mlme_get_macaddr(vdev), + QDF_MAC_ADDR_SIZE); + + qdf_copy_macaddr(&pmo_set_pkt_fltr_req->bssid, + &peer_bssid); + + pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc); + if (!pmo_tx_ops.send_set_pkt_filter) { + pmo_err("send_set_pkt_filter is null"); + status = QDF_STATUS_E_NULL_VALUE; + goto out; + } + + status = pmo_tx_ops.send_set_pkt_filter(vdev, request_buf); + if (status != QDF_STATUS_SUCCESS) + goto out; + +out: + if (request_buf) + qdf_mem_free(request_buf); + PMO_EXIT(); + + return status; +} + +QDF_STATUS pmo_tgt_clear_pkt_filter(struct wlan_objmgr_vdev *vdev, + struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param, + uint8_t vdev_id) +{ + QDF_STATUS status; + struct pmo_rcv_pkt_fltr_clear_param *request_buf = NULL; + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_pmo_tx_ops pmo_tx_ops; + struct qdf_mac_addr peer_bssid; + + PMO_ENTER(); + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + pmo_err("psoc unavailable for vdev %p", vdev); + status = QDF_STATUS_E_NULL_VALUE; + goto out; + } + + pmo_info("filter_id = %d", pmo_clr_pkt_fltr_param->filter_id); + + request_buf = qdf_mem_malloc(sizeof(*request_buf)); + + if (request_buf == NULL) { + pmo_err("Not able to allocate memory for Receive Filter Set Filter request"); + status = QDF_STATUS_E_NOMEM; + goto out; + } + + status = pmo_get_vdev_bss_peer_mac_addr(vdev, + &peer_bssid); + if (status != QDF_STATUS_SUCCESS) { + status = QDF_STATUS_E_INVAL; + goto out; + } + + qdf_mem_copy(request_buf, pmo_clr_pkt_fltr_param, sizeof(*request_buf)); + + qdf_mem_copy(&request_buf->self_macaddr.bytes, + wlan_vdev_mlme_get_macaddr(vdev), + QDF_MAC_ADDR_SIZE); + + qdf_copy_macaddr(&pmo_clr_pkt_fltr_param->bssid, + &peer_bssid); + + pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc); + if (!pmo_tx_ops.send_clear_pkt_filter) { + pmo_err("send_clear_pkt_filter is null"); + status = QDF_STATUS_E_NULL_VALUE; + goto out; + } + + status = pmo_tx_ops.send_clear_pkt_filter(vdev, request_buf); + if (status != QDF_STATUS_SUCCESS) + goto out; + +out: + if (request_buf) + qdf_mem_free(request_buf); + PMO_EXIT(); + + return status; +} + diff --git a/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/pmo/dispatcher/src/wlan_pmo_ucfg_api.c index 064047a277d9..3a8b5c017c25 100644 --- a/pmo/dispatcher/src/wlan_pmo_ucfg_api.c +++ b/pmo/dispatcher/src/wlan_pmo_ucfg_api.c @@ -29,6 +29,7 @@ #include "wlan_pmo_main.h" #include "wlan_pmo_lphb.h" #include "wlan_pmo_suspend_resume.h" +#include "wlan_pmo_pkt_filter.h" QDF_STATUS pmo_ucfg_get_psoc_config(struct wlan_objmgr_psoc *psoc, struct pmo_psoc_cfg *psoc_cfg) @@ -182,6 +183,21 @@ QDF_STATUS pmo_ucfg_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev) return pmo_core_disable_gtk_offload_in_fwr(vdev); } +QDF_STATUS pmo_ucfg_set_pkt_filter(struct wlan_objmgr_psoc *psoc, + struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req, + uint8_t vdev_id) +{ + return pmo_core_set_pkt_filter(psoc, pmo_set_pkt_fltr_req, vdev_id); +} + +QDF_STATUS pmo_ucfg_clear_pkt_filter(struct wlan_objmgr_psoc *psoc, + struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param, + uint8_t vdev_id) +{ + return pmo_core_clear_pkt_filter(psoc, + pmo_clr_pkt_fltr_param, vdev_id); +} + QDF_STATUS pmo_ucfg_get_gtk_rsp(struct wlan_objmgr_vdev *vdev, struct pmo_gtk_rsp_req *gtk_rsp_req) { diff --git a/target_if/pmo/inc/target_if_pmo.h b/target_if/pmo/inc/target_if_pmo.h index 4f738aaca833..beb1fe720ab2 100644 --- a/target_if/pmo/inc/target_if_pmo.h +++ b/target_if/pmo/inc/target_if_pmo.h @@ -137,6 +137,30 @@ QDF_STATUS target_if_pmo_send_non_arp_bcast_filter_req( struct wlan_objmgr_vdev *vdev, struct pmo_bcast_filter_params *bcast_req); +/** + * target_if_pmo_send_pkt_filter_req() - enable packet filter + * @vdev: objmgr vdev + * @rcv_filter_param: filter params + * + * This function enable packet filter + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +QDF_STATUS target_if_pmo_send_pkt_filter_req(struct wlan_objmgr_vdev *vdev, + struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param); + +/** + * target_if_pmo_clear_pkt_filter_req() - disable packet filter + * @vdev: objmgr vdev + * @rcv_clear_param: filter params + * + * This function disable packet filter + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +QDF_STATUS target_if_pmo_clear_pkt_filter_req(struct wlan_objmgr_vdev *vdev, + struct pmo_rcv_pkt_fltr_clear_param *rcv_clear_param); + /** * target_if_pmo_send_arp_offload_req() - sends arp request to fwr * @vdev: objmgr vdev diff --git a/target_if/pmo/src/target_if_pmo_main.c b/target_if/pmo/src/target_if_pmo_main.c index 45269794930c..4bfcc74280ae 100644 --- a/target_if/pmo/src/target_if_pmo_main.c +++ b/target_if/pmo/src/target_if_pmo_main.c @@ -94,6 +94,10 @@ void target_if_pmo_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) target_if_pmo_psoc_send_host_wakeup_ind; pmo_tx_ops->psoc_send_target_resume_req = target_if_pmo_psoc_send_target_resume_req; + pmo_tx_ops->send_set_pkt_filter = + target_if_pmo_send_pkt_filter_req; + pmo_tx_ops->send_clear_pkt_filter = + target_if_pmo_clear_pkt_filter_req; } diff --git a/target_if/pmo/src/target_if_pmo_pkt_filter.c b/target_if/pmo/src/target_if_pmo_pkt_filter.c new file mode 100644 index 000000000000..9803e99ce6dc --- /dev/null +++ b/target_if/pmo/src/target_if_pmo_pkt_filter.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2017 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: target_if_pmo_pkt_filter.c + * + * Target interface file for pmo component to + * send packet filter related cmd and process event. + */ + +#include "target_if.h" +#include "target_if_pmo.h" +#include "wmi_unified_pmo_api.h" +#include "wlan_pmo_pkt_filter_public_struct.h" + +QDF_STATUS target_if_pmo_send_pkt_filter_req(struct wlan_objmgr_vdev *vdev, + struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param) +{ + uint8_t vdev_id; + struct wlan_objmgr_psoc *psoc; + QDF_STATUS status; + + if (!vdev) { + target_if_err("vdev ptr passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + if (!psoc) { + target_if_err("psoc handle is NULL"); + return QDF_STATUS_E_INVAL; + } + + /* send the command along with data */ + status = wmi_unified_config_packet_filter_cmd( + GET_WMI_HDL_FROM_PSOC(psoc), vdev_id, + rcv_filter_param, + rcv_filter_param->filter_id, true); + if (status) { + target_if_err("Failed to send pkt_filter cmd"); + return QDF_STATUS_E_INVAL; + } + + /* Enable packet filter */ + status = wmi_unified_enable_disable_packet_filter_cmd( + GET_WMI_HDL_FROM_PSOC(psoc), + vdev_id, true); + if (status) + target_if_err("Failed to send packet filter wmi cmd to fw"); + + return status; +} + +QDF_STATUS target_if_pmo_clear_pkt_filter_req(struct wlan_objmgr_vdev *vdev, + struct pmo_rcv_pkt_fltr_clear_param *rcv_clear_param) +{ + uint8_t vdev_id; + struct wlan_objmgr_psoc *psoc; + QDF_STATUS status; + + if (!vdev) { + target_if_err("vdev ptr passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + if (!psoc) { + target_if_err("psoc handle is NULL"); + return QDF_STATUS_E_INVAL; + } + + /* send the command along with data */ + status = wmi_unified_config_packet_filter_cmd( + GET_WMI_HDL_FROM_PSOC(psoc), vdev_id, + NULL, rcv_clear_param->filter_id, false); + + if (status) + target_if_err("Failed to clear filter cmd"); + + return status; +}