qcacmn: Add support for frame delay operation
Add frame delay support for IOT Simulation. Change-Id: I1ae2f681cde5d3e4092bf65a34f48290af6877d3 CRs-Fixed: 2734410
This commit is contained in:

committed by
snandini

parent
3be1a0a167
commit
d2c1b38caa
@@ -40,6 +40,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define USER_BUF_LEN_DROP (2 + 2 + 2 + 2 + 1 + 17)
|
#define USER_BUF_LEN_DROP (2 + 2 + 2 + 2 + 1 + 17)
|
||||||
|
/*
|
||||||
|
* IOT SIM User Buf Format for Drop
|
||||||
|
* ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
* |FrmType/subtype| Seq |category|action| delay |MacAddr|
|
||||||
|
* ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
* | 2Characters |2char| 2chars |2chars| 4char|17chars|
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define USER_BUF_LEN_DELAY (2 + 2 + 2 + 2 + 4 + 17)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wlan_iot_sim_pdev_obj_create_handler() - handler for pdev object create
|
* wlan_iot_sim_pdev_obj_create_handler() - handler for pdev object create
|
||||||
@@ -103,6 +112,7 @@ iot_sim_find_peer_from_mac(struct iot_sim_context *isc,
|
|||||||
* @pdev: reference to global pdev object
|
* @pdev: reference to global pdev object
|
||||||
* @nbuf: frame buffer
|
* @nbuf: frame buffer
|
||||||
* @tx: TRUE in case of tx
|
* @tx: TRUE in case of tx
|
||||||
|
* @rx_param: mgmt_rx_event_params
|
||||||
*
|
*
|
||||||
* This function updates the outgoing management frame with
|
* This function updates the outgoing management frame with
|
||||||
* the content stored in iot_sim_context.
|
* the content stored in iot_sim_context.
|
||||||
@@ -113,7 +123,8 @@ iot_sim_find_peer_from_mac(struct iot_sim_context *isc,
|
|||||||
QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev,
|
QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev,
|
||||||
qdf_nbuf_t nbuf,
|
qdf_nbuf_t nbuf,
|
||||||
struct beacon_tmpl_params *param,
|
struct beacon_tmpl_params *param,
|
||||||
bool tx);
|
bool tx,
|
||||||
|
struct mgmt_rx_event_params *rx_param);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* iot_sim_get_ctx_from_pdev() - API to get iot_sim context object
|
* iot_sim_get_ctx_from_pdev() - API to get iot_sim context object
|
||||||
|
@@ -21,8 +21,10 @@
|
|||||||
#include <qdf_types.h>
|
#include <qdf_types.h>
|
||||||
#include <qdf_util.h>
|
#include <qdf_util.h>
|
||||||
#include <qdf_str.h>
|
#include <qdf_str.h>
|
||||||
|
#include <qdf_delayed_work.h>
|
||||||
#include <wmi_unified_param.h>
|
#include <wmi_unified_param.h>
|
||||||
#include <wlan_iot_sim_utils_api.h>
|
#include <wlan_iot_sim_utils_api.h>
|
||||||
|
#include <wlan_lmac_if_api.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* iot_sim_oper_to_str - function to return iot sim operation string
|
* iot_sim_oper_to_str - function to return iot sim operation string
|
||||||
@@ -164,7 +166,7 @@ iot_sim_find_peer_from_mac(struct iot_sim_context *isc,
|
|||||||
qdf_list_peek_next(&isc->peer_list, node, &next_node));
|
qdf_list_peek_next(&isc->peer_list, node, &next_node));
|
||||||
|
|
||||||
qdf_spin_unlock_bh(&isc->iot_sim_lock);
|
qdf_spin_unlock_bh(&isc->iot_sim_lock);
|
||||||
iot_sim_err("Failed to find peer");
|
iot_sim_debug("Failed to find peer");
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -686,7 +688,7 @@ iot_sim_send_rule_to_fw(struct iot_sim_context *isc,
|
|||||||
{
|
{
|
||||||
struct simulation_test_params param;
|
struct simulation_test_params param;
|
||||||
|
|
||||||
if (FRAME_TYPE_IS_BEACON(type, subtype) && offset) {
|
if (oper != DELAY && FRAME_TYPE_IS_BEACON(type, subtype) && offset) {
|
||||||
iot_sim_info("Beacon update from offset:%d", offset);
|
iot_sim_info("Beacon update from offset:%d", offset);
|
||||||
return QDF_STATUS_E_NOSUPPORT;
|
return QDF_STATUS_E_NOSUPPORT;
|
||||||
}
|
}
|
||||||
@@ -740,7 +742,8 @@ iot_sim_send_rule_to_fw(struct iot_sim_context *isc,
|
|||||||
QDF_STATUS
|
QDF_STATUS
|
||||||
iot_sim_del_rule(struct iot_sim_rule_per_seq **s_e,
|
iot_sim_del_rule(struct iot_sim_rule_per_seq **s_e,
|
||||||
struct iot_sim_rule **f_e,
|
struct iot_sim_rule **f_e,
|
||||||
enum iot_sim_operations oper)
|
enum iot_sim_operations oper,
|
||||||
|
struct iot_sim_context *isc)
|
||||||
{
|
{
|
||||||
if (oper == CONTENT_CHANGE) {
|
if (oper == CONTENT_CHANGE) {
|
||||||
qdf_mem_free((*f_e)->frm_content);
|
qdf_mem_free((*f_e)->frm_content);
|
||||||
@@ -748,7 +751,31 @@ iot_sim_del_rule(struct iot_sim_rule_per_seq **s_e,
|
|||||||
} else if (oper == DROP) {
|
} else if (oper == DROP) {
|
||||||
(*f_e)->drop = false;
|
(*f_e)->drop = false;
|
||||||
} else if (oper == DELAY) {
|
} else if (oper == DELAY) {
|
||||||
/* TBD */
|
if (!qdf_delayed_work_stop((*f_e)->dwork)) {
|
||||||
|
iot_sim_err("delayed work is in running state");
|
||||||
|
/* iot_sim_lock need to be released for the delay */
|
||||||
|
/* work callback to complete execution */
|
||||||
|
/* Hence releasing the lock */
|
||||||
|
qdf_spin_unlock_bh(&isc->iot_sim_lock);
|
||||||
|
/* iot_sim_delay_lock will be freed only after delay */
|
||||||
|
/* work callback execution completion */
|
||||||
|
qdf_spin_lock_bh(&(*f_e)->iot_sim_delay_lock);
|
||||||
|
qdf_spin_lock_bh(&isc->iot_sim_lock);
|
||||||
|
qdf_delayed_work_stop_sync((*f_e)->dwork);
|
||||||
|
qdf_spin_unlock_bh(&(*f_e)->iot_sim_delay_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_delayed_work_destroy((*f_e)->dwork);
|
||||||
|
qdf_spinlock_destroy(&(*f_e)->iot_sim_delay_lock);
|
||||||
|
qdf_mem_free((*f_e)->dwork->context);
|
||||||
|
qdf_mem_free((*f_e)->dwork);
|
||||||
|
qdf_nbuf_free((*f_e)->nbuf_list[0]);
|
||||||
|
(*f_e)->nbuf_list[0] = NULL;
|
||||||
|
qdf_nbuf_free((*f_e)->nbuf_list[1]);
|
||||||
|
(*f_e)->nbuf_list[1] = NULL;
|
||||||
|
(*f_e)->sec_buf = NULL;
|
||||||
|
qdf_mem_free((*f_e)->rx_param);
|
||||||
|
(*f_e)->rx_param = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qdf_test_bit(oper, (unsigned long *)
|
if (qdf_test_bit(oper, (unsigned long *)
|
||||||
@@ -835,7 +862,7 @@ iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
|
|||||||
f_e = &((*s_e)->rule_per_type[type][subtype]);
|
f_e = &((*s_e)->rule_per_type[type][subtype]);
|
||||||
|
|
||||||
if (*f_e)
|
if (*f_e)
|
||||||
status = iot_sim_del_rule(s_e, f_e, oper);
|
status = iot_sim_del_rule(s_e, f_e, oper, isc);
|
||||||
|
|
||||||
for (i = 0; i < MAX_SEQ; i++)
|
for (i = 0; i < MAX_SEQ; i++)
|
||||||
if (peer->rule_per_seq[i])
|
if (peer->rule_per_seq[i])
|
||||||
@@ -850,6 +877,53 @@ iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* iot_sim_delay_cb - Delayed work callback function
|
||||||
|
* to process delayed frames
|
||||||
|
*
|
||||||
|
* @context: Delayed work callback context
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
static void iot_sim_delay_cb(void *ctxt)
|
||||||
|
{
|
||||||
|
struct wlan_objmgr_psoc *psoc = NULL;
|
||||||
|
struct iot_sim_cb_context *context = ctxt;
|
||||||
|
|
||||||
|
qdf_spin_lock_bh(&context->piot_sim_rule->iot_sim_delay_lock);
|
||||||
|
qdf_spin_lock_bh(&context->isc->iot_sim_lock);
|
||||||
|
psoc = wlan_pdev_get_psoc(context->isc->pdev_obj);
|
||||||
|
context->piot_sim_rule->sec_buf = context->piot_sim_rule->nbuf_list[0];
|
||||||
|
qdf_spin_unlock_bh(&context->isc->iot_sim_lock);
|
||||||
|
mgmt_txrx_rx_handler(psoc, context->piot_sim_rule->sec_buf,
|
||||||
|
context->piot_sim_rule->rx_param);
|
||||||
|
qdf_spin_lock_bh(&context->isc->iot_sim_lock);
|
||||||
|
if (context->piot_sim_rule->nbuf_list[1]) {
|
||||||
|
context->piot_sim_rule->nbuf_list[0] =
|
||||||
|
context->piot_sim_rule->nbuf_list[1];
|
||||||
|
if (!qdf_delayed_work_start(context->piot_sim_rule->dwork,
|
||||||
|
context->
|
||||||
|
piot_sim_rule->delay_dur)) {
|
||||||
|
iot_sim_err("delayed_work_start failed");
|
||||||
|
qdf_nbuf_free(context->piot_sim_rule->nbuf_list[0]);
|
||||||
|
qdf_mem_free(context->piot_sim_rule->
|
||||||
|
rx_param->rx_params);
|
||||||
|
qdf_mem_free(context->piot_sim_rule->rx_param);
|
||||||
|
context->piot_sim_rule->nbuf_list[0] = NULL;
|
||||||
|
context->piot_sim_rule->rx_param = NULL;
|
||||||
|
}
|
||||||
|
context->piot_sim_rule->nbuf_list[1] = NULL;
|
||||||
|
} else {
|
||||||
|
context->piot_sim_rule->nbuf_list[0] = NULL;
|
||||||
|
qdf_mem_free(context->piot_sim_rule->rx_param->rx_params);
|
||||||
|
qdf_mem_free(context->piot_sim_rule->rx_param);
|
||||||
|
context->piot_sim_rule->rx_param = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_spin_unlock_bh(&context->isc->iot_sim_lock);
|
||||||
|
qdf_spin_unlock_bh(&context->piot_sim_rule->iot_sim_delay_lock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* iot_sim_add_rule - function to add iot_sim rule
|
* iot_sim_add_rule - function to add iot_sim rule
|
||||||
*
|
*
|
||||||
@@ -859,6 +933,7 @@ iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
|
|||||||
* @frm: user provided frame content
|
* @frm: user provided frame content
|
||||||
* @offset: user provided offset
|
* @offset: user provided offset
|
||||||
* @len: length of the user provided frame content
|
* @len: length of the user provided frame content
|
||||||
|
* @isc: iot sim context
|
||||||
*
|
*
|
||||||
* Return: QDF_STATUS_SUCCESS
|
* Return: QDF_STATUS_SUCCESS
|
||||||
*/
|
*/
|
||||||
@@ -866,8 +941,11 @@ QDF_STATUS
|
|||||||
iot_sim_add_rule(struct iot_sim_rule_per_seq **s_e,
|
iot_sim_add_rule(struct iot_sim_rule_per_seq **s_e,
|
||||||
struct iot_sim_rule **f_e,
|
struct iot_sim_rule **f_e,
|
||||||
enum iot_sim_operations oper,
|
enum iot_sim_operations oper,
|
||||||
uint8_t *frm, uint16_t offset, uint16_t len)
|
uint8_t *frm, uint16_t offset, uint16_t len,
|
||||||
|
struct iot_sim_context *isc)
|
||||||
{
|
{
|
||||||
|
struct iot_sim_cb_context *cb_context;
|
||||||
|
|
||||||
if (!*f_e) {
|
if (!*f_e) {
|
||||||
*f_e = qdf_mem_malloc(sizeof(struct iot_sim_rule));
|
*f_e = qdf_mem_malloc(sizeof(struct iot_sim_rule));
|
||||||
if (!*f_e) {
|
if (!*f_e) {
|
||||||
@@ -886,7 +964,35 @@ iot_sim_add_rule(struct iot_sim_rule_per_seq **s_e,
|
|||||||
} else if (oper == DROP) {
|
} else if (oper == DROP) {
|
||||||
(*f_e)->drop = true;
|
(*f_e)->drop = true;
|
||||||
} else if (oper == DELAY) {
|
} else if (oper == DELAY) {
|
||||||
/* TBD */
|
(*f_e)->delay_dur = offset;
|
||||||
|
(*f_e)->dwork = qdf_mem_malloc(sizeof(struct qdf_delayed_work));
|
||||||
|
if (!(*f_e)->dwork) {
|
||||||
|
iot_sim_err("can't allocate dwork");
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb_context = qdf_mem_malloc(sizeof(struct iot_sim_cb_context));
|
||||||
|
if (!cb_context) {
|
||||||
|
iot_sim_err("can't allocate cb_context");
|
||||||
|
qdf_mem_free((*f_e)->dwork);
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb_context->isc = isc;
|
||||||
|
cb_context->piot_sim_rule = *f_e;
|
||||||
|
if (QDF_STATUS_SUCCESS !=
|
||||||
|
qdf_delayed_work_create((*f_e)->dwork, iot_sim_delay_cb,
|
||||||
|
cb_context)) {
|
||||||
|
iot_sim_err("delayed_work_create failed");
|
||||||
|
qdf_mem_free(cb_context);
|
||||||
|
qdf_mem_free((*f_e)->dwork);
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*f_e)->nbuf_list[0] = NULL;
|
||||||
|
(*f_e)->nbuf_list[1] = NULL;
|
||||||
|
iot_sim_err("delayed_work_created");
|
||||||
|
qdf_spinlock_create(&((*f_e)->iot_sim_delay_lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
(*s_e)->use_count++;
|
(*s_e)->use_count++;
|
||||||
@@ -919,7 +1025,7 @@ iot_sim_add_rule_for_mac(struct iot_sim_context *isc,
|
|||||||
uint8_t type, uint8_t subtype,
|
uint8_t type, uint8_t subtype,
|
||||||
uint16_t seq, uint16_t offset,
|
uint16_t seq, uint16_t offset,
|
||||||
uint8_t *frm, uint16_t len,
|
uint8_t *frm, uint16_t len,
|
||||||
uint8_t drop, bool action)
|
uint16_t drop, bool action)
|
||||||
{
|
{
|
||||||
QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
||||||
struct iot_sim_rule_per_peer *peer;
|
struct iot_sim_rule_per_peer *peer;
|
||||||
@@ -969,12 +1075,16 @@ iot_sim_add_rule_for_mac(struct iot_sim_context *isc,
|
|||||||
iot_sim_info("Rule addition for " QDF_MAC_ADDR_STR,
|
iot_sim_info("Rule addition for " QDF_MAC_ADDR_STR,
|
||||||
QDF_MAC_ADDR_ARRAY(mac->bytes));
|
QDF_MAC_ADDR_ARRAY(mac->bytes));
|
||||||
|
|
||||||
iot_sim_info("oper:%s seq: %hu %s:%hu/%hu",
|
iot_sim_info("oper:%s seq: %hu %s:%hu/%hu delay:%hu",
|
||||||
iot_sim_oper_to_str(oper), seq,
|
iot_sim_oper_to_str(oper), seq,
|
||||||
action ? "category/action code" : "type/subtype",
|
action ? "category/action code" : "type/subtype",
|
||||||
type, subtype);
|
type, subtype, drop);
|
||||||
|
|
||||||
status = iot_sim_add_rule(s_e, f_e, oper, frm, offset, len);
|
if (oper == DELAY)
|
||||||
|
offset = drop;
|
||||||
|
|
||||||
|
status = iot_sim_add_rule(s_e, f_e, oper, frm,
|
||||||
|
offset, len, isc);
|
||||||
qdf_spin_unlock_bh(&isc->iot_sim_lock);
|
qdf_spin_unlock_bh(&isc->iot_sim_lock);
|
||||||
} else {
|
} else {
|
||||||
/* TBD: clear the rules for peer with address 'mac'*/
|
/* TBD: clear the rules for peer with address 'mac'*/
|
||||||
@@ -1101,6 +1211,93 @@ free:
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* iot_sim_parse_user_input_delay - function to parse user input into
|
||||||
|
* predefined format for delay operation.
|
||||||
|
* All arguments passed will be filled
|
||||||
|
* upon success
|
||||||
|
* @isc: iot sim context
|
||||||
|
* @userbuf: local copy of user input
|
||||||
|
* @count: length of userbuf
|
||||||
|
* @t_st: address of type variable
|
||||||
|
* @seq: address of seq variable
|
||||||
|
* @cat_type: 802.11 action frame category code
|
||||||
|
* @act_type: 802.11 action frame action code
|
||||||
|
* @delay: address of delay variable
|
||||||
|
* @addr: pointer to mac address
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS_SUCCESS on success
|
||||||
|
* QDF_STATUS_E_FAILURE otherwise
|
||||||
|
*/
|
||||||
|
QDF_STATUS
|
||||||
|
iot_sim_parse_user_input_delay(struct iot_sim_context *isc,
|
||||||
|
char *userbuf, ssize_t count,
|
||||||
|
uint8_t *t_st, uint16_t *seq,
|
||||||
|
uint8_t *cat_type, uint8_t *act_type,
|
||||||
|
uint16_t *delay, struct qdf_mac_addr *addr)
|
||||||
|
{
|
||||||
|
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||||
|
char *argv[6], *delim = " ", *substr;
|
||||||
|
int argc = -1, ret = 0;
|
||||||
|
|
||||||
|
qdf_mem_zero(argv, sizeof(argv));
|
||||||
|
userbuf = qdf_str_trim(userbuf);
|
||||||
|
|
||||||
|
while ((substr = qdf_str_sep(&userbuf, delim)) != NULL) {
|
||||||
|
if (!isspace(*substr) && *substr != '\0')
|
||||||
|
argv[++argc] = substr;
|
||||||
|
if (argc >= 5)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
iot_sim_err("Invalid argument count %d", (argc + 1));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!argv[0] || !argv[1] || !argv[2] || !argv[3] || !argv[4]) {
|
||||||
|
iot_sim_err("One or more arguments are null");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* User can send delay data in following format:
|
||||||
|
* 1. Add delay rule for specific peer
|
||||||
|
* <t_st> <seq> <category_type> <action_type> <delay> <MAC>
|
||||||
|
* 2. Remove delay rule for specific peer
|
||||||
|
* <t_st> <seq> <category_type> <action_type> <delay> <MAC>
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = kstrtou8(argv[0], 16, t_st);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
ret = kstrtou16(argv[1], 10, seq);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
ret = kstrtou8(argv[2], 10, cat_type);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
ret = kstrtou8(argv[3], 10, act_type);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
ret = kstrtou16(argv[4], 10, delay);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If argv[5] is valid, this must be mac address
|
||||||
|
*/
|
||||||
|
if (argv[5])
|
||||||
|
status = qdf_mac_parse(argv[5], addr);
|
||||||
|
|
||||||
|
iot_sim_err("delay rule mac address " QDF_MAC_ADDR_STR,
|
||||||
|
QDF_MAC_ADDR_ARRAY(addr->bytes));
|
||||||
|
|
||||||
|
return status;
|
||||||
|
err:
|
||||||
|
iot_sim_err("kstrtoXX failed: %d", ret);
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* iot_sim_debug_delay_write - Write Handler for delay operation
|
* iot_sim_debug_delay_write - Write Handler for delay operation
|
||||||
* @file: debugfs file pointer
|
* @file: debugfs file pointer
|
||||||
@@ -1115,7 +1312,86 @@ iot_sim_debug_delay_write(struct file *file,
|
|||||||
const char __user *buf,
|
const char __user *buf,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
iot_sim_err("delay iot sim ops called");
|
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||||
|
unsigned char t_st, type, subtype;
|
||||||
|
uint16_t seq = 0;
|
||||||
|
char *locbuf = NULL;
|
||||||
|
enum iot_sim_operations oper = DELAY;
|
||||||
|
struct qdf_mac_addr mac_addr = QDF_MAC_ADDR_BCAST_INIT;
|
||||||
|
struct iot_sim_context *isc =
|
||||||
|
((struct seq_file *)file->private_data)->private;
|
||||||
|
uint8_t action = 0, category = 0, tmp[2];
|
||||||
|
bool is_action = false, clear = false;
|
||||||
|
uint16_t delay = 0;
|
||||||
|
|
||||||
|
if ((!buf) || (count > USER_BUF_LEN_DELAY) || (count < 6))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
locbuf = qdf_mem_malloc(USER_BUF_LEN_DELAY + 1);
|
||||||
|
if (!locbuf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (copy_from_user(locbuf, buf, count)) {
|
||||||
|
qdf_mem_free(locbuf);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = iot_sim_parse_user_input_delay(isc, locbuf, count,
|
||||||
|
&t_st, &seq, &category,
|
||||||
|
&action, &delay, &mac_addr);
|
||||||
|
if (QDF_IS_STATUS_ERROR(status)) {
|
||||||
|
iot_sim_err("iot_sim_parse_user_input_delay failed");
|
||||||
|
goto free;
|
||||||
|
}
|
||||||
|
iot_sim_err("Delay rule t_st:%d, seq:%hu cat_type:%d, act_type:%d, delay:%hu",
|
||||||
|
t_st, seq, category, action, delay);
|
||||||
|
|
||||||
|
type = (t_st & IEEE80211_FC0_TYPE_MASK) >> IEEE80211_FC0_TYPE_SHIFT;
|
||||||
|
subtype = (t_st & IEEE80211_FC0_SUBTYPE_MASK);
|
||||||
|
subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
|
||||||
|
|
||||||
|
if (type > N_FRAME_TYPE || subtype > N_FRAME_SUBTYPE || seq > MAX_SEQ)
|
||||||
|
goto free;
|
||||||
|
|
||||||
|
if (FRAME_TYPE_IS_ACTION(type, subtype)) {
|
||||||
|
tmp[0] = category;
|
||||||
|
tmp[1] = action;
|
||||||
|
/*
|
||||||
|
* convert 802.11 category and action code to iot sim codes
|
||||||
|
*/
|
||||||
|
status = iot_sim_get_index_for_action_frm(tmp, &category,
|
||||||
|
&action, false);
|
||||||
|
if (QDF_IS_STATUS_ERROR(status))
|
||||||
|
goto free;
|
||||||
|
|
||||||
|
is_action = 1;
|
||||||
|
type = category;
|
||||||
|
subtype = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear = delay ? false : true;
|
||||||
|
status = iot_sim_send_rule_to_fw(isc, oper, &mac_addr, type, subtype,
|
||||||
|
seq, delay, NULL, 0, is_action, clear);
|
||||||
|
if (QDF_IS_STATUS_SUCCESS(status))
|
||||||
|
goto free;
|
||||||
|
|
||||||
|
/* check for rule removal */
|
||||||
|
if (!delay) {
|
||||||
|
status = iot_sim_delete_rule_for_mac(isc, oper, seq,
|
||||||
|
type, subtype,
|
||||||
|
&mac_addr,
|
||||||
|
is_action);
|
||||||
|
} else {
|
||||||
|
status = iot_sim_add_rule_for_mac(isc, oper, &mac_addr,
|
||||||
|
type, subtype, seq, 0,
|
||||||
|
NULL, 0, delay, is_action);
|
||||||
|
}
|
||||||
|
if (QDF_IS_STATUS_SUCCESS(status))
|
||||||
|
iot_sim_debug("iot_sim: Rule update Delay Operation - Success");
|
||||||
|
else
|
||||||
|
iot_sim_err("iot_sim: Rule update Delay Operation - Fail");
|
||||||
|
free:
|
||||||
|
qdf_mem_free(locbuf);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -77,6 +77,7 @@
|
|||||||
#define MAX_SEQ 0x4
|
#define MAX_SEQ 0x4
|
||||||
#define MAX_PEER_COUNT 0x2
|
#define MAX_PEER_COUNT 0x2
|
||||||
#define MAX_ACTION 0x3
|
#define MAX_ACTION 0x3
|
||||||
|
#define RX_STATUS_SIZE 0x96
|
||||||
#define IOT_SIM_DEBUGFS_FILE_NUM 3
|
#define IOT_SIM_DEBUGFS_FILE_NUM 3
|
||||||
#define FRAME_TYPE_IS_BEACON(type, subtype) ((type) == 0 && (subtype) == 8)
|
#define FRAME_TYPE_IS_BEACON(type, subtype) ((type) == 0 && (subtype) == 8)
|
||||||
#define FRAME_TYPE_IS_ACTION(type, subtype) ((type) == 0 && (subtype) == 13)
|
#define FRAME_TYPE_IS_ACTION(type, subtype) ((type) == 0 && (subtype) == 13)
|
||||||
@@ -113,6 +114,11 @@ struct iot_sim_rule {
|
|||||||
bool drop;
|
bool drop;
|
||||||
uint16_t delay_dur;
|
uint16_t delay_dur;
|
||||||
uint8_t rule_bitmap;
|
uint8_t rule_bitmap;
|
||||||
|
qdf_nbuf_t nbuf_list[2];
|
||||||
|
qdf_nbuf_t sec_buf;
|
||||||
|
struct qdf_delayed_work *dwork;
|
||||||
|
struct mgmt_rx_event_params *rx_param;
|
||||||
|
qdf_spinlock_t iot_sim_delay_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -190,4 +196,9 @@ enum iot_sim_subcmd {
|
|||||||
IOT_SIM_MAX_SUBCMD,
|
IOT_SIM_MAX_SUBCMD,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct iot_sim_cb_context {
|
||||||
|
struct iot_sim_context *isc;
|
||||||
|
struct iot_sim_rule *piot_sim_rule;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _IOT_SIM_DEFS_I_H_ */
|
#endif /* _IOT_SIM_DEFS_I_H_ */
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <wlan_iot_sim_utils_api.h>
|
#include <wlan_iot_sim_utils_api.h>
|
||||||
#include <qdf_module.h>
|
#include <qdf_module.h>
|
||||||
|
#include <qdf_delayed_work.h>
|
||||||
#include "../../core/iot_sim_cmn_api_i.h"
|
#include "../../core/iot_sim_cmn_api_i.h"
|
||||||
#include <wlan_objmgr_pdev_obj.h>
|
#include <wlan_objmgr_pdev_obj.h>
|
||||||
#include <wlan_objmgr_vdev_obj.h>
|
#include <wlan_objmgr_vdev_obj.h>
|
||||||
@@ -198,9 +199,12 @@ iot_sim_apply_content_change_rule(struct wlan_objmgr_pdev *pdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* iot_sim_apply_drop_rule - function to apply drop rule. If set buffer will be
|
* iot_sim_apply_delay_drop_rule - function to apply delay or drop rule.
|
||||||
* freed here and proper return value will be sent to
|
* If drop rule is set, buffer will be freed
|
||||||
* tgt layer.
|
* here and proper return value will be sent to
|
||||||
|
* tgt layer. In case of delay rule, delayed
|
||||||
|
* workqueue will be scheduled for rx frame
|
||||||
|
* processing
|
||||||
*
|
*
|
||||||
* @piot_sim_rule: iot_sim rule structure
|
* @piot_sim_rule: iot_sim rule structure
|
||||||
* @nbuf: skb coming from upper stack
|
* @nbuf: skb coming from upper stack
|
||||||
@@ -209,16 +213,67 @@ iot_sim_apply_content_change_rule(struct wlan_objmgr_pdev *pdev,
|
|||||||
* QDF_STATUS_E_NULL_VALUE, when drop rule is applied
|
* QDF_STATUS_E_NULL_VALUE, when drop rule is applied
|
||||||
*/
|
*/
|
||||||
QDF_STATUS
|
QDF_STATUS
|
||||||
iot_sim_apply_drop_rule(struct iot_sim_rule *piot_sim_rule,
|
iot_sim_apply_delay_drop_rule(struct iot_sim_rule *piot_sim_rule,
|
||||||
qdf_nbuf_t nbuf)
|
qdf_nbuf_t nbuf,
|
||||||
|
struct mgmt_rx_event_params *param)
|
||||||
{
|
{
|
||||||
if (!piot_sim_rule->drop)
|
struct mgmt_rx_event_params *rx_param;
|
||||||
|
|
||||||
|
if (!piot_sim_rule->drop &&
|
||||||
|
!piot_sim_rule->delay_dur)
|
||||||
return QDF_STATUS_E_NOSUPPORT;
|
return QDF_STATUS_E_NOSUPPORT;
|
||||||
|
|
||||||
if (nbuf)
|
if (piot_sim_rule->drop && nbuf) {
|
||||||
qdf_nbuf_free(nbuf);
|
qdf_nbuf_free(nbuf);
|
||||||
|
iot_sim_debug("iot_sim: Drop rule applied");
|
||||||
|
} else if (piot_sim_rule->delay_dur) {
|
||||||
|
if (nbuf == piot_sim_rule->sec_buf) {
|
||||||
|
iot_sim_debug("iot_sim: rx frame process after delay");
|
||||||
|
return QDF_STATUS_E_NOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (piot_sim_rule->nbuf_list[0]) {
|
||||||
|
if (!qdf_delayed_work_stop(piot_sim_rule->
|
||||||
|
dwork)) {
|
||||||
|
piot_sim_rule->nbuf_list[1] = nbuf;
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_nbuf_free(piot_sim_rule->nbuf_list[0]);
|
||||||
|
qdf_mem_free(piot_sim_rule->rx_param->rx_params);
|
||||||
|
qdf_mem_free(piot_sim_rule->rx_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
rx_param = qdf_mem_malloc(sizeof(struct mgmt_rx_event_params));
|
||||||
|
if (!rx_param) {
|
||||||
|
iot_sim_err("rx_param alloc failed");
|
||||||
|
return QDF_STATUS_E_NOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_mem_copy(rx_param, param,
|
||||||
|
sizeof(struct mgmt_rx_event_params));
|
||||||
|
rx_param->rx_params = qdf_mem_malloc(RX_STATUS_SIZE);
|
||||||
|
if (!rx_param->rx_params) {
|
||||||
|
iot_sim_err("rx_param->rx_params alloc failed");
|
||||||
|
qdf_mem_free(rx_param);
|
||||||
|
return QDF_STATUS_E_NOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_mem_copy(rx_param->rx_params,
|
||||||
|
param->rx_params, RX_STATUS_SIZE);
|
||||||
|
piot_sim_rule->rx_param = rx_param;
|
||||||
|
piot_sim_rule->nbuf_list[0] = nbuf;
|
||||||
|
if (!qdf_delayed_work_start(piot_sim_rule->dwork,
|
||||||
|
piot_sim_rule->delay_dur)) {
|
||||||
|
iot_sim_err("delayed_work_start failed");
|
||||||
|
qdf_mem_free(rx_param->rx_params);
|
||||||
|
qdf_mem_free(rx_param);
|
||||||
|
return QDF_STATUS_E_NOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
iot_sim_err("iot_sim: Delay rule applied");
|
||||||
|
}
|
||||||
|
|
||||||
iot_sim_debug("iot_sim: Drop rule applied");
|
|
||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,13 +288,14 @@ iot_sim_apply_drop_rule(struct iot_sim_rule *piot_sim_rule,
|
|||||||
* @nbuf: input packet
|
* @nbuf: input packet
|
||||||
* @param: beacon template cmd parameter
|
* @param: beacon template cmd parameter
|
||||||
* @tx: tx or not
|
* @tx: tx or not
|
||||||
|
* @rx_param: mgmt_rx_event_params
|
||||||
*
|
*
|
||||||
* Return: QDF_STATUS_SUCCESS in general
|
* Return: QDF_STATUS_SUCCESS in general
|
||||||
* QDF_STATUS_E_NOSUPPORT, no content change rule found for this frame
|
* QDF_STATUS_E_NOSUPPORT, no content change rule found for this frame
|
||||||
*/
|
*/
|
||||||
QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
|
QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
|
||||||
struct beacon_tmpl_params *param,
|
struct beacon_tmpl_params *param,
|
||||||
bool tx)
|
bool tx, struct mgmt_rx_event_params *rx_param)
|
||||||
{
|
{
|
||||||
uint8_t type, subtype, seq = 0;
|
uint8_t type, subtype, seq = 0;
|
||||||
struct iot_sim_context *isc;
|
struct iot_sim_context *isc;
|
||||||
@@ -347,9 +403,12 @@ QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
|
|||||||
if (status == QDF_STATUS_E_NOSUPPORT)
|
if (status == QDF_STATUS_E_NOSUPPORT)
|
||||||
goto norule;
|
goto norule;
|
||||||
} else {
|
} else {
|
||||||
status = iot_sim_apply_drop_rule(piot_sim_rule, nbuf);
|
status = iot_sim_apply_delay_drop_rule(piot_sim_rule,
|
||||||
|
nbuf, rx_param);
|
||||||
if (QDF_IS_STATUS_SUCCESS(status))
|
if (QDF_IS_STATUS_SUCCESS(status))
|
||||||
status = QDF_STATUS_E_NULL_VALUE;
|
status = QDF_STATUS_E_NULL_VALUE;
|
||||||
|
else
|
||||||
|
status = QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_spin_unlock_bh(&isc->iot_sim_lock);
|
qdf_spin_unlock_bh(&isc->iot_sim_lock);
|
||||||
|
@@ -39,11 +39,13 @@ struct iot_sim_cbacks {
|
|||||||
* @vdev - vdev object.
|
* @vdev - vdev object.
|
||||||
* @buf - skb
|
* @buf - skb
|
||||||
* @tx - TRUE in case of Tx
|
* @tx - TRUE in case of Tx
|
||||||
|
* @rx_param - mgmt_rx_event_params
|
||||||
*
|
*
|
||||||
* Return : QDF_STATUS_E_SUCCESS/QDF_STATUS_E_FAILURE.
|
* Return : QDF_STATUS_E_SUCCESS/QDF_STATUS_E_FAILURE.
|
||||||
*/
|
*/
|
||||||
QDF_STATUS iot_sim_cmd_handler(struct wlan_objmgr_vdev *vdev, qdf_nbuf_t buf,
|
QDF_STATUS iot_sim_cmd_handler(struct wlan_objmgr_vdev *vdev, qdf_nbuf_t buf,
|
||||||
struct beacon_tmpl_params *param, bool tx);
|
struct beacon_tmpl_params *bcn_param, bool tx,
|
||||||
|
struct mgmt_rx_event_params *param);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wlan_iot_sim_init() - API to init iot_sim component
|
* wlan_iot_sim_init() - API to init iot_sim component
|
||||||
|
@@ -24,11 +24,12 @@
|
|||||||
#define IEEE80211_FRAME_BODY_OFFSET 0x18
|
#define IEEE80211_FRAME_BODY_OFFSET 0x18
|
||||||
|
|
||||||
QDF_STATUS iot_sim_cmd_handler(struct wlan_objmgr_vdev *vdev, qdf_nbuf_t nbuf,
|
QDF_STATUS iot_sim_cmd_handler(struct wlan_objmgr_vdev *vdev, qdf_nbuf_t nbuf,
|
||||||
struct beacon_tmpl_params *param, bool tx)
|
struct beacon_tmpl_params *bcn_param, bool tx,
|
||||||
|
struct mgmt_rx_event_params *param)
|
||||||
{
|
{
|
||||||
struct wlan_objmgr_pdev *pdev = vdev->vdev_objmgr.wlan_pdev;
|
struct wlan_objmgr_pdev *pdev = vdev->vdev_objmgr.wlan_pdev;
|
||||||
|
|
||||||
return iot_sim_frame_update(pdev, nbuf, param, tx);
|
return iot_sim_frame_update(pdev, nbuf, bcn_param, tx, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDF_STATUS iot_sim_register_callbacks(struct wlan_objmgr_pdev *pdev,
|
QDF_STATUS iot_sim_register_callbacks(struct wlan_objmgr_pdev *pdev,
|
||||||
|
@@ -194,7 +194,8 @@ QDF_STATUS iot_sim_mgmt_tx_update(struct wlan_objmgr_psoc *psoc,
|
|||||||
status = rx_ops->iot_sim_rx_ops.iot_sim_cmd_handler(vdev,
|
status = rx_ops->iot_sim_rx_ops.iot_sim_cmd_handler(vdev,
|
||||||
buf,
|
buf,
|
||||||
NULL,
|
NULL,
|
||||||
true);
|
true,
|
||||||
|
NULL);
|
||||||
if (QDF_IS_STATUS_ERROR(status))
|
if (QDF_IS_STATUS_ERROR(status))
|
||||||
mgmt_txrx_err("iot_sim_cmd_handler returned failure");
|
mgmt_txrx_err("iot_sim_cmd_handler returned failure");
|
||||||
}
|
}
|
||||||
|
@@ -946,7 +946,8 @@ static QDF_STATUS simulation_frame_update(struct wlan_objmgr_psoc *psoc,
|
|||||||
if (vdev) {
|
if (vdev) {
|
||||||
status = rx_ops->iot_sim_rx_ops.
|
status = rx_ops->iot_sim_rx_ops.
|
||||||
iot_sim_cmd_handler(vdev, buf,
|
iot_sim_cmd_handler(vdev, buf,
|
||||||
NULL, false);
|
NULL, false,
|
||||||
|
rx_param);
|
||||||
if (status == QDF_STATUS_E_NULL_VALUE) {
|
if (status == QDF_STATUS_E_NULL_VALUE) {
|
||||||
wlan_objmgr_vdev_release_ref(vdev, dbgid);
|
wlan_objmgr_vdev_release_ref(vdev, dbgid);
|
||||||
mgmt_txrx_debug("iot_sim:Pkt processed at RX");
|
mgmt_txrx_debug("iot_sim:Pkt processed at RX");
|
||||||
|
@@ -1447,8 +1447,9 @@ struct iot_sim_cbacks;
|
|||||||
struct wlan_lmac_if_iot_sim_rx_ops {
|
struct wlan_lmac_if_iot_sim_rx_ops {
|
||||||
QDF_STATUS (*iot_sim_cmd_handler)(struct wlan_objmgr_vdev *vdev,
|
QDF_STATUS (*iot_sim_cmd_handler)(struct wlan_objmgr_vdev *vdev,
|
||||||
qdf_nbuf_t n_buf,
|
qdf_nbuf_t n_buf,
|
||||||
struct beacon_tmpl_params *param,
|
struct beacon_tmpl_params *bcn_param,
|
||||||
bool tx);
|
bool tx,
|
||||||
|
struct mgmt_rx_event_params *param);
|
||||||
QDF_STATUS (*iot_sim_register_cb)(struct wlan_objmgr_pdev *pdev,
|
QDF_STATUS (*iot_sim_register_cb)(struct wlan_objmgr_pdev *pdev,
|
||||||
struct iot_sim_cbacks *cb);
|
struct iot_sim_cbacks *cb);
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user