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 à :

révisé par
nshrivas

Parent
cb709cad18
révision
c5cdd1eaaf
@@ -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
|
||||
|
@@ -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(¶m, 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;
|
||||
}
|
||||
|
||||
|
@@ -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_ */
|
||||
|
@@ -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");
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -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 */
|
||||
|
@@ -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");
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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";
|
||||
|
@@ -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
|
||||
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur