diff options
| author | Rajeev Kumar Sirasanagandla <rsirasan@codeaurora.org> | 2017-01-25 14:45:44 +0530 |
|---|---|---|
| committer | Hanumanth Reddy Pothula <c_hpothu@codeaurora.org> | 2017-02-13 14:42:46 +0530 |
| commit | 60eb9a3c5781a35f1c1cecbf3bffe0f6ff337f6b (patch) | |
| tree | f1819182398ba0bad3a44894bed5daeba1a35296 | |
| parent | 8ac94bda17763849c50e3dd289a3f85b884e89cc (diff) | |
qcacld-2.0: Randomize sa of action frames
This change add support to randomize source address of action frames
for improving user privacy.
Change-Id: I5a5b245677d968983705692a5e510bef121e089f
CRs-Fixed: 1102831
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_main.h | 63 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_p2p.h | 16 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg80211.c | 24 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_main.c | 35 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_p2p.c | 554 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 28 | ||||
| -rw-r--r-- | CORE/MAC/src/include/sirParams.h | 1 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 160 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.h | 2 | ||||
| -rw-r--r-- | CORE/SME/inc/sme_Api.h | 34 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 94 | ||||
| -rw-r--r-- | CORE/SYS/legacy/src/utils/src/macTrace.c | 1 | ||||
| -rw-r--r-- | CORE/WDA/inc/wlan_qct_wda.h | 1 |
13 files changed, 1010 insertions, 3 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index a5601e1a0589..4c0ca17cd175 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -152,6 +152,8 @@ #define WLAN_WAIT_TIME_CHAIN_RSSI 1000 +#define WLAN_WAIT_TIME_SET_RND 100 + #define MAX_NUMBER_OF_ADAPTERS 4 #define MAX_CFG_STRING_LEN 255 @@ -284,6 +286,12 @@ typedef enum } scan_reject_states; /* + * Maximum no.of random mac addresses supported by firmware + * for transmitting management action frames + */ +#define MAX_RANDOM_MAC_ADDRS 16 + +/* * Generic asynchronous request/response support * * Many of the APIs supported by HDD require a call to SME to @@ -331,6 +339,20 @@ struct linkspeedContext unsigned int magic; }; +/** + * struct random_mac_context - Context used with hdd_random_mac_callback + * @random_mac_completion: Event on which hdd_set_random_mac will wait + * @adapter: Pointer to adapter + * @magic: For valid context this is set to ACTION_FRAME_RANDOM_CONTEXT_MAGIC + * @set_random_addr: Status of random filter set + */ +struct random_mac_context { + struct completion random_mac_completion; + hdd_adapter_t *adapter; + unsigned int magic; + bool set_random_addr; +}; + extern spinlock_t hdd_context_lock; #define STATS_CONTEXT_MAGIC 0x53544154 //STAT @@ -343,6 +365,7 @@ extern spinlock_t hdd_context_lock; #define FW_STATUS_MAGIC 0x46575354 /* FWSTATUS(FWST) */ #define POWER_STATS_MAGIC 0x14111990 #define BPF_CONTEXT_MAGIC 0x4575354 /* BPF */ +#define ACTION_FRAME_RANDOM_CONTEXT_MAGIC 0x87878787 #ifdef QCA_LL_TX_FLOW_CT /* MAX OS Q block time value in msec @@ -736,6 +759,28 @@ struct hdd_mon_set_ch_info { eCsrPhyMode phy_mode; }; +/** + * struct action_frame_cookie - Action frame cookie item in cookie list + * @cookie_node: List item + * @cookie: Cookie value + */ +struct action_frame_cookie { + struct list_head cookie_node; + uint64_t cookie; +}; + +/** + * struct action_frame_random_mac - Action Frame random mac addr & related attrs + * @in_use: Checks whether random mac is in use + * @addr: Contains random mac addr + * @cookie_list: List of cookies tied with random mac + */ +struct action_frame_random_mac { + bool in_use; + uint8_t addr[VOS_MAC_ADDR_SIZE]; + struct list_head cookie_list; +}; + struct hdd_station_ctx { /** Handle to the Wireless Extension State */ @@ -1395,6 +1440,10 @@ struct hdd_adapter_s queue_oper_history[WLAN_HDD_MAX_HISTORY_ENTRY]; struct hdd_netif_queue_stats queue_oper_stats[WLAN_REASON_TYPE_MAX]; struct power_stats_response *chip_power_stats; + + /* random address management for management action frames */ + spinlock_t random_mac_lock; + struct action_frame_random_mac random_mac[MAX_RANDOM_MAC_ADDRS]; }; #define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station) @@ -2095,6 +2144,20 @@ hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name ) hdd_adapter_t * hdd_get_adapter_by_vdev( hdd_context_t *pHddCtx, tANI_U32 vdev_id ); hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx, tSirMacAddr macAddr ); + +/** + * hdd_get_adapter_by_rand_macaddr() - Get adapter using random DA of MA frms + * @hdd_ctx: Pointer to hdd context + * @mac_addr: random mac address + * + * This function is used to get adapter from randomized destination mac + * address present in management action frames + * + * Return: If randomized addr is present then return pointer to adapter + * else NULL + */ +hdd_adapter_t * hdd_get_adapter_by_rand_macaddr(hdd_context_t *hdd_ctx, tSirMacAddr mac_addr); + VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter ); hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode ); void hdd_deinit_adapter(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, diff --git a/CORE/HDD/inc/wlan_hdd_p2p.h b/CORE/HDD/inc/wlan_hdd_p2p.h index 4126fc30e684..55236875ff24 100644 --- a/CORE/HDD/inc/wlan_hdd_p2p.h +++ b/CORE/HDD/inc/wlan_hdd_p2p.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -47,6 +47,7 @@ #define WLAN_HDD_GET_TYPE_FRM_FC(__fc__) (((__fc__) & 0x0F) >> 2) #define WLAN_HDD_GET_SUBTYPE_FRM_FC(__fc__) (((__fc__) & 0xF0) >> 4) #define WLAN_HDD_80211_FRM_DA_OFFSET 4 +#define WLAN_HDD_80211_FRM_SA_OFFSET 10 #define P2P_WILDCARD_SSID_LEN 7 #define P2P_WILDCARD_SSID "DIRECT-" @@ -209,4 +210,17 @@ void wlan_hdd_cleanup_remain_on_channel_ctx(hdd_adapter_t *pAdapter); #define MAX_ROC_REQ_QUEUE_ENTRY 10 void wlan_hdd_roc_request_dequeue(struct work_struct *work); + +/** + * hdd_check_random_mac() - Whether addr is present in random_mac array + * @adapter: Pointer to adapter + * @mac_addr: random mac address + * + * This function is used to check whether given mac addr is present in list of + * random_mac structures in specified adapter + * + * Return: If random addr is present return true else false + */ +bool hdd_check_random_mac(hdd_adapter_t *adapter, uint8_t *random_mac_addr); + #endif // __P2P_H diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 71fe89b9bd01..0a13285d4397 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -14047,6 +14047,29 @@ static void wlan_hdd_cfg80211_add_connected_pno_support(struct wiphy *wiphy) } #endif +#ifdef CFG80211_RAND_TA_FOR_PUBLIC_ACTION_FRAME +/** + * wlan_hdd_cfg80211_action_frame_randomization_init() - Randomize SA of MA frms + * @wiphy: Pointer to wiphy + * + * This function is used to indicate the support of source mac address + * randomization of management action frames + * + * Return: None + */ +static void +wlan_hdd_cfg80211_action_frame_randomization_init(struct wiphy *wiphy) +{ + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA); +} +#else +static void +wlan_hdd_cfg80211_action_frame_randomization_init(struct wiphy *wiphy) +{ + return; +} +#endif + /* * FUNCTION: wlan_hdd_cfg80211_init * This function is called by hdd_wlan_startup() @@ -14302,6 +14325,7 @@ int wlan_hdd_cfg80211_init(struct device *dev, hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg); wlan_hdd_cfg80211_scan_randomization_init(wiphy); + wlan_hdd_cfg80211_action_frame_randomization_init(wiphy); EXIT(); return 0; diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index b12ed9be972c..664c8fd585b8 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -10270,6 +10270,19 @@ static inline void hdd_adapter_runtime_suspend_denit(hdd_adapter_t *adapter) { } #endif +/** + * hdd_adapter_init_action_frame_random_mac() - Initialze attributes needed for + * randomization of SA in management action frames + * @adapter: Pointer to adapter + * + * Return: None + */ +static void hdd_adapter_init_action_frame_random_mac(hdd_adapter_t *adapter) +{ + spin_lock_init(&adapter->random_mac_lock); + vos_mem_zero(adapter->random_mac, sizeof(adapter->random_mac)); +} + static hdd_adapter_t* hdd_alloc_station_adapter(hdd_context_t *pHddCtx, tSirMacAddr macAddr, unsigned char name_assign_type, @@ -11102,6 +11115,9 @@ hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type, if( VOS_STATUS_SUCCESS != status ) goto err_free_netdev; + /* initialize action frame random mac info */ + hdd_adapter_init_action_frame_random_mac(pAdapter); + // Workqueue which gets scheduled in IPv4 notification callback vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue); @@ -12663,6 +12679,25 @@ hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx, } +hdd_adapter_t * hdd_get_adapter_by_rand_macaddr(hdd_context_t *hdd_ctx, + tSirMacAddr mac_addr) +{ + hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL; + hdd_adapter_t *adapter; + VOS_STATUS status; + + status = hdd_get_front_adapter(hdd_ctx, &adapter_node); + while (adapter_node && status == VOS_STATUS_SUCCESS) { + adapter = adapter_node->pAdapter; + if(adapter && hdd_check_random_mac(adapter, mac_addr)) + return adapter; + status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next); + adapter_node = next; + } + + return NULL; +} + hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name ) { hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c index df5f60a4dbd7..931346ecd522 100644 --- a/CORE/HDD/src/wlan_hdd_p2p.c +++ b/CORE/HDD/src/wlan_hdd_p2p.c @@ -162,6 +162,500 @@ static bool hdd_p2p_is_action_type_rsp( const u8 *buf ) return FALSE; } +/** + * hdd_random_mac_callback() - Callback invoked from wmi layer + * @set_random_addr: Status of random mac filter set operation + * @context: Context passed while registring callback + * + * This function is invoked from wmi layer to give the status of + * random mac filter set operation by firmware. + * + * Return: None + */ +static void hdd_random_mac_callback(bool set_random_addr, void *context) +{ + struct random_mac_context *rnd_ctx; + hdd_adapter_t *adapter; + + if (!context) { + hddLog(LOGE, FL("Bad param, pContext")); + return; + } + + rnd_ctx = context; + adapter = rnd_ctx->adapter; + + spin_lock(&hdd_context_lock); + if ((!adapter) || + (rnd_ctx->magic != ACTION_FRAME_RANDOM_CONTEXT_MAGIC)) { + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + FL("Invalid context, magic [%08x]"), rnd_ctx->magic); + return; + } + + rnd_ctx->magic = 0; + if (set_random_addr) + rnd_ctx->set_random_addr = true; + + complete(&rnd_ctx->random_mac_completion); + spin_unlock(&hdd_context_lock); +} + +/** + * hdd_set_random_mac() - Invoke sme api to set random mac filter + * @adapter: Pointer to adapter + * @random_mac_addr: Mac addr filter to be set + * + * Return: If set is successful return true else return false + */ +static bool hdd_set_random_mac(hdd_adapter_t *adapter, uint8_t *random_mac_addr) +{ + struct random_mac_context context; + hdd_context_t *hdd_ctx; + eHalStatus sme_status; + unsigned long rc; + bool status = false; + + ENTER(); + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (wlan_hdd_validate_context(hdd_ctx)) { + hddLog(LOGE,FL("Invalid hdd ctx")); + return false; + } + + init_completion(&context.random_mac_completion); + context.adapter = adapter; + context.magic = ACTION_FRAME_RANDOM_CONTEXT_MAGIC; + context.set_random_addr = false; + + sme_status = sme_set_random_mac(hdd_ctx->hHal, hdd_random_mac_callback, + adapter->sessionId, random_mac_addr, + &context); + + if (sme_status != eHAL_STATUS_SUCCESS) { + hddLog(LOGE,FL("Unable to set random mac")); + } else { + rc = wait_for_completion_timeout(&context.random_mac_completion, + msecs_to_jiffies(WLAN_WAIT_TIME_SET_RND)); + if (!rc) { + hddLog(LOGE, + FL("SME timed out while setting random mac")); + } + } + + spin_lock(&hdd_context_lock); + context.magic = 0; + status = context.set_random_addr; + spin_unlock(&hdd_context_lock); + + EXIT(); + return status; +} + +/** + * hdd_clear_random_mac() - Invoke sme api to clear random mac filter + * @adapter: Pointer to adapter + * @random_mac_addr: Mac addr filter to be cleared + * + * Return: If clear is successful return true else return false + */ +static bool hdd_clear_random_mac(hdd_adapter_t *adapter, + uint8_t *random_mac_addr) +{ + hdd_context_t *hdd_ctx; + eHalStatus status; + + ENTER(); + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (wlan_hdd_validate_context(hdd_ctx)) { + hddLog(LOGE,FL("Invalid hdd ctx")); + return false; + } + + status = sme_clear_random_mac(hdd_ctx->hHal, adapter->sessionId, + random_mac_addr); + + if (status != eHAL_STATUS_SUCCESS) { + hddLog(LOGE,FL("Unable to clear random mac")); + return false; + } + + EXIT(); + return true; +} + +bool hdd_check_random_mac(hdd_adapter_t *adapter, uint8_t *random_mac_addr) +{ + uint32_t i = 0; + + spin_lock(&adapter->random_mac_lock); + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + if ((adapter->random_mac[i].in_use) && + (!memcmp(adapter->random_mac[i].addr, random_mac_addr, + VOS_MAC_ADDR_SIZE))) { + spin_unlock(&adapter->random_mac_lock); + return true; + } + } + spin_unlock(&adapter->random_mac_lock); + return false; +} + +/** + * find_action_frame_cookie() - Checks for action cookie in cookie list + * @cookie_list: List of cookies + * @cookie: Cookie to be searched + * + * Return: If search is successful return pointer to action_frame_cookie + * object in which cookie item is encapsulated. + */ +static struct action_frame_cookie * find_action_frame_cookie( + struct list_head *cookie_list, + uint64_t cookie) +{ + struct action_frame_cookie *action_cookie = NULL; + struct list_head *temp = NULL; + + list_for_each(temp, cookie_list) { + action_cookie = list_entry(temp, struct action_frame_cookie, + cookie_node); + if (action_cookie->cookie == cookie) + return action_cookie; + } + + return NULL; +} + +/** + * allocate_action_frame_cookie() - Allocate and add action cookie to given list + * @cookie_list: List of cookies + * @cookie: Cookie to be added + * + * Return: If allocation and addition is successful return pointer to + * action_frame_cookie object in which cookie item is encapsulated. + */ +static struct action_frame_cookie * allocate_action_frame_cookie( + struct list_head *cookie_list, + uint64_t cookie) +{ + struct action_frame_cookie *action_cookie = NULL; + + action_cookie = vos_mem_malloc(sizeof(*action_cookie)); + if(!action_cookie) + return NULL; + + action_cookie->cookie = cookie; + list_add(&action_cookie->cookie_node, cookie_list); + + return action_cookie; +} + +/** + * delete_action_frame_cookie() - Delete the cookie from given list + * @cookie_list: List of cookies + * @cookie: Cookie to be deleted + * + * This function deletes the cookie item from given list and corresponding + * object in which it is encapsulated. + * + * Return: None + */ +static void delete_action_frame_cookie( + struct action_frame_cookie *action_cookie) +{ + list_del(&action_cookie->cookie_node); + vos_mem_free(action_cookie); +} + +/** + * append_action_frame_cookie() - Append action cookie to given list + * @cookie_list: List of cookies + * @cookie: Cookie to be append + * + * This is a wrapper function which invokes allocate_action_frame_cookie + * if the cookie to be added is not duplicate + * + * Return: 0 - for successfull case + * -EALREADY - if cookie is duplicate + * -ENOMEM - if allocation is failed + */ +static int32_t append_action_frame_cookie(struct list_head *cookie_list, + uint64_t cookie) +{ + struct action_frame_cookie *action_cookie = NULL; + + /* + * There should be no mac entry with empty cookie list, + * check and ignore if duplicate + */ + action_cookie = find_action_frame_cookie(cookie_list, cookie); + if (action_cookie) + /* random mac address is already programmed */ + return -EALREADY; + + /* insert new cookie in cookie list */ + action_cookie = allocate_action_frame_cookie(cookie_list, cookie); + if (!action_cookie) + return -ENOMEM; + + return 0; +} + +/** + * hdd_set_action_frame_random_mac() - Store action frame cookie + * @adapter: Pointer to adapter + * @random_mac_addr: Mac addr for cookie + * @cookie: Cookie to be stored + * + * This function is used to create cookie list and append the cookies + * to same for corresponding random mac addr. If this cookie is the first + * item in the list then random mac filter is set. + * + * Return: 0 - for success else negative value + */ +static int32_t hdd_set_action_frame_random_mac(hdd_adapter_t *adapter, + uint8_t *random_mac_addr, + uint64_t cookie) +{ + uint32_t i = 0; + uint32_t in_use_cnt = 0; + struct action_frame_cookie *action_cookie = NULL; + int32_t append_ret = 0; + + if (!cookie) { + hddLog(LOGE, FL("Invalid cookie")); + return -EINVAL; + } + + hddLog(LOG1, FL("mac_addr: " MAC_ADDRESS_STR " && cookie = %llu"), + MAC_ADDR_ARRAY(random_mac_addr), cookie); + + spin_lock(&adapter->random_mac_lock); + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + if (adapter->random_mac[i].in_use) { + in_use_cnt++; + if (!memcmp(adapter->random_mac[i].addr, + random_mac_addr, VOS_MAC_ADDR_SIZE)) + break; + } + } + + if (i != MAX_RANDOM_MAC_ADDRS) { + append_ret = append_action_frame_cookie( + &adapter->random_mac[i].cookie_list, + cookie); + spin_unlock(&adapter->random_mac_lock); + + if(append_ret == -ENOMEM) { + hddLog(LOGE, FL("No Sufficient memory for cookie")); + return append_ret; + } + + return 0; + } + + if (in_use_cnt == MAX_RANDOM_MAC_ADDRS) { + spin_unlock(&adapter->random_mac_lock); + hddLog(LOGE, FL("Reached the limit of Max random addresses")); + return -EBUSY; + } + + /* get the first unused buf and store new random mac */ + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + if (!adapter->random_mac[i].in_use) + break; + } + + INIT_LIST_HEAD(&adapter->random_mac[i].cookie_list); + action_cookie = allocate_action_frame_cookie(&adapter->random_mac[i].cookie_list, + cookie); + if(!action_cookie) { + spin_unlock(&adapter->random_mac_lock); + hddLog(LOGE, FL("No Sufficient memory for cookie")); + return -ENOMEM; + } + vos_mem_copy(adapter->random_mac[i].addr, random_mac_addr, + VOS_MAC_ADDR_SIZE); + adapter->random_mac[i].in_use = true; + spin_unlock(&adapter->random_mac_lock); + /* Program random mac_addr */ + if (!hdd_set_random_mac(adapter, adapter->random_mac[i].addr)) { + spin_lock(&adapter->random_mac_lock); + /* clear the cookie */ + delete_action_frame_cookie(action_cookie); + adapter->random_mac[i].in_use = false; + spin_unlock(&adapter->random_mac_lock); + hddLog(LOGE, FL("random mac filter set failed for: " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(adapter->random_mac[i].addr)); + return -EFAULT; + } + + return 0; +} + +/** + * hdd_reset_action_frame_random_mac() - Delete action frame cookie with + * given random mac addr + * @adapter: Pointer to adapter + * @random_mac_addr: Mac addr for cookie + * @cookie: Cookie to be deleted + * + * This function is used to delete the cookie from the cookie list corresponding + * to given random mac addr.If cookie list is empty after deleting, + * it will clear random mac filter. + * + * Return: 0 - for success else negative value + */ +static int32_t hdd_reset_action_frame_random_mac(hdd_adapter_t *adapter, + uint8_t *random_mac_addr, + uint64_t cookie) +{ + uint32_t i = 0; + struct action_frame_cookie *action_cookie = NULL; + + if (!cookie) { + hddLog(LOGE, FL("Invalid cookie")); + return -EINVAL; + } + + hddLog(LOG1, FL("mac_addr: " MAC_ADDRESS_STR " && cookie = %llu"), + MAC_ADDR_ARRAY(random_mac_addr), cookie); + + spin_lock(&adapter->random_mac_lock); + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + if ((adapter->random_mac[i].in_use) && + (!memcmp(adapter->random_mac[i].addr, + random_mac_addr, VOS_MAC_ADDR_SIZE))) + break; + } + + if (i == MAX_RANDOM_MAC_ADDRS) { + spin_unlock(&adapter->random_mac_lock); + hddLog(LOGE, FL("trying to delete cookie of random mac-addr" + " for which entry is not present")); + return -EINVAL; + } + + action_cookie = find_action_frame_cookie(&adapter->random_mac[i].cookie_list, + cookie); + + if (!action_cookie) { + spin_unlock(&adapter->random_mac_lock); + hddLog(LOG1, FL("No cookie matches")); + return 0; + } + + delete_action_frame_cookie(action_cookie); + if (list_empty(&adapter->random_mac[i].cookie_list)) { + adapter->random_mac[i].in_use = false; + spin_unlock(&adapter->random_mac_lock); + hdd_clear_random_mac(adapter, random_mac_addr); + hddLog(LOG1, FL("Deleted random mac_addr:" + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(random_mac_addr)); + return 0; + } + + spin_unlock(&adapter->random_mac_lock); + return 0; +} + +/** + * hdd_delete_action_frame_cookie() - Delete action frame cookie + * @adapter: Pointer to adapter + * @cookie: Cookie to be deleted + * + * This function parses the cookie list of each random mac addr until the + * specified cookie is found and then deletes it. If cookie list is empty + * after deleting, it will clear random mac filter. + * + * Return: 0 - for success else negative value + */ +static int32_t hdd_delete_action_frame_cookie(hdd_adapter_t *adapter, + uint64_t cookie) +{ + uint32_t i = 0; + struct action_frame_cookie *action_cookie = NULL; + + hddLog(LOG1, FL("Delete cookie = %llu"), cookie); + + spin_lock(&adapter->random_mac_lock); + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + if (!adapter->random_mac[i].in_use) + continue; + + action_cookie = find_action_frame_cookie(&adapter->random_mac[i].cookie_list, + cookie); + + if (!action_cookie) + continue; + + delete_action_frame_cookie(action_cookie); + + if (list_empty(&adapter->random_mac[i].cookie_list)) { + adapter->random_mac[i].in_use = false; + spin_unlock(&adapter->random_mac_lock); + hdd_clear_random_mac(adapter, + adapter->random_mac[i].addr); + hddLog(LOG1, FL("Deleted random addr "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(adapter->random_mac[i].addr)); + return 0; + } + spin_unlock(&adapter->random_mac_lock); + return 0; + } + + spin_unlock(&adapter->random_mac_lock); + hddLog(LOG1, FL("Invalid cookie")); + return -EINVAL; +} + +/** + * hdd_delete_all_action_frame_cookies() - Delete all action frame cookies + * @adapter: Pointer to adapter + * + * This function deletes all the cookie lists of each random mac addr and clears + * the corresponding random mac filters. + * + * Return: 0 - for success else negative value + */ +static void hdd_delete_all_action_frame_cookies(hdd_adapter_t *adapter) +{ + uint32_t i = 0; + struct action_frame_cookie *action_cookie = NULL; + struct list_head *n; + struct list_head *temp; + + spin_lock(&adapter->random_mac_lock); + + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + + if (!adapter->random_mac[i].in_use) + continue; + + /* empty the list and clear random addr */ + list_for_each_safe(temp, n, + &adapter->random_mac[i].cookie_list) { + action_cookie = list_entry(temp, + struct action_frame_cookie, + cookie_node); + list_del(temp); + vos_mem_free(action_cookie); + } + + adapter->random_mac[i].in_use = false; + spin_unlock(&adapter->random_mac_lock); + hdd_clear_random_mac(adapter, adapter->random_mac[i].addr); + hddLog(LOG1, FL("Deleted random addr " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(adapter->random_mac[i].addr)); + spin_lock(&adapter->random_mac_lock); + } + + spin_unlock(&adapter->random_mac_lock); +} + static eHalStatus wlan_hdd_remain_on_channel_callback(tHalHandle hHal, void* pCtx, eHalStatus status) @@ -360,6 +854,7 @@ void wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter) ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) ) { + hdd_delete_all_action_frame_cookies(pAdapter); sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ), pAdapter->sessionId ); } @@ -463,6 +958,7 @@ void wlan_hdd_cleanup_remain_on_channel_ctx(hdd_adapter_t *pAdapter) } else if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT || pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) { + hdd_delete_all_action_frame_cookies(pAdapter); sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId); } @@ -548,6 +1044,7 @@ void wlan_hdd_remain_on_chan_timeout(void *data) ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) ) { + hdd_delete_all_action_frame_cookies(pAdapter); sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ), pAdapter->sessionId ); } @@ -1352,6 +1849,7 @@ int __wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy, (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) { tANI_U8 sessionId = pAdapter->sessionId; + hdd_delete_all_action_frame_cookies(pAdapter); sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ), sessionId ); } else if ((WLAN_HDD_SOFTAP== pAdapter->device_mode) || @@ -1404,7 +1902,6 @@ int wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy, return ret; } - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) || defined(WITH_BACKPORTS) int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, struct ieee80211_channel *chan, bool offchan, @@ -1446,6 +1943,7 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, unsigned long rc; hdd_adapter_t *goAdapter; uint8_t home_ch = 0; + bool enb_random_mac = false; ENTER(); @@ -1609,6 +2107,7 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, home_ch = goAdapter->sessionCtx.ap.operatingChannel; } + if (ieee80211_frequency_to_channel(chan->center_freq) == home_ch) { /* if adapter is already on requested ch, no need for ROC */ wait = 0; @@ -1795,6 +2294,19 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, } } + if (!vos_mem_compare((uint8_t *)(&buf[WLAN_HDD_80211_FRM_SA_OFFSET]), + &pAdapter->macAddressCurrent, VOS_MAC_ADDR_SIZE)) { + hddLog(LOG1, "%s: sa of action frame is randomized with mac-addr: " + MAC_ADDRESS_STR, __func__, + MAC_ADDR_ARRAY((uint8_t *)(&buf[WLAN_HDD_80211_FRM_SA_OFFSET]))); + enb_random_mac = true; + } + + if (enb_random_mac && !noack) + hdd_set_action_frame_random_mac(pAdapter, + (uint8_t *)(&buf[WLAN_HDD_80211_FRM_SA_OFFSET]), + *cookie); + if (eHAL_STATUS_SUCCESS != sme_sendAction( WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId, buf, len, extendedWait, noack)) @@ -1827,6 +2339,13 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, err: if(!noack) { + if (enb_random_mac && + ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) || + (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE))) + hdd_reset_action_frame_random_mac(pAdapter, + (uint8_t *)(&buf[WLAN_HDD_80211_FRM_SA_OFFSET]), + *cookie); hdd_sendActionCnf( pAdapter, FALSE ); } return 0; @@ -1900,6 +2419,31 @@ int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, return ret; } +/** + * hdd_wlan_delete_mgmt_tx_cookie() - Wrapper to delete action frame cookie + * @wdev: Pointer to wireless device + * @cookie: Cookie to be deleted + * + * This is a wrapper function which actually invokes the hdd api to delete + * cookie based on the device mode of adapter. + * + * Return: 0 - for success else negative value + */ +static int hdd_wlan_delete_mgmt_tx_cookie(struct wireless_dev *wdev, + u64 cookie) +{ + struct net_device *dev = wdev->netdev; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + + if ((adapter->device_mode == WLAN_HDD_INFRA_STATION) || + (adapter->device_mode == WLAN_HDD_P2P_CLIENT) || + (adapter->device_mode == WLAN_HDD_P2P_DEVICE)) { + hdd_delete_action_frame_cookie(adapter, cookie); + } + + return 0; +} + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) || defined(WITH_BACKPORTS) int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, struct wireless_dev *wdev, @@ -1910,6 +2454,8 @@ int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, return -EINVAL; } + hdd_wlan_delete_mgmt_tx_cookie(wdev, cookie); + return wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy, wdev, cookie); } #else @@ -2575,6 +3121,12 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter, &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]); if (NULL == pAdapter) { + pAdapter = hdd_get_adapter_by_rand_macaddr(pHddCtx, + &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]); + } + + if (NULL == pAdapter) + { /* We will receive broadcast management frames in OCB mode */ pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_OCB); if (NULL == pAdapter || !vos_is_macaddr_broadcast( diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index bb7af9a1c2b7..59952c6effd3 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -8356,4 +8356,32 @@ struct sir_peer_set_rx_blocksize { uint32_t rx_block_ack_win_limit; }; +/** + * enum action_filter_type - Type of action frame filter + * @SME_ACTION_FRAME_RANDOM_MAC_SET: Set filter + * @SME_ACTION_FRAME_RANDOM_MAC_CLEAR: Clear filter + */ +enum action_filter_type { + SME_ACTION_FRAME_RANDOM_MAC_SET, + SME_ACTION_FRAME_RANDOM_MAC_CLEAR, +}; + +typedef void (*action_frame_random_filter_callback)(bool set_random_addr, + void *context); +/** + * struct action_frame_random_filter - Random mac filter attrs for set/clear + * @session_id: Session interface + * @filter_type: Type of filter from action_filter_type + * @callback: Invoked from wmi + * @context: Parameter to be used with callback + * @mac_addr: Random mac addr for which filter is to be set + */ +struct action_frame_random_filter { + uint32_t session_id; + enum action_filter_type filter_type; + action_frame_random_filter_callback callback; + void *context; + uint8_t mac_addr[VOS_MAC_ADDR_SIZE]; +}; + #endif /* __SIR_API_H */ diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h index 0fe84ba295ac..b8e957f689a8 100644 --- a/CORE/MAC/src/include/sirParams.h +++ b/CORE/MAC/src/include/sirParams.h @@ -794,6 +794,7 @@ typedef struct sSirMbMsgP2p #define SIR_HAL_POWER_DEBUG_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 371) #define SIR_HAL_GET_PEER_INFO_EXT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 372) #define SIR_HAL_GET_PEER_INFO_EXT_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 373) +#define SIR_HAL_ACTION_FRAME_RANDOM_MAC (SIR_HAL_ITC_MSG_TYPES_BEGIN + 374) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 2946215de3ff..46d19e5cb74f 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -8524,6 +8524,59 @@ static void wma_register_debug_callback(void) vos_register_debug_callback(VOS_MODULE_ID_WDA, &wma_state_info_dump); } +/** + * wma_action_frame_filter_mac_event_handler() - action frame filter evt handler + * @handle: wma handle + * @event_buf: event handler data + * @len: length of @event_buf + * + * this function will handle the + * WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID + * + * Return: int + */ +static int +wma_action_frame_filter_mac_event_handler(void *handle, u_int8_t *event_buf, + u_int32_t len) +{ + tp_wma_handle wma_handle = (tp_wma_handle)handle; + WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID_param_tlvs *param_buf; + wmi_vdev_add_mac_addr_to_rx_filter_status_event_fixed_param *event; + struct action_frame_random_filter *filter; + struct wma_txrx_node *intr; + bool status = false; + + WMA_LOGD("%s: Enter", __func__); + + param_buf = + (WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID_param_tlvs *)event_buf; + if (!param_buf) { + WMA_LOGA(FL("Invalid action frame filter mac event")); + return -EINVAL; + } + event = param_buf->fixed_param; + if (!event) { + WMA_LOGA(FL("Invalid fixed param")); + return -EINVAL; + } + + intr = &wma_handle->interfaces[event->vdev_id]; + /* command is in progess */ + if(!intr->action_frame_filter) { + WMA_LOGE(FL("no action frame req is pending - invalid event")); + return -1; + } + filter = intr->action_frame_filter; + if (event->status) + status = true; + + (filter->callback)(status, filter->context); + intr->action_frame_filter = NULL; + vos_mem_free(filter); + + return 0; +} + struct wma_version_info g_wmi_version_info; /* @@ -8961,6 +9014,10 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, WMI_CHAN_INFO_EVENTID, wma_chan_info_event_handler); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID, + wma_action_frame_filter_mac_event_handler); + wma_register_debug_callback(); wma_ndp_register_all_event_handlers(wma_handle); @@ -19571,6 +19628,14 @@ static void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params) wma->interfaces[params->smesessionId].psnr_req = NULL; } + if (wma->interfaces[params->smesessionId].action_frame_filter) { + struct action_frame_random_filter *action_frame_filter = + wma->interfaces[params->smesessionId].action_frame_filter; + wma->interfaces[params->smesessionId].action_frame_filter = + NULL; + vos_mem_free(action_frame_filter); + } + if (wlan_op_mode_ibss == txrx_vdev->opmode) { wma->ibss_started = 0; } @@ -32433,6 +32498,96 @@ static VOS_STATUS wma_set_rx_blocksize(tp_wma_handle wma_handle, return VOS_STATUS_SUCCESS; } +/** + * wma_process_action_frame_random_mac() - set/clear action frame random mac + * @wma_handle: pointer to wma handle + * @filter: pointer to buffer containing random mac, session_id and callback + * + * Return: VOS_STATUS_SUCCESS for success or error code. + */ +static VOS_STATUS +wma_process_action_frame_random_mac(tp_wma_handle wma_handle, + struct action_frame_random_filter *filter) +{ + wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *cmd; + uint32_t len; + wmi_buf_t buf; + int ret; + struct action_frame_random_filter *filter_bkup = NULL; + struct wma_txrx_node *intr = NULL; + + if (!filter) { + WMA_LOGE(FL("invalid pointer")); + return VOS_STATUS_E_INVAL; + } + + if (!wma_handle) { + WMA_LOGE(FL("WMA context is invald!")); + return VOS_STATUS_E_INVAL; + } + + if (filter->filter_type == SME_ACTION_FRAME_RANDOM_MAC_SET) { + intr = &wma_handle->interfaces[filter->session_id]; + /* command is in progess */ + if(intr->action_frame_filter != NULL) { + WMA_LOGE(FL("previous action frame req is pending")); + return VOS_STATUS_SUCCESS; + } + + filter_bkup = adf_os_mem_alloc(NULL, sizeof(*filter)); + if (!filter_bkup) { + WMA_LOGE( + FL("action frame filter mem alloc failed")); + return VOS_STATUS_E_FAILURE; + } + + adf_os_mem_set(filter_bkup, 0, sizeof(*filter)); + filter_bkup->session_id = filter->session_id; + filter_bkup->callback = filter->callback; + filter_bkup->filter_type = filter->filter_type; + filter_bkup->context = filter->context; + + vos_mem_copy(filter_bkup->mac_addr, filter->mac_addr, + VOS_MAC_ADDR_SIZE); + intr->action_frame_filter = (void *)filter_bkup; + } + + len = sizeof(*cmd); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + + if (!buf) { + WMA_LOGE(FL("Failed allocate wmi buffer")); + return VOS_STATUS_E_NOMEM; + } + cmd = (wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *) + wmi_buf_data(buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param)); + + cmd->vdev_id = filter->session_id; + WMI_CHAR_ARRAY_TO_MAC_ADDR(filter->mac_addr, &cmd->mac_addr); + if (filter->filter_type == SME_ACTION_FRAME_RANDOM_MAC_SET) + cmd->enable = 1; + else + cmd->enable = 0; + + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID); + if (ret) { + WMA_LOGE(FL("Failed to send action frame random mac cmd")); + wmi_buf_free(buf); + if (filter->filter_type == SME_ACTION_FRAME_RANDOM_MAC_SET) { + adf_os_mem_free(filter_bkup); + intr->action_frame_filter = NULL; + } + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + /* * function : wma_mc_process_msg * Description : @@ -33358,6 +33513,11 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) case SIR_HAL_POWER_DEBUG_STATS_REQ: wma_process_power_debug_stats_req(wma_handle); break; + case WDA_ACTION_FRAME_RANDOM_MAC: + wma_process_action_frame_random_mac(wma_handle, + (struct action_frame_random_filter *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; default: WMA_LOGD("unknow msg type %x", msg->type); /* Do Nothing? MSG Body should be freed at here */ diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index 21eaeef546e9..2332d0156c04 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -646,7 +646,7 @@ struct wma_txrx_node { uint8_t wep_default_key_idx; bool is_vdev_valid; uint16_t channelwidth; - + struct action_frame_random_filter *action_frame_filter; }; #if defined(QCA_WIFI_FTM) diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index 1faabd332c6a..b9a6c028cdf2 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -4764,4 +4764,38 @@ eHalStatus sme_power_debug_stats_req(tHalHandle hal, void (*callback_fn) (struct power_stats_response *response, void *context), void *power_stats_context); #endif + +/** + * sme_set_random_mac() - Set random mac address filter + * @hal: hal handle for getting global mac struct + * @callback: callback to be invoked for response from firmware + * @session_id: interface id + * @random_mac: random mac address to be set + * @context: parameter to callback + * + * This function is used to set random mac address filter for action frames + * which are send with the same address, callback is invoked when corresponding + * event from firmware has come. + * + * Return: eHalStatus enumeration. + */ +eHalStatus sme_set_random_mac(tHalHandle hal, + action_frame_random_filter_callback callback, + uint32_t session_id, uint8_t *random_mac, + void *context); + +/** + * sme_clear_random_mac() - clear random mac address filter + * @hal: HAL handle + * @session_id: interface id + * @random_mac: random mac address to be cleared + * + * This function is used to clear the randmom mac address filters + * which are set with sme_set_random_mac + * + * Return: eHalStatus enumeration. + */ +eHalStatus sme_clear_random_mac(tHalHandle hal, uint32_t session_id, + uint8_t *random_mac); + #endif //#if !defined( __SME_API_H ) diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index e89fedf2dcd7..d2fa3d2c2d37 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -20260,3 +20260,97 @@ eHalStatus sme_update_sub20_channel_width(tHalHandle hal_handle, return status; } #endif + +eHalStatus sme_set_random_mac(tHalHandle hal, + action_frame_random_filter_callback callback, + uint32_t session_id, uint8_t *random_mac, + void *context) +{ + + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + vos_msg_t vos_msg; + struct action_frame_random_filter *filter; + + filter = vos_mem_malloc(sizeof(*filter)); + + if (!filter) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Failed to alloc random mac filter")); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_zero(filter, sizeof(*filter)); + + filter->session_id = session_id; + filter->filter_type = SME_ACTION_FRAME_RANDOM_MAC_SET; + filter->callback = callback; + filter->context = context; + vos_mem_copy(filter->mac_addr, random_mac, VOS_MAC_ADDR_SIZE); + + status = sme_AcquireGlobalLock(&mac_ctx->sme); + if (status == eHAL_STATUS_SUCCESS) { + /* Serialize the req through MC thread */ + vos_msg.bodyptr = filter; + vos_msg.type = WDA_ACTION_FRAME_RANDOM_MAC; + vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("action frame set random mac msg fail")); + status = eHAL_STATUS_FAILURE; + vos_mem_free(filter); + } + sme_ReleaseGlobalLock(&mac_ctx->sme); + } else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("sme_AcquireGlobalLock failed")); + vos_mem_free(filter); + } + return status; +} + +eHalStatus sme_clear_random_mac(tHalHandle hal, uint32_t session_id, + uint8_t *random_mac) +{ + + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + vos_msg_t vos_msg; + struct action_frame_random_filter *filter; + + filter = vos_mem_malloc(sizeof(*filter)); + + if (!filter) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Failed to alloc random mac filter")); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_zero(filter, sizeof(*filter)); + + filter->session_id = session_id; + filter->filter_type = SME_ACTION_FRAME_RANDOM_MAC_CLEAR; + vos_mem_copy(filter->mac_addr, random_mac, VOS_MAC_ADDR_SIZE); + + status = sme_AcquireGlobalLock(&mac_ctx->sme); + if (status == eHAL_STATUS_SUCCESS) { + /* Serialize the req through MC thread */ + vos_msg.bodyptr = filter; + vos_msg.type = WDA_ACTION_FRAME_RANDOM_MAC; + vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("action frame clear random mac msg fail")); + status = eHAL_STATUS_FAILURE; + vos_mem_free(filter); + } + sme_ReleaseGlobalLock(&mac_ctx->sme); + } else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("sme_AcquireGlobalLock failed")); + vos_mem_free(filter); + } + return status; +} diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c index ea7bb57b530f..21e0ad168e25 100644 --- a/CORE/SYS/legacy/src/utils/src/macTrace.c +++ b/CORE/SYS/legacy/src/utils/src/macTrace.c @@ -1000,6 +1000,7 @@ tANI_U8* macTraceGetWdaMsgString(tANI_U16 wdaMsg) CASE_RETURN_STRING(WDA_SET_MIB_STATS_ENABLE); CASE_RETURN_STRING(WDA_SET_MIB_STATS_DISABLE); CASE_RETURN_STRING(SIR_HAL_POWER_DEBUG_STATS_REQ); + CASE_RETURN_STRING(WDA_ACTION_FRAME_RANDOM_MAC); default: return((tANI_U8*) "UNKNOWN"); break; diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h index 5fa36324979a..a4569bb524bd 100644 --- a/CORE/WDA/inc/wlan_qct_wda.h +++ b/CORE/WDA/inc/wlan_qct_wda.h @@ -1107,6 +1107,7 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); #define WDA_UPDATE_STA_INACTIVITY_TIMEOUT SIR_HAL_STA_INACTIVITY_TIMEOUT +#define WDA_ACTION_FRAME_RANDOM_MAC SIR_HAL_ACTION_FRAME_RANDOM_MAC tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg); |
