qcacmn: iot_sim add support for drop operation

Adding support for iot_sim drop operation.
Drop operation will be handled in Rx direction.

Change-Id: If2e1c9663a69fcd16715cdd1d28639a388ea1c0c
CRs-Fixed: 2686309
Cette révision appartient à :
nakul kachhwaha
2020-05-15 12:47:26 +05:30
révisé par nshrivas
Parent cb709cad18
révision c5cdd1eaaf
12 fichiers modifiés avec 577 ajouts et 97 suppressions

Voir le fichier

@@ -31,6 +31,15 @@
*
*/
#define USER_BUF_LEN (1 + 2 + 2 + 2 + MAX_BUFFER_SIZE + 6)
/*
* IOT SIM User Buf Format for Drop
* ++++++++++++++++++++++++++++++++++++++++++++++++++++++
* |FrmType/subtype| Seq |category|action| drop |MacAddr|
* ++++++++++++++++++++++++++++++++++++++++++++++++++++++
* | 2Characters |2char| 2chars |2chars| 1char|17chars|
*
*/
#define USER_BUF_LEN_DROP (2 + 2 + 2 + 2 + 1 + 17)
/**
* wlan_iot_sim_pdev_obj_create_handler() - handler for pdev object create
@@ -80,6 +89,7 @@ QDF_STATUS iot_sim_get_index_for_action_frm(uint8_t *frm, uint8_t *cat,
* iot_sim_frame_update() - Management frame update
* @pdev: reference to global pdev object
* @nbuf: frame buffer
* @direction: direction tx or rx
*
* This function updates the outgoing management frame with
* the content stored in iot_sim_context.
@@ -87,7 +97,8 @@ QDF_STATUS iot_sim_get_index_for_action_frm(uint8_t *frm, uint8_t *cat,
* Return: QDF_STATUS_SUCCESS on success
* QDF_STATUS_E_FAILURE on failure
*/
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, bool direction);
/*
* iot_sim_get_ctx_from_pdev() - API to get iot_sim context object

Voir le fichier

@@ -20,6 +20,7 @@
#include <qdf_mem.h>
#include <qdf_types.h>
#include <qdf_util.h>
#include <qdf_str.h>
#include <wmi_unified_param.h>
/*
@@ -267,9 +268,9 @@ iot_sim_parse_user_input_content_change(struct iot_sim_context *isc,
int argc = -1, ret = 0;
qdf_mem_zero(argv, sizeof(argv));
userbuf = strim(userbuf);
userbuf = qdf_str_trim(userbuf);
while ((substr = strsep(&userbuf, delim)) != NULL) {
while ((substr = qdf_str_sep(&userbuf, delim)) != NULL) {
if (!isspace(*substr) && *substr != '\0')
argv[++argc] = substr;
if (argc >= 5)
@@ -360,6 +361,17 @@ err:
return status;
}
/*
* iot_sim_get_index_for_action_frm - function to convert 802.11 action frame
* category and action code into iot sim
* specific code.
*
* @frm: buf containing 802.11 action/category codes
* @cat_type: buf to hold converted category code
* @act_type: buf to hold converted action code
*
* Return: QDF_STATUS_SUCCESS on success, failure otherwise
*/
QDF_STATUS
iot_sim_get_index_for_action_frm(uint8_t *frm, uint8_t *cat_type,
uint8_t *act_type)
@@ -405,6 +417,30 @@ iot_sim_get_index_for_action_frm(uint8_t *frm, uint8_t *cat_type,
return QDF_STATUS_SUCCESS;
}
/*
* iot_sim_action_frame_supported_by_fw - function to find if action frame is
* supported by fw or not
* @category: iot_sim specific category code
* @action: iot_sim specific action code
*
* Return: true if supported else false
*/
bool
iot_sim_action_frame_supported_by_fw(uint8_t category, uint8_t action)
{
switch (category) {
case IEEE80211_ACTION_CAT_BA:
switch (action) {
case IEEE80211_ACTION_BA_ADDBA_REQUEST:
return true;
default:
return false;
}
default:
return false;
}
}
/*
* iot_sim_frame_supported_by_fw - function to find if frame is supported by fw
* @type: 802.11 frame type
@@ -413,8 +449,11 @@ iot_sim_get_index_for_action_frm(uint8_t *frm, uint8_t *cat_type,
* Return: true if supported else false
*/
bool
iot_sim_frame_supported_by_fw(uint8_t type, uint8_t subtype)
iot_sim_frame_supported_by_fw(uint8_t type, uint8_t subtype, bool action)
{
if (action)
return iot_sim_action_frame_supported_by_fw(type, subtype);
switch (type << IEEE80211_FC0_TYPE_SHIFT) {
case IEEE80211_FC0_TYPE_MGT:
switch (subtype << IEEE80211_FC0_SUBTYPE_SHIFT) {
@@ -444,6 +483,74 @@ iot_sim_frame_supported_by_fw(uint8_t type, uint8_t subtype)
}
}
/*
* iot_sim_remap_type_subtype - function to convert rules for response
* type frame into request type. This is
* used for drop/delay operation. This function
* will update the passed type and subtype value.
*
* @type: 802.11 frame type
* @subtype: 802.11 frame subtype
* @seq: authentication sequence number, mostly 0 for non-authentication frame
* @action: flag to indicate action frame
*
* Return: QDF_STATUS_SUCCESS
*/
QDF_STATUS
iot_sim_remap_type_subtype(uint8_t *type, uint8_t *subtype,
uint16_t *seq, bool action)
{
if (action) {
switch (*type) {
case CAT_BA:
switch (*subtype) {
case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
*subtype = IEEE80211_ACTION_BA_ADDBA_REQUEST;
break;
default:
break;
}
break;
default:
break;
}
return QDF_STATUS_SUCCESS;
}
switch (*type << IEEE80211_FC0_TYPE_SHIFT) {
case IEEE80211_FC0_TYPE_MGT:
switch (*subtype << IEEE80211_FC0_SUBTYPE_SHIFT) {
case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
*subtype = IEEE80211_FC0_SUBTYPE_ASSOC_REQ;
*subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
break;
case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
*subtype = IEEE80211_FC0_SUBTYPE_REASSOC_REQ;
*subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
break;
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
*subtype = IEEE80211_FC0_SUBTYPE_PROBE_REQ;
*subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
break;
case IEEE80211_FC0_SUBTYPE_AUTH:
*subtype = IEEE80211_FC0_SUBTYPE_AUTH;
*subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
/* If auth response (auth seq num 2) is marked as
* drop, then drop the auth request (auth seq num 1)
*/
if (*seq == IEEE80211_AUTH_OPEN_RESPONSE)
*seq = IEEE80211_AUTH_OPEN_REQUEST;
break;
default:
break;
}
default:
break;
}
return QDF_STATUS_SUCCESS;
}
/*
* iot_sim_send_rule_to_fw - function to send iot_sim rule to fw
*
@@ -456,6 +563,8 @@ iot_sim_frame_supported_by_fw(uint8_t type, uint8_t subtype)
* @offset: user provided offset
* @frm: user provided frame content
* @length: length of frm
* @action: flag to indicate action frame
* @drop: flag to indicate set drop rule
* @clear: flag to indicate set rule or clear
*
* Return: QDF_STATUS_SUCCESS
@@ -466,20 +575,30 @@ iot_sim_send_rule_to_fw(struct iot_sim_context *isc,
struct qdf_mac_addr *mac,
uint8_t type, uint8_t subtype,
uint16_t seq, uint16_t offset,
uint8_t *frm, uint16_t len, bool clear)
uint8_t *frm, uint16_t len,
bool action, bool clear)
{
struct simulation_test_params param;
if (iot_sim_frame_supported_by_fw(type, subtype)) {
if (iot_sim_frame_supported_by_fw(type, subtype, action)) {
qdf_mem_zero(&param, sizeof(struct simulation_test_params));
param.pdev_id = wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj);
qdf_mem_copy(param.peer_mac, mac, QDF_MAC_ADDR_SIZE);
param.test_cmd_type = oper;
/* subtype_cmd: Rule:- set:0 clear:1 */
param.test_subcmd_type = clear;
/* subtype_cmd: Set subcmd based on action and clear flag */
if (action) {
if (clear)
param.test_subcmd_type = DEL_RULE_ACTION;
else
param.test_subcmd_type = ADD_RULE_ACTION;
} else {
if (clear)
param.test_subcmd_type = DEL_RULE;
else
param.test_subcmd_type = ADD_RULE;
}
param.frame_type = type;
param.frame_subtype = subtype;
param.seq = seq;
param.offset = offset;
param.frame_length = len;
@@ -514,14 +633,18 @@ iot_sim_del_rule(struct iot_sim_rule_per_seq **s_e,
qdf_mem_free((*f_e)->frm_content);
(*f_e)->frm_content = NULL;
} else if (oper == DROP) {
/* TBD */
(*f_e)->drop = false;
} else if (oper == DELAY) {
/* TBD */
}
if (qdf_test_bit(oper, (unsigned long *)
&(*f_e)->rule_bitmap)) {
(*s_e)->use_count--;
qdf_clear_bit(oper, (unsigned long *)
&(*f_e)->rule_bitmap);
}
if (!(*f_e)->rule_bitmap) {
qdf_mem_free(*f_e);
*f_e = NULL;
@@ -575,6 +698,9 @@ iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
return QDF_STATUS_E_FAILURE;
}
if (oper == DROP || oper == DELAY)
iot_sim_remap_type_subtype(&type, &subtype, &seq, action);
peer = iot_sim_find_peer_from_mac(isc, mac);
if (peer) {
qdf_spin_lock(&peer->iot_sim_lock);
@@ -631,7 +757,7 @@ iot_sim_add_rule(struct iot_sim_rule_per_seq **s_e,
(*f_e)->len = len;
(*f_e)->offset = offset;
} else if (oper == DROP) {
/* TBD */
(*f_e)->drop = true;
} else if (oper == DELAY) {
/* TBD */
}
@@ -666,7 +792,7 @@ iot_sim_add_rule_for_mac(struct iot_sim_context *isc,
uint8_t type, uint8_t subtype,
uint16_t seq, uint16_t offset,
uint8_t *frm, uint16_t len,
bool action)
uint8_t drop, bool action)
{
QDF_STATUS status = QDF_STATUS_E_FAILURE;
struct iot_sim_rule_per_peer *peer;
@@ -686,6 +812,9 @@ iot_sim_add_rule_for_mac(struct iot_sim_context *isc,
return status;
}
if (oper == DROP || oper == DELAY)
iot_sim_remap_type_subtype(&type, &subtype, &seq, action);
peer = iot_sim_find_peer_from_mac(isc, mac);
if (peer) {
qdf_spin_lock(&peer->iot_sim_lock);
@@ -800,7 +929,8 @@ iot_sim_debug_content_change_write(struct file *file,
clear = length ? false : true;
status = iot_sim_send_rule_to_fw(isc, oper, &mac_addr, type, subtype,
seq, offset, content, length, clear);
seq, offset, content, length,
is_action, clear);
if (QDF_IS_STATUS_SUCCESS(status))
goto free;
@@ -814,7 +944,8 @@ iot_sim_debug_content_change_write(struct file *file,
} else {
status = iot_sim_add_rule_for_mac(isc, oper, &mac_addr,
type, subtype, seq, offset,
content, length, is_action);
content, length, 0,
is_action);
}
if (QDF_IS_STATUS_SUCCESS(status))
iot_sim_err("iot_sim: Content Change Operation - success");
@@ -845,6 +976,96 @@ iot_sim_debug_delay_write(struct file *file,
return count;
}
/*
* iot_sim_parse_user_input_drop - function to parse user input into
* predefined format for drop 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
* @drop: address of drop variable to specify drop the frame or not
* @addr: pointer to mac address
*
* Return: QDF_STATUS_SUCCESS on success
* QDF_STATUS_E_FAILURE otherwise
*/
QDF_STATUS
iot_sim_parse_user_input_drop(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,
uint8_t *drop, 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 drop data in following format:
* 1. Add drop rule for specific peer
* <t_st> <seq> <category_type> <action_type> <drop> <MAC>
* 2. Add drop rule for broadcast peer
* <t_st> <seq> <category_type> <action_type> <drop>
* 3. Remove drop rule for specific peer
* <t_st> <seq> <category_type> <action_type> <drop> <MAC>
* 4. Remove drop rule for broadcast peer
* <t_st> <seq> <category_type> <action_type> <drop> <BCAST_MAC>
* 5. Remove drop rule for all peer
* <t_st> <seq> <category_type> <action_type> <drop>
*/
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 = kstrtou8(argv[4], 10, drop);
if (ret)
goto err;
/*
* If argv[5] is valid, this must be mac address
*/
if (argv[5])
status = qdf_mac_parse(argv[5], addr);
return status;
err:
iot_sim_err("kstrtoXX failed: %d", ret);
return QDF_STATUS_E_FAILURE;
}
/*
* iot_sim_debug_drop_write - Write Handler for drop operation
* @file: debugfs file pointer
@@ -859,7 +1080,81 @@ iot_sim_debug_drop_write(struct file *file,
const char __user *buf,
size_t count, loff_t *ppos)
{
iot_sim_err("drop 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 = DROP;
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], drop = 0;
bool is_action = false, clear = false;
if ((!buf) || (count > USER_BUF_LEN_DROP) || (count < 6))
return -EFAULT;
locbuf = qdf_mem_malloc(USER_BUF_LEN_DROP + 1);
if (!locbuf)
return -ENOMEM;
if (copy_from_user(locbuf, buf, count)) {
qdf_mem_free(locbuf);
return -EFAULT;
}
status = iot_sim_parse_user_input_drop(isc, locbuf, count,
&t_st, &seq, &category,
&action, &drop, &mac_addr);
if (QDF_IS_STATUS_ERROR(status))
goto free;
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);
if (QDF_IS_STATUS_ERROR(status))
goto free;
is_action = 1;
type = category;
subtype = action;
}
clear = drop ? false : true;
status = iot_sim_send_rule_to_fw(isc, oper, &mac_addr, type, subtype,
seq, 0, NULL, 0, is_action, clear);
if (QDF_IS_STATUS_SUCCESS(status))
goto free;
/* check for rule removal */
if (!drop) {
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, drop, is_action);
}
if (QDF_IS_STATUS_SUCCESS(status))
iot_sim_debug("iot_sim: Rule update Drop Operation - Success");
else
iot_sim_err("iot_sim: Rule update Drop Operation - Fail");
free:
qdf_mem_free(locbuf);
return count;
}

