Merge "qcacld-3.0: Configure and clear default packet filters over suspend and resume" into wlan-cld3.driver.lnx.2.0-dev

This commit is contained in:
CNSS_WLAN Service 2017-10-17 12:54:15 -07:00 • committed by Gerrit - the friendly Code Review server
commit ca11a07897
8 changed files with 401 additions and 2 deletions

View file

@ -13105,6 +13105,44 @@ enum hdd_external_acs_freq_band {
#define CFG_MBO_CAND_RSSI_BTC_THRESHOLD_MAX (0)
/*
* <ini>
* g_enable_packet_filter_bitmap - Enable Packet filters before going into
* suspend mode
* @Min: 0
* @Max: 63
* @Default: 0
* Below is the Detailed bit map of the Filters
* bit-0 : IPv6 multicast
* bit-1 : IPv4 multicast
* bit-2 : IPv4 broadcast
* bit-3 : XID - Exchange station Identification packet, solicits the
* identification of the receiving station
* bit-4 : STP - Spanning Tree Protocol, builds logical loop free topology
* bit-5 : DTP/LLC/CDP
* DTP - Dynamic Trunking Protocol is used by Ciscoswitches to negotiate
* whether an interconnection between two switches should be put into access or
* trunk mode
* LLC - Logical link control, used for multiplexing, flow & error control
* CDP - Cisco Discovery Protocol packet contains information about the cisco
* devices in the network
*
* This ini support to enable above mentioned packet filters
* when target goes to suspend mode, clear those when resume
*
* Related: None
*
* Supported Feature: PACKET FILTERING
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_ENABLE_PACKET_FILTERS_NAME "g_enable_packet_filter_bitmap"
#define CFG_ENABLE_PACKET_FILTERS_DEFAULT (0)
#define CFG_ENABLE_PACKET_FILTERS_MIN (0)
#define CFG_ENABLE_PACKET_FILTERS_MAX (63)
/*
* Type declarations
*/
@ -13961,6 +13999,7 @@ struct hdd_config {
int8_t mbo_current_rssi_thres;
int8_t mbo_current_rssi_mcc_thres;
int8_t mbo_candidate_rssi_btc_thres;
uint8_t packet_filters_bitmap;
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))

View file

@ -1781,6 +1781,7 @@ struct hdd_context {
eCsrBand curr_band;
bool fw_mem_dump_enabled;
bool imps_enabled;
int user_configured_pkt_filter_rules;
};
/**

View file

@ -0,0 +1,58 @@
/*
* 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.
*/
#if !defined(WLAN_HDD_PACKET_FILTER_API_H__)
#define WLAN_HDD_PACKET_FILTER_API_H__
/**
* DOC: wlan_hdd_packet_filter_rules.h
*
*/
/* Include files */
/**
* hdd_enable_default_pkt_filters() - Enable default packet filters based
* on, filters bit map provided in INI, when target goes to suspend mode
* @adapter: Adapter context for which default filters to be configure
*
* Return: zero if success, non-zero otherwise
*/
int hdd_enable_default_pkt_filters(struct hdd_adapter *pAadapter);
/**
* hdd_disable_default_pkt_filters() - Disable default packet filters based
* on, filters bit map provided in INI, when target resumes
* @adapter: Adapter context for which default filters to be cleared
*
* Return: zero if success, non-zero otherwise
*/
int hdd_disable_default_pkt_filters(struct hdd_adapter *adapter);
/**
* wlan_hdd_set_filter() - Set packet filter
* @hdd_ctx: Global HDD context
* @request: Packet filter request struct
* @sessionId: Target session for the request
*
* Return: 0 on success, non-zero on error
*/
int wlan_hdd_set_filter(struct hdd_context *hdd_ctx,
struct pkt_filter_cfg *request,
uint8_t sessionId);
#endif

View file

@ -0,0 +1,180 @@
/*
* 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.
*/
#if !defined(WLAN_HDD_PACKET_FILTER_RULES_H__)
#define WLAN_HDD_PACKET_FILTER_RULES_H__
/**
* DOC: wlan_hdd_packet_filter_rules.h
*
*/
/* Include files */
#define MAX_NUM_PACKET_FILTERS 6
/**
* @filter_action: Filter action, set/clear the filter
* Ex: filter_action = 1 set the filter
* filter_action = 2 clear the filter
* @filter_id: Filter id Ex: 1/2/3/4/5 .... MAX_NUM_FILTERS
* @num_params: Number of parameters Ex: 1/2/3/4/5
* @params_data: Packet filter parameters details
*
* @protocol_layer: the type of protocol layer header to which the data
* being configured correspond
* Ex: protocol_layer = 1 - MAC Header
* protocol_layer = 2 - ARP Header
* protocol_layer = 3 - IP Header
* @compare_flag: comparison type
* EX: compare_flag = 0 - comparison is invalid
* compare_flag = 1 - compare for equality of the data present in received
* packet to the corresponding configured data
* compare_flag = 2 - compare for equality of the data present in received
* packet to the corresponding configured data after
* applying the mask
* compare_flag = 3 - compare for non-equality of the data present in
* received packet to the corresponding configured data
* compare_flag = 4 - compare for non-equality of the data present in
* received packet to the corresponding configured data
* after applying the mask
* @data_fffset: Offset of the data to compare from the respective protocol
* layer header start (as per the respective protocol
* specification) in terms of bytes
* @data_length: length of data to compare
* @compare_data: Array of 8 bytes
* @data_mask: Mask to be applied on the received packet data (Array of 8 bytes)
*/
static const struct pkt_filter_cfg
packet_filter_default_rules[MAX_NUM_PACKET_FILTERS] = {
{ .filter_action = 1,
.filter_id = 0,
.num_params = 3,
.params_data = {
{ .protocol_layer = 1,
.compare_flag = 5,
.data_offset = 0,
.data_length = 1,
.compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
{ .protocol_layer = 2,
.compare_flag = 3,
.data_offset = 6,
.data_length = 2,
.compare_data = {134, 221, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
{ .protocol_layer = 3,
.compare_flag = 4,
.data_offset = 24,
.data_length = 2,
.compare_data = {255, 0, 0, 0, 0, 0, 0, 0},
.data_mask = {255, 0, 0, 0, 0, 0, 0, 0} } } },
{ .filter_action = 1,
.filter_id = 0,
.num_params = 3,
.params_data = {
{ .protocol_layer = 1,
.compare_flag = 5,
.data_offset = 0,
.data_length = 1,
.compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
{ .protocol_layer = 2,
.compare_flag = 3,
.data_offset = 6,
.data_length = 2,
.compare_data = {8, 0, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
{ .protocol_layer = 3,
.compare_flag = 4,
.data_offset = 16,
.data_length = 1,
.compare_data = {224, 0, 0, 0, 0, 0, 0, 0},
.data_mask = {240, 0, 0, 0, 0, 0, 0, 0} } } },
{ .filter_action = 1,
.filter_id = 0,
.num_params = 3,
.params_data = {
{ .protocol_layer = 1,
.compare_flag = 5,
.data_offset = 0,
.data_length = 1,
.compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
{ .protocol_layer = 2,
.compare_flag = 3,
.data_offset = 6,
.data_length = 2,
.compare_data = {8, 0, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
{ .protocol_layer = 3,
.compare_flag = 4,
.data_offset = 18,
.data_length = 2,
.compare_data = {0, 255, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 255, 0, 0, 0, 0, 0, 0} } } },
{ .filter_action = 1,
.filter_id = 0,
.num_params = 2,
.params_data = {
{ .protocol_layer = 1,
.compare_flag = 5,
.data_offset = 0,
.data_length = 1,
.compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
{ .protocol_layer = 2,
.compare_flag = 3,
.data_offset = 8,
.data_length = 4,
.compare_data = {0, 1, 175, 129, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} } } },
{ .filter_action = 1,
.filter_id = 0,
.num_params = 2,
.params_data = {
{ .protocol_layer = 1,
.compare_flag = 5,
.data_offset = 0,
.data_length = 1,
.compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
{ .protocol_layer = 2,
.compare_flag = 3,
.data_offset = 6,
.data_length = 2,
.compare_data = {0, 39, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} } } },
{ .filter_action = 1,
.filter_id = 0,
.num_params = 2,
.params_data = {
{ .protocol_layer = 1,
.compare_flag = 5,
.data_offset = 0,
.data_length = 1,
.compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
{ .protocol_layer = 2,
.compare_flag = 3,
.data_offset = 4,
.data_length = 2,
.compare_data = {0, 12, 0, 0, 0, 0, 0, 0},
.data_mask = {0, 0, 0, 0, 0, 0, 0, 0} } } } };
#endif

View file

@ -5156,13 +5156,19 @@ struct reg_table_entry g_registry_table[] = {
CFG_MBO_CAND_RSSI_BTC_THRESHOLD_DEFAULT,
CFG_MBO_CAND_RSSI_BTC_THRESHOLD_MIN,
CFG_MBO_CAND_RSSI_BTC_THRESHOLD_MAX),
REG_VARIABLE(CFG_IS_FILS_ENABLED_NAME, WLAN_PARAM_Integer,
struct hdd_config, is_fils_enabled,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_IS_FILS_ENABLED_DEFAULT,
CFG_IS_FILS_ENABLED_MIN,
CFG_IS_FILS_ENABLED_MAX),
REG_VARIABLE(CFG_ENABLE_PACKET_FILTERS_NAME, WLAN_PARAM_Integer,
struct hdd_config, packet_filters_bitmap,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_ENABLE_PACKET_FILTERS_DEFAULT,
CFG_ENABLE_PACKET_FILTERS_MIN,
CFG_ENABLE_PACKET_FILTERS_MAX),
};

View file

@ -0,0 +1,100 @@
/*
* 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: wlan_hdd_packet_filter.c
*
* WLAN Host Device Driver implementation
*
*/
/* Include Files */
#include "wlan_hdd_packet_filter_api.h"
int hdd_enable_default_pkt_filters(struct hdd_adapter *adapter)
{
struct hdd_context *hdd_ctx;
uint8_t filters = 0, i = 0, filter_id = 1;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (hdd_ctx == NULL) {
hdd_err("HDD context is Null!!!");
return -EINVAL;
}
if (!hdd_ctx->user_configured_pkt_filter_rules) {
hdd_info("user has defined pkt filter run hence skipping default packet filter rule");
return 0;
}
filters = hdd_ctx->config->packet_filters_bitmap;
while (filters != 0) {
if (filters & 0x1) {
hdd_err("setting filter[%d], of id = %d",
i+1, filter_id);
packet_filter_default_rules[i].filter_id = filter_id;
wlan_hdd_set_filter(hdd_ctx,
&packet_filter_default_rules[i],
adapter->sessionId);
filter_id++;
}
filters = filters >> 1;
i++;
}
return 0;
}
int hdd_disable_default_pkt_filters(struct hdd_adapter *adapter)
{
struct hdd_context *hdd_ctx;
uint8_t filters = 0, i = 0, filter_id = 1;
struct pkt_filter_cfg packet_filter_default_rules;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (hdd_ctx == NULL) {
hdd_err("HDD context is Null!!!");
return -EINVAL;
}
if (!hdd_ctx->user_configured_pkt_filter_rules) {
hdd_info("user has defined pkt filter run hence skipping default packet filter rule");
return 0;
}
filters = hdd_ctx->config->packet_filters_bitmap;
while (filters != 0) {
if (filters & 0x1) {
hdd_err("Clearing filter[%d], of id = %d",
i+1, filter_id);
packet_filter_default_rules.filter_action =
HDD_RCV_FILTER_CLEAR;
packet_filter_default_rules.filter_id = i;
wlan_hdd_set_filter(hdd_ctx,
&packet_filter_default_rules,
adapter->sessionId);
filter_id++;
}
filters = filters >> 1;
i++;
}
return 0;
}

View file

@ -81,6 +81,7 @@
#include <wlan_logging_sock_svc.h>
#include "scheduler_api.h"
#include "cds_utils.h"
#include "wlan_hdd_packet_filter_api.h"
/* Preprocessor definitions and constants */
#ifdef QCA_WIFI_NAPIER_EMULATION
@ -1098,6 +1099,9 @@ hdd_suspend_wlan(void)
WLAN_STOP_ALL_NETIF_QUEUE,
WLAN_CONTROL_PATH);
if (adapter->device_mode == QDF_STA_MODE)
status = hdd_enable_default_pkt_filters(adapter);
/* Configure supported OffLoads */
hdd_enable_host_offloads(adapter, pmo_apps_suspend);
hdd_update_conn_state_mask(adapter, &conn_state_mask);
@ -1164,6 +1168,9 @@ static int hdd_resume_wlan(void)
WLAN_WAKE_ALL_NETIF_QUEUE,
WLAN_CONTROL_PATH);
if (adapter->device_mode == QDF_STA_MODE)
status = hdd_disable_default_pkt_filters(adapter);
next_adapter:
status = hdd_get_next_adapter(hdd_ctx, pAdapterNode, &pNext);
pAdapterNode = pNext;

View file

@ -103,6 +103,7 @@
#include <wlan_osif_priv.h>
#include "wlan_hdd_regulatory.h"
#include "wlan_reg_ucfg_api.h"
#include "wlan_hdd_packet_filter_api.h"
#define HDD_FINISH_ULA_TIME_OUT 800
#define HDD_SET_MCBC_FILTERS_TO_FW 1
@ -12049,7 +12050,7 @@ static int iw_set_keepalive_params(struct net_device *dev,
*
* Return: 0 on success, non-zero on error
*/
static int wlan_hdd_set_filter(struct hdd_context *hdd_ctx,
int wlan_hdd_set_filter(struct hdd_context *hdd_ctx,
struct pkt_filter_cfg *request,
uint8_t sessionId)
{
@ -12274,6 +12275,13 @@ static int __iw_set_packet_filter_params(struct net_device *dev,
return -ENOMEM;
}
if (request->filter_action == HDD_RCV_FILTER_SET)
hdd_ctx->user_configured_pkt_filter_rules |=
1 << request->filter_id;
else if (request->filter_action == HDD_RCV_FILTER_CLEAR)
hdd_ctx->user_configured_pkt_filter_rules &=
~(1 << request->filter_id);
ret = wlan_hdd_set_filter(hdd_ctx, request, adapter->sessionId);
qdf_mem_free(request);