Voir le fichier

@@ -164,11 +164,26 @@ struct iot_sim_context {
* @IOT_SIM_MAX_OPERATION - iot sim max operation
*/
enum iot_sim_operations {
INVALID_OPERATION,
CONTENT_CHANGE = 1,
CONTENT_CHANGE,
DROP,
DELAY,
IOT_SIM_MAX_OPERATION
};
/* enum iot_sim_subcmd - iot sim FW related subcommands
*
* @ADD_RULE - Add Rule
* @DEL_RULE - Delete Rule
* @ADD_RULE_ACTION - Add rule for action frame
* @DEL_RULE_ACTION - Del rule for action frame
* @IOT_SIM_MAX_SUBCMD - iot sim max subcmd
*/
enum iot_sim_subcmd {
ADD_RULE = 0,
DEL_RULE,
ADD_RULE_ACTION,
DEL_RULE_ACTION,
IOT_SIM_MAX_SUBCMD,
};
#endif /* _IOT_SIM_DEFS_I_H_ */

Voir le fichier

@@ -22,78 +22,31 @@
#define IEEE80211_FRAME_BODY_OFFSET 0x18
QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf)
{
uint8_t type, subtype, seq = 0;
struct iot_sim_context *isc;
uint8_t *buf = qdf_nbuf_data(nbuf), *frm = NULL;
int fixed_param_length = 0;
bool is_action_frm = false;
uint8_t cat, cat_index;
int auth_seq_index = 0, offset = 0;
struct iot_sim_rule *piot_sim_rule = NULL;
qdf_size_t buf_len = 0;
type = (buf[0] & IEEE80211_FC0_TYPE_MASK) >> IEEE80211_FC0_TYPE_SHIFT;
subtype = (buf[0] & IEEE80211_FC0_SUBTYPE_MASK);
isc = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_IOT_SIM_COMP);
if (!isc) {
iot_sim_err("pdev IOT_SIM object is NULL!");
return QDF_STATUS_SUCCESS;
}
if (type == IEEE80211_FC0_TYPE_MGT &&
subtype == IEEE80211_FC0_SUBTYPE_AUTH) {
/* Authentication frame */
auth_seq_index = IEEE80211_FRAME_BODY_OFFSET + 2;
seq = le16toh(*(u_int16_t *)(buf + auth_seq_index));
} else if (type == IEEE80211_FC0_TYPE_MGT &&
subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
/* Probe response frame */
fixed_param_length = 12;
else if (type == IEEE80211_FC0_TYPE_MGT &&
(subtype == IEEE80211_FC0_SUBTYPE_ASSOC_RESP ||
subtype == IEEE80211_FC0_SUBTYPE_REASSOC_RESP))
/* Assoc/Reassoc response frame */
fixed_param_length = 6;
else if (type == IEEE80211_FC0_TYPE_MGT &&
subtype == IEEE80211_FC0_SUBTYPE_ACTION) {
/* Action frame */
frm = buf + IEEE80211_FRAME_BODY_OFFSET;
is_action_frm = true;
if (iot_sim_get_index_for_action_frm(frm, &cat, &cat_index)) {
iot_sim_err("get_index_for_action_frm failed");
return QDF_STATUS_SUCCESS;
}
}
subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
iot_sim_debug("iot_sim: Change content operation for frame");
iot_sim_debug("type:%d subtype:%d seq:%d, is_action_frm: %u",
type, subtype, seq, is_action_frm);
/* Only broadcast peer is getting handled right now.
* Need to add support for peer based content modification
/*
* iot_sim_apply_content_change_rule - function to apply content change rule
* packet from upper stack will be modified
* as per the user content.
* @piot_sim_rule: iot_sim rule structure
* @nbuf: skb coming from upper stack
* @fixed_param_length: length of fixed parameters in frame body
*
* Return: QDF_STATUS_SUCCESS on successful content update or otherwise
* QDF_STATUS_E_NOSUPPORT, no content change rule found for this frame
*/
qdf_spin_lock(&isc->bcast_peer.iot_sim_lock);
if (!isc->bcast_peer.rule_per_seq[seq])
goto norule;
buf_len = qdf_nbuf_len(nbuf);
if (is_action_frm)
piot_sim_rule = isc->bcast_peer.rule_per_seq[seq]->
rule_per_action_frm[cat][cat_index];
else
piot_sim_rule = isc->bcast_peer.rule_per_seq[seq]->
rule_per_type[type][subtype];
if (!piot_sim_rule)
goto norule;
QDF_STATUS
iot_sim_apply_content_change_rule(struct iot_sim_rule *piot_sim_rule,
qdf_nbuf_t nbuf,
int fixed_param_length)
{
uint8_t *buf = NULL;
qdf_size_t buf_len = 0;
int offset = 0;
if (!piot_sim_rule->frm_content || !piot_sim_rule->len)
goto norule;
return QDF_STATUS_E_NOSUPPORT;
buf_len = qdf_nbuf_len(nbuf);
buf = qdf_nbuf_data(nbuf);
if (piot_sim_rule->offset ==
IEEE80211_FRAME_BODY_OFFSET) {
@@ -122,8 +75,133 @@ QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf)
} else {
iot_sim_err("Failed to modify content");
}
qdf_spin_unlock(&isc->bcast_peer.iot_sim_lock);
return QDF_STATUS_SUCCESS;
}
/*
* iot_sim_apply_drop_rule - function to apply drop rule. If set buffer will be
* freed here and proper return value will be sent to
* tgt layer.
*
* @piot_sim_rule: iot_sim rule structure
* @nbuf: skb coming from upper stack
*
* Return: QDF_STATUS_SUCCESS on successful drop
* QDF_STATUS_E_NULL_VALUE, when drop rule is applied
*/
QDF_STATUS
iot_sim_apply_drop_rule(struct iot_sim_rule *piot_sim_rule,
qdf_nbuf_t nbuf)
{
if (!piot_sim_rule->drop)
return QDF_STATUS_E_NOSUPPORT;
if (nbuf)
qdf_nbuf_free(nbuf);
iot_sim_debug("iot_sim: Drop rule applied");
return QDF_STATUS_SUCCESS;
}
/*
* iot_sim_frame_update - Function to parse input packet coming from upper
* stack in Tx direction and to tgt layer in Rx
* direction. This function will also check if rule
* for that frame type/subtype is set or not and call
* specific operation functions.
*
* @pdev: pdev object
* @nbuf: input packet
* @direction: direction to specify from where this packet is arrived
*
* Return: QDF_STATUS_SUCCESS in general
* 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,
bool tx)
{
uint8_t type, subtype, seq = 0;
struct iot_sim_context *isc;
uint8_t *buf = qdf_nbuf_data(nbuf), *frm = NULL;
int fixed_param_length = 0;
bool is_action_frm = false;
uint8_t cat, cat_index;
int auth_seq_index = 0;
struct iot_sim_rule *piot_sim_rule = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS;
isc = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_IOT_SIM_COMP);
if (!isc) {
iot_sim_err("pdev IOT_SIM object is NULL!");
return QDF_STATUS_SUCCESS;
}
type = (buf[0] & IEEE80211_FC0_TYPE_MASK) >> IEEE80211_FC0_TYPE_SHIFT;
subtype = (buf[0] & IEEE80211_FC0_SUBTYPE_MASK);
if (type == IEEE80211_FC0_TYPE_MGT &&
subtype == IEEE80211_FC0_SUBTYPE_AUTH) {
/* Authentication frame */
auth_seq_index = IEEE80211_FRAME_BODY_OFFSET + 2;
seq = le16toh(*(u_int16_t *)(buf + auth_seq_index));
} else if (type == IEEE80211_FC0_TYPE_MGT &&
subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
/* Probe response frame */
fixed_param_length = 12;
else if (type == IEEE80211_FC0_TYPE_MGT &&
(subtype == IEEE80211_FC0_SUBTYPE_ASSOC_RESP ||
subtype == IEEE80211_FC0_SUBTYPE_REASSOC_RESP))
/* Assoc/Reassoc response frame */
fixed_param_length = 6;
else if (type == IEEE80211_FC0_TYPE_MGT &&
subtype == IEEE80211_FC0_SUBTYPE_ACTION) {
/* Action frame */
frm = buf + IEEE80211_FRAME_BODY_OFFSET;
is_action_frm = true;
if (iot_sim_get_index_for_action_frm(frm, &cat, &cat_index)) {
iot_sim_err("get_index_for_action_frm failed");
return QDF_STATUS_SUCCESS;
}
}
subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
iot_sim_debug("iot_sim: type:%d subtype:%d seq:%d, action:%u dir:%s",
type, subtype, seq, is_action_frm,
tx ? "TX" : "RX");
/* Only broadcast peer is getting handled right now.
* Need to add support for peer based content modification
*/
qdf_spin_lock(&isc->bcast_peer.iot_sim_lock);
if (!isc->bcast_peer.rule_per_seq[seq])
goto norule;
if (is_action_frm)
piot_sim_rule = isc->bcast_peer.rule_per_seq[seq]->
rule_per_action_frm[cat][cat_index];
else
piot_sim_rule = isc->bcast_peer.rule_per_seq[seq]->
rule_per_type[type][subtype];
if (!piot_sim_rule)
goto norule;
if (tx) {
status = iot_sim_apply_content_change_rule(piot_sim_rule,
nbuf,
fixed_param_length);
if (status == QDF_STATUS_E_NOSUPPORT)
goto norule;
} else {
status = iot_sim_apply_drop_rule(piot_sim_rule, nbuf);
if (QDF_IS_STATUS_SUCCESS(status))
status = QDF_STATUS_E_NULL_VALUE;
}
qdf_spin_unlock(&isc->bcast_peer.iot_sim_lock);
return status;
norule:
iot_sim_debug("Rule not set for this frame");

Voir le fichier

@@ -28,10 +28,12 @@ struct wmi_iot_sim_cmd_ops;
* iot_sim_cmd_handler() - IOT SIM frame handler function
* @vdev - vdev object.
* @buf - skb
* @tx - TRUE in case of Tx
*
* 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,
bool tx);
/**
* wlan_iot_sim_init() - API to init iot_sim component

Voir le fichier

@@ -23,11 +23,12 @@
#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,
bool tx)
{
struct wlan_objmgr_pdev *pdev = vdev->vdev_objmgr.wlan_pdev;
return iot_sim_frame_update(pdev, nbuf);
return iot_sim_frame_update(pdev, nbuf, tx);
}
QDF_STATUS

Voir le fichier

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2018-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
@@ -170,4 +170,16 @@ qdf_str_ncmp(const char *str1, const char *str2, qdf_size_t limit)
return __qdf_str_ncmp(str1, str2, limit);
}
/**
* qdf_str_sep - extract token from string
* @str: String buffer
* @delim: Delimitter
* Return: Pointer to the first token
*
*/
static inline char *qdf_str_sep(char **str, char *delim)
{
return __qdf_str_sep(str, delim);
}
#endif /* __QDF_STR_H */

Voir le fichier

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2018-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
@@ -34,5 +34,6 @@
#define __qdf_str_trim(str) strim(str)
#define __qdf_str_nlen(str, limit) strnlen(str, limit)
#define __qdf_str_ncmp(left, right, limit) strncmp(left, right, limit)
#define __qdf_str_sep(buf, delim) strsep(buf, delim)
#endif /* __I_QDF_STR_H */

Voir le fichier

@@ -191,7 +191,9 @@ QDF_STATUS iot_sim_mgmt_tx_update(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_E_NULL_VALUE;
}
if (rx_ops->iot_sim_rx_ops.iot_sim_cmd_handler) {
status = rx_ops->iot_sim_rx_ops.iot_sim_cmd_handler(vdev, buf);
status = rx_ops->iot_sim_rx_ops.iot_sim_cmd_handler(vdev,
buf,
true);
if (QDF_IS_STATUS_ERROR(status))
mgmt_txrx_err("iot_sim_cmd_handler returned failure");
}

Voir le fichier

@@ -908,6 +908,63 @@ mgmt_txrx_get_frm_type(uint8_t mgmt_subtype, uint8_t *mpdu_data_ptr)
return frm_type;
}
#ifdef WLAN_IOT_SIM_SUPPORT
static QDF_STATUS simulation_frame_update(struct wlan_objmgr_psoc *psoc,
qdf_nbuf_t buf,
struct mgmt_rx_event_params *rx_param)
{
uint8_t *addr = NULL;
struct wlan_objmgr_vdev *vdev = NULL;
uint8_t pdevid = 0;
wlan_objmgr_ref_dbgid dbgid;
struct wlan_lmac_if_rx_ops *rx_ops = NULL;
struct wlan_objmgr_pdev *pdev;
struct ieee80211_frame *wh;
u_int8_t *data;
QDF_STATUS status = QDF_STATUS_SUCCESS;
rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
if (rx_ops && rx_ops->iot_sim_rx_ops.iot_sim_cmd_handler) {
data = (uint8_t *)qdf_nbuf_data(buf);
wh = (struct ieee80211_frame *)data;
addr = (uint8_t *)wh->i_addr3;
pdevid = rx_param->pdev_id;
dbgid = WLAN_IOT_SIM_ID;
if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)addr)) {
pdev = wlan_objmgr_get_pdev_by_id(psoc, pdevid,
dbgid);
if (pdev) {
vdev = wlan_objmgr_pdev_get_first_vdev(pdev,
dbgid);
wlan_objmgr_pdev_release_ref(pdev, dbgid);
}
} else
vdev = wlan_objmgr_get_vdev_by_macaddr_from_psoc(psoc,
pdevid,
addr,
dbgid);
if (vdev) {
status = rx_ops->iot_sim_rx_ops.
iot_sim_cmd_handler(vdev, buf, false);
if (status == QDF_STATUS_E_NULL_VALUE) {
wlan_objmgr_vdev_release_ref(vdev, dbgid);
mgmt_txrx_debug("iot_sim:Pkt processed at RX");
return status;
}
wlan_objmgr_vdev_release_ref(vdev, dbgid);
}
}
return status;
}
#else
static QDF_STATUS simulation_frame_update(struct wlan_objmgr_psoc *psoc,
qdf_nbuf_t buf,
struct mgmt_rx_event_params *rx_param)
{
return QDF_STATUS_SUCCESS;
}
#endif
/**
* wlan_mgmt_txrx_rx_handler_list_copy() - copies rx handler list
* @rx_handler: pointer to rx handler list
@@ -1084,6 +1141,9 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler(
WLAN_SEQ_SEQ_SHIFT), mgmt_rx_params->rssi,
mgmt_rx_params->tsf_delta);
if (simulation_frame_update(psoc, buf, mgmt_rx_params))
return QDF_STATUS_E_FAILURE;
mgmt_txrx_psoc_ctx = (struct mgmt_txrx_priv_psoc_context *)
wlan_objmgr_psoc_get_comp_private_obj(psoc,
WLAN_UMAC_COMP_MGMT_TXRX);

Voir le fichier

@@ -267,6 +267,7 @@ typedef void (*wlan_objmgr_peer_status_handler)(
* @FTM_TIME_SYNC_ID: ftm time sync operations
* @WLAN_PKT_CAPTURE_ID Packet capture operations
* @WLAN_DCS_ID: DCS operations
* @WLAN_IOT_SIM_ID: IOT Simulation feature
* @WLAN_REF_ID_MAX: Max id used to generate ref count tracking array
*/
/* New value added to the enum must also be reflected in function
@@ -349,6 +350,7 @@ typedef enum {
FTM_TIME_SYNC_ID = 73,
WLAN_PKT_CAPTURE_ID = 74,
WLAN_DCS_ID = 75,
WLAN_IOT_SIM_ID = 76,
WLAN_REF_ID_MAX,
} wlan_objmgr_ref_dbgid;
@@ -437,7 +439,8 @@ static inline const char *string_from_dbgid(wlan_objmgr_ref_dbgid id)
"WLAN_PSOC_TARGET_IF_ID",
"FTM_TIME_SYNC_ID",
"WLAN_PKT_CAPTURE_ID",
"WLAN_DCS_ID"};
"WLAN_DCS_ID",
"WLAN_IOT_SIM_ID"};
if (id >= WLAN_REF_ID_MAX)
return "Unknown";

Voir le fichier

@@ -1424,7 +1424,7 @@ struct wlan_lmac_if_sptrl_rx_ops {
**/
struct wlan_lmac_if_iot_sim_rx_ops {
QDF_STATUS (*iot_sim_cmd_handler)(struct wlan_objmgr_vdev *vdev,
qdf_nbuf_t n_buf);
qdf_nbuf_t n_buf, bool tx);
};
#endif