From a55792d148732546cb05d39c6a8408e3d041457b Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Mon, 15 May 2017 14:52:40 +0530 Subject: [PATCH 1/6] qcacmn: Race condition while using pkt log buffer There can be a race condition if the pktlog_buf inside pktlog APIs, is accessed simultanously from two threads. To prevent this use mutex in the caller functions of pktlog APIs. Change-Id: Iea6e3cd28a7a347c1753fe71d0646fb43ee184fa CRs-Fixed: 2047150 --- utils/pktlog/include/pktlog_ac_api.h | 1 + utils/pktlog/linux_ac.c | 46 +++++++++++++++--- utils/pktlog/pktlog_ac.c | 70 +++++++++++++++++++++++++++- 3 files changed, 108 insertions(+), 9 deletions(-) diff --git a/utils/pktlog/include/pktlog_ac_api.h b/utils/pktlog/include/pktlog_ac_api.h index b27558201a48..b879f07dd583 100644 --- a/utils/pktlog/include/pktlog_ac_api.h +++ b/utils/pktlog/include/pktlog_ac_api.h @@ -98,6 +98,7 @@ struct ath_pktlog_info { /* Size of buffer in bytes */ int32_t buf_size; spinlock_t log_lock; + struct mutex pktlog_mutex; /* Threshold of TCP SACK packets for triggered stop */ int sack_thr; diff --git a/utils/pktlog/linux_ac.c b/utils/pktlog/linux_ac.c index b84c013aeac5..e16142a30ddd 100644 --- a/utils/pktlog/linux_ac.c +++ b/utils/pktlog/linux_ac.c @@ -128,6 +128,7 @@ int pktlog_alloc_buf(struct hif_opaque_softc *scn) unsigned long vaddr; struct page *vpg; struct ath_pktlog_info *pl_info; + struct ath_pktlog_buf *buffer; ol_txrx_pdev_handle pdev_txrx_handle; pdev_txrx_handle = cds_get_context(QDF_MODULE_ID_TXRX); @@ -143,25 +144,39 @@ int pktlog_alloc_buf(struct hif_opaque_softc *scn) page_cnt = (sizeof(*(pl_info->buf)) + pl_info->buf_size) / PAGE_SIZE; - pl_info->buf = vmalloc((page_cnt + 2) * PAGE_SIZE); - if (pl_info->buf == NULL) { + spin_lock_bh(&pl_info->log_lock); + if (pl_info->buf != NULL) { + printk(PKTLOG_TAG "Buffer is already in use\n"); + spin_unlock_bh(&pl_info->log_lock); + return -EINVAL; + } + spin_unlock_bh(&pl_info->log_lock); + + buffer = vmalloc((page_cnt + 2) * PAGE_SIZE); + if (buffer == NULL) { printk(PKTLOG_TAG "%s: Unable to allocate buffer " "(%d pages)\n", __func__, page_cnt); return -ENOMEM; } - pl_info->buf = (struct ath_pktlog_buf *) - (((unsigned long)(pl_info->buf) + PAGE_SIZE - 1) + buffer = (struct ath_pktlog_buf *) + (((unsigned long)(buffer) + PAGE_SIZE - 1) & PAGE_MASK); - for (vaddr = (unsigned long)(pl_info->buf); - vaddr < ((unsigned long)(pl_info->buf) + (page_cnt * PAGE_SIZE)); + for (vaddr = (unsigned long)(buffer); + vaddr < ((unsigned long)(buffer) + (page_cnt * PAGE_SIZE)); vaddr += PAGE_SIZE) { vpg = vmalloc_to_page((const void *)vaddr); SetPageReserved(vpg); } + spin_lock_bh(&pl_info->log_lock); + if (pl_info->buf != NULL) + pktlog_release_buf(pdev_txrx_handle); + + pl_info->buf = buffer; + spin_unlock_bh(&pl_info->log_lock); return 0; } @@ -200,6 +215,7 @@ static void pktlog_cleanup(struct ath_pktlog_info *pl_info) { pl_info->log_state = 0; PKTLOG_LOCK_DESTROY(pl_info); + mutex_destroy(&pl_info->pktlog_mutex); } /* sysctl procfs handler to enable pktlog */ @@ -802,7 +818,7 @@ rd_done: } static ssize_t -pktlog_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) +__pktlog_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) { size_t bufhdr_size; size_t count = 0, ret_val = 0; @@ -944,6 +960,22 @@ rd_done: return ret_val; } +static ssize_t +pktlog_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) +{ + size_t ret; + struct ath_pktlog_info *pl_info; + + pl_info = (struct ath_pktlog_info *) + PDE_DATA(file->f_path.dentry->d_inode); + if (!pl_info) + return 0; + mutex_lock(&pl_info->pktlog_mutex); + ret = __pktlog_read(file, buf, nbytes, ppos); + mutex_unlock(&pl_info->pktlog_mutex); + return ret; +} + #ifndef VMALLOC_VMADDR #define VMALLOC_VMADDR(x) ((unsigned long)(x)) #endif diff --git a/utils/pktlog/pktlog_ac.c b/utils/pktlog/pktlog_ac.c index bf611c51d78e..4b7c17d33d2b 100644 --- a/utils/pktlog/pktlog_ac.c +++ b/utils/pktlog/pktlog_ac.c @@ -362,6 +362,7 @@ void pktlog_init(struct hif_opaque_softc *scn) OS_MEMZERO(pl_info, sizeof(*pl_info)); PKTLOG_LOCK_INIT(pl_info); + mutex_init(&pl_info->pktlog_mutex); pl_info->buf_size = PKTLOG_DEFAULT_BUFSIZE; pl_info->buf = NULL; @@ -387,7 +388,7 @@ void pktlog_init(struct hif_opaque_softc *scn) PKTLOG_SW_EVENT_SUBSCRIBER.callback = pktlog_callback; } -int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, +static int __pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, bool ini_triggered, uint8_t user_triggered, uint32_t is_iwpriv_command) { @@ -505,7 +506,49 @@ int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, return 0; } -int pktlog_setsize(struct hif_opaque_softc *scn, int32_t size) +int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, + bool ini_triggered, uint8_t user_triggered, + uint32_t is_iwpriv_command) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info *pl_info; + struct ol_txrx_pdev_t *txrx_pdev; + int error; + + if (!scn) { + printk("%s: Invalid scn context\n", __func__); + ASSERT(0); + return -EINVAL; + } + + txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); + if (!txrx_pdev) { + printk("%s: Invalid txrx_pdev context\n", __func__); + ASSERT(0); + return -EINVAL; + } + + pl_dev = txrx_pdev->pl_dev; + if (!pl_dev) { + printk("%s: Invalid pktlog context\n", __func__); + ASSERT(0); + return -EINVAL; + } + + pl_info = pl_dev->pl_info; + + if (!pl_info) + return 0; + + + mutex_lock(&pl_info->pktlog_mutex); + error = __pktlog_enable(scn, log_state, ini_triggered, + user_triggered, is_iwpriv_command); + mutex_unlock(&pl_info->pktlog_mutex); + return error; +} + +static int __pktlog_setsize(struct hif_opaque_softc *scn, int32_t size) { ol_txrx_pdev_handle pdev_txrx_handle = cds_get_context(QDF_MODULE_ID_TXRX); @@ -568,6 +611,29 @@ int pktlog_setsize(struct hif_opaque_softc *scn, int32_t size) return 0; } +int pktlog_setsize(struct hif_opaque_softc *scn, int32_t size) +{ + int status; + ol_txrx_pdev_handle pdev_txrx_handle = + cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info *pl_info; + + if (pdev_txrx_handle == NULL || + pdev_txrx_handle->pl_dev == NULL || + pdev_txrx_handle->pl_dev->pl_info == NULL) + return -EFAULT; + + pl_dev = pdev_txrx_handle->pl_dev; + pl_info = pl_dev->pl_info; + + mutex_lock(&pl_info->pktlog_mutex); + status = __pktlog_setsize(scn, size); + mutex_unlock(&pl_info->pktlog_mutex); + + return status; +} + int pktlog_clearbuff(struct hif_opaque_softc *scn, bool clear_buff) { ol_txrx_pdev_handle pdev_txrx_handle = From 83eddc57a1846c9a5253ead3e5d1d379c29836a0 Mon Sep 17 00:00:00 2001 From: Ajit Pal Singh Date: Tue, 23 May 2017 16:22:05 +0530 Subject: [PATCH 2/6] qcacmn: Add wifi configuration attribute restrict offchannel This commit defines an attribute to QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION - QCA_WLAN_VENDOR_ATTR_CONFIG_RESTRICT_OFFCHANNEL which can be used to restrict offchannel operations on the AP/GO interface. The goal is to restrict any operations which would cause the AP/GO to leave its operating channel. Change-Id: I88c2edb9456105068d0907b47dcd78cc09dc2428 CRs-Fixed: 2050999 --- os_if/linux/qca_vendor.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/os_if/linux/qca_vendor.h b/os_if/linux/qca_vendor.h index 91aa93a1338d..75408280417e 100644 --- a/os_if/linux/qca_vendor.h +++ b/os_if/linux/qca_vendor.h @@ -2966,6 +2966,35 @@ enum qca_wlan_vendor_attr_config { QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_DATA_SNR_WEIGHT = 46, /* 32-bit unsigned value to set ack snr weight */ QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ACK_SNR_WEIGHT = 47, + /* + * 8 bit unsigned value that is set on an AP/GO virtual interface to + * disable operations that would cause the AP/GO to leave its operating + * channel. + * + * This will restrict the scans to the AP/GO operating channel and the + * channels of the other band, if DBS is supported.A STA/CLI interface + * brought up after this setting is enabled, will be restricted to + * connecting to devices only on the AP/GO interface's operating channel + * or on the other band in DBS case. P2P supported channel list is + * modified, to only include AP interface's operating-channel and the + * channels of the other band if DBS is supported. + * + * These restrictions are only applicable as long as the AP/GO interface + * is alive. If the AP/GO interface is brought down then this + * setting/restriction is forgotten. + * + * If this variable is set on an AP/GO interface while a multi-channel + * concurrent session is active, it has no effect on the operation of + * the current interfaces, other than restricting the scan to the AP/GO + * operating channel and the other band channels if DBS is supported. + * However, if the STA is brought down and restarted then the new STA + * connection will either be formed on the AP/GO channel or on the + * other band in a DBS case. This is because of the scan being + * restricted on these channels as mentioned above. + * + * 1-Disable offchannel operations, 0-Enable offchannel operations. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RESTRICT_OFFCHANNEL = 49, /* keep last */ QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST, From 8c63d04d3bdaeeba12ba58d796701eb9868b4b7a Mon Sep 17 00:00:00 2001 From: Ajit Pal Singh Date: Wed, 24 May 2017 11:58:09 +0530 Subject: [PATCH 3/6] qcacmn: Add vdev-mlme caps MASK for restrict_offchannel Adds new vdev-mlme caps mask WLAN_VDEV_C_RESTRICT_OFFCHAN for tracking restrict offchannel setting. When this bit is set any operations which can cause the AP/GO to leave the operating channel are avoided. Also reads vdev-mlme caps:WLAN_VDEV_C_RESTRICT_OFFCHAN in function policy_mgr_is_dnsc_set() to determine if Do_Not_Switch_Channel is enabled. Moves declaration of policy_mgr_is_dnsc_set() to wlan_policy_mgr_api.h so that it can be used outside of policy manager. Change-Id: I53013af5f4c72917f862630e63333951ec75ce8c CRs-Fixed: 2050999 --- .../obj_mgr/inc/wlan_objmgr_vdev_obj.h | 2 ++ .../policy_mgr/inc/wlan_policy_mgr_api.h | 11 ++++++++++ .../src/wlan_policy_mgr_get_set_utils.c | 21 +++++++++++++++---- .../policy_mgr/src/wlan_policy_mgr_i.h | 12 ----------- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h index 02929b83efad..a7897160e19c 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h @@ -210,6 +210,8 @@ #define WLAN_VDEV_C_WME_TKIPMIC 0x00000080 /* CAPABILITY: bg scanning */ #define WLAN_VDEV_C_BGSCAN 0x00000100 + /* CAPABILITY: Restrict offchannel */ +#define WLAN_VDEV_C_RESTRICT_OFFCHAN 0x00000200 /* Invalid VDEV identifier */ #define WLAN_INVALID_VDEV_ID 255 diff --git a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index c96d0e9abfcd..40cce054c0e1 100644 --- a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -1895,4 +1895,15 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, */ uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, struct dbs_nss *nss_dbs); + +/** + * policy_mgr_is_dnsc_set - Check if user has set + * "Do_Not_Switch_Channel" for the vdev passed + * @vdev: vdev pointer + * + * Get "Do_Not_Switch_Channel" setting for the vdev passed. + * + * Return: true for success, else false + */ +bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 4420e63a5350..9d16bdd63c25 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -2408,10 +2408,23 @@ bool policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc) return flag; } -bool policy_mgr_vdev_mlme_is_dnsc_set(struct wlan_objmgr_vdev *vdev) +bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev) { - /* TODO : Check Dont_Switch_Channel status from vdev mlme caps*/ - return false; + bool roffchan; + + if (!vdev) { + policy_mgr_err("Invalid parameter"); + return false; + } + + wlan_vdev_obj_lock(vdev); + roffchan = wlan_vdev_mlme_cap_get(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN); + wlan_vdev_obj_unlock(vdev); + + policy_mgr_debug("Restrict offchannel:%s", + roffchan ? "set" : "clear"); + + return roffchan; } QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, @@ -2456,7 +2469,7 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, * return true. */ /* TODO: To be enhanced for SBS */ - if (policy_mgr_vdev_mlme_is_dnsc_set(vdev)) { + if (policy_mgr_is_dnsc_set(vdev)) { if (operating_channel == channel) *ok = true; else if (WLAN_REG_IS_SAME_BAND_CHANNELS(operating_channel, diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h index 9a48a16fc32e..5100017bda57 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h @@ -414,16 +414,4 @@ bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, uint8_t *channel, uint8_t *vdev_id, enum policy_mgr_con_mode mode); - -/** - * policy_mgr_vdev_mlme_is_dnsc_set - Check if user has set - * "Do_Not_Switch_Channel" for this vdev - * @vdev: vdev pointer - * - * Get "Do_Not_Switch_Channel" setting for this vdev - * - * Return: true for success, else false - */ -bool policy_mgr_vdev_mlme_is_dnsc_set(struct wlan_objmgr_vdev *vdev); - #endif From 7c24ceadfb58b9ef456b89620d8d763665f40603 Mon Sep 17 00:00:00 2001 From: Ajit Pal Singh Date: Tue, 30 May 2017 20:32:33 +0530 Subject: [PATCH 4/6] qcacmn: Fill the frequencies in the SCAN req correctly Out of the list of scan channels passed by the application, if the driver skips some channels, then the frequency list sent to firmware was not correctly filled. For example if supplicant passes channels 1, 6, 11 and we want to skip 1 and 6, then "req->scan_req.chan_list[0] = 0, req->scan_req.chan_list[1] = 0 and req->scan_req.chan_list[2] = 11". It should have been "req->scan_req.chan_list[0] = 11" Fixes the same. Change-Id: Idcef090169b8848c2576e620aa0fbe93918c219c CRs-fixed: 2053866 --- os_if/linux/scan/src/wlan_cfg80211_scan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/os_if/linux/scan/src/wlan_cfg80211_scan.c b/os_if/linux/scan/src/wlan_cfg80211_scan.c index ffce5af6d49b..2ec383b23a80 100644 --- a/os_if/linux/scan/src/wlan_cfg80211_scan.c +++ b/os_if/linux/scan/src/wlan_cfg80211_scan.c @@ -1018,7 +1018,8 @@ int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev, #endif len += snprintf(chl + len, 5, "%d ", channel); - req->scan_req.chan_list[i] = wlan_chan_to_freq(channel); + req->scan_req.chan_list[num_chan] = + wlan_chan_to_freq(channel); num_chan++; } cfg80211_notice("Channel-List: %s", chl); From 1c7d897d9cb93961a13492bf5ecaf2a1636924b6 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Thu, 1 Jun 2017 16:08:17 +0530 Subject: [PATCH 5/6] qcacmn: Add support to extract pdev_id from utf seg info pdev_id is required to get the pdev object from utf event. Extract pdev_id from the seg info within utf event's data stream. Change-Id: Id8d3263a7f33d234c7cb43c99a0a44f28df5724d CRs-Fixed: 2055128 --- wmi/inc/wmi_unified_param.h | 17 +++++++++++++++++ wmi/src/wmi_unified_tlv.c | 4 +++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index a5291179783c..6597acd70a2f 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -7106,6 +7106,7 @@ enum WMI_HOST_CALIBRATION_STATUS { * struct wmi_host_pdev_utf_event - Host defined struct to hold utf event data * @data: Pointer to data * @datalen: Data length + * @pdev_id: Pdev_id of data * */ struct wmi_host_pdev_utf_event { @@ -7114,6 +7115,22 @@ struct wmi_host_pdev_utf_event { uint32_t pdev_id; }; +/** + * struct wmi_host_utf_seg_header_info - Host defined struct to map seg info in + * UTF event + * @len: segment length + * @msgref: message reference + * @segment_info: segment info + * @pdev_id: pdev_id + * + */ +struct wmi_host_utf_seg_header_info { + uint32_t len; + uint32_t msgref; + uint32_t segment_info; + uint32_t pdev_id; +}; + /** * struct wmi_host_pdev_qvit_event - Host defined struct to hold qvit event data * @data: Pointer to data diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 13f213c4673a..fd50d18d2289 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -16510,13 +16510,15 @@ static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, struct wmi_host_pdev_utf_event *event) { WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; + struct wmi_host_utf_seg_header_info *seg_hdr; param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; event->data = param_buf->data; event->datalen = param_buf->num_data; + seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; /* Set pdev_id=1 until FW adds support to include pdev_id */ event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( - WMI_PDEV_ID_1ST); + seg_hdr->pdev_id); return QDF_STATUS_SUCCESS; } From c6cd8dc07de014bc1243be2a3c5db87c54feebfc Mon Sep 17 00:00:00 2001 From: Sathish Kumar Date: Wed, 31 May 2017 19:01:08 +0530 Subject: [PATCH 6/6] qcacmn: Add API to check if HT rates is allowed Add API to check if HT rates are allowed based on the cipher and mode Change-Id: I7a24dcaf82f92abf9e9d6c7d7bbd3818e955c330 CRs-Fixed: 2053603 --- .../crypto/inc/wlan_crypto_global_api.h | 25 +++++ .../crypto/src/wlan_crypto_global_api.c | 101 ++++++++++++++---- 2 files changed, 104 insertions(+), 22 deletions(-) diff --git a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h index d9e1f4f87227..01719d51890d 100644 --- a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h +++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h @@ -50,6 +50,31 @@ QDF_STATUS wlan_crypto_set_param(struct wlan_objmgr_vdev *vdev, */ int32_t wlan_crypto_get_param(struct wlan_objmgr_vdev *vdev, wlan_crypto_param_type param); +/** + * wlan_crypto_get_peer_param - called by ucfg to get crypto peer param + * + * @peer: peer + * @param: param to be get. + * + * This function gets called from ucfg to get peer param + * + * Return: value or -1 for failure + */ +int32_t wlan_crypto_get_peer_param(struct wlan_objmgr_peer *peer, + wlan_crypto_param_type param); + +/** + * wlan_crypto_is_htallowed - called by ucfg to check if HT rates is allowed + * + * @vdev: Vdev + * @peer: Peer + * + * This function is called to check if HT rates is allowed + * + * Return: 0 for not allowed and +ve for allowed + */ +uint8_t wlan_crypto_is_htallowed(struct wlan_objmgr_vdev *vdev, + struct wlan_objmgr_peer *peer); /** * wlan_crypto_setkey - called by ucfg to setkey * diff --git a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c index 93cb4c32af16..54075f6a7c6b 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c +++ b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c @@ -34,6 +34,8 @@ #include "wlan_crypto_param_handling_i.h" #include "wlan_crypto_obj_mgr_i.h" +#include + const struct wlan_crypto_cipher *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX]; @@ -143,29 +145,20 @@ QDF_STATUS wlan_crypto_set_param(struct wlan_objmgr_vdev *vdev, } /** - * wlan_crypto_get_param - called by ucfg to get crypto param + * wlan_crypto_get_param_value - called by crypto APIs to get value for param * - * @vdev: vdev - * @param: param to be get. + * @param: Crypto param type + * @crypto_params: Crypto params struct * - * This function gets called from ucfg to get param + * This function gets called from in-within crypto layer * * Return: value or -1 for failure */ -int32_t wlan_crypto_get_param(struct wlan_objmgr_vdev *vdev, - wlan_crypto_param_type param){ +static int32_t wlan_crypto_get_param_value(wlan_crypto_param_type param, + struct wlan_crypto_params *crypto_params) +{ int32_t value = -1; - struct wlan_crypto_comp_priv *crypto_priv; - struct wlan_crypto_params *crypto_params; - crypto_priv = (struct wlan_crypto_comp_priv *) - wlan_get_vdev_crypto_obj(vdev); - if (crypto_priv == NULL) { - qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__); - return QDF_STATUS_E_INVAL; - } - - crypto_params = &(crypto_priv->crypto_params); switch (param) { case WLAN_CRYPTO_PARAM_AUTH_MODE: value = wlan_crypto_get_authmode(crypto_params); @@ -195,6 +188,71 @@ int32_t wlan_crypto_get_param(struct wlan_objmgr_vdev *vdev, return value; } +int32_t wlan_crypto_get_param(struct wlan_objmgr_vdev *vdev, + wlan_crypto_param_type param) +{ + int32_t value = -1; + struct wlan_crypto_comp_priv *crypto_priv; + struct wlan_crypto_params *crypto_params; + crypto_priv = (struct wlan_crypto_comp_priv *) + wlan_get_vdev_crypto_obj(vdev); + + if (crypto_priv == NULL) { + qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__); + return QDF_STATUS_E_INVAL; + } + + crypto_params = &(crypto_priv->crypto_params); + value = wlan_crypto_get_param_value(param, crypto_params); + + return value; +} + +int32_t wlan_crypto_get_peer_param(struct wlan_objmgr_peer *peer, + wlan_crypto_param_type param) +{ + int32_t value = -1; + struct wlan_crypto_comp_priv *crypto_priv; + struct wlan_crypto_params *crypto_params; + + crypto_params = wlan_crypto_peer_get_comp_params(peer, + &crypto_priv); + + if (crypto_params == NULL) { + qdf_print("%s[%d] crypto_params NULL\n", __func__, __LINE__); + return QDF_STATUS_E_INVAL; + } + value = wlan_crypto_get_param_value(param, crypto_params); + + return value; +} + +uint8_t wlan_crypto_is_htallowed(struct wlan_objmgr_vdev *vdev, + struct wlan_objmgr_peer *peer) +{ + int32_t ucast_cipher; + + if (!(vdev || peer)) { + qdf_print("%s[%d] Invalid params\n", __func__, __LINE__); + return 0; + } + + if (vdev) + ucast_cipher = wlan_crypto_get_param(vdev, + WLAN_CRYPTO_PARAM_UCAST_CIPHER); + else + ucast_cipher = wlan_crypto_get_peer_param(peer, + WLAN_CRYPTO_PARAM_UCAST_CIPHER); + + return (ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_WEP)) || + ((ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_TKIP)) && + !(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_CCM)) && + !(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_GCM)) && + !(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_GCM_256)) && + !(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_CCM_256))); +} +qdf_export_symbol(wlan_crypto_is_htallowed); + static void initialize_send_iv(uint8_t *iv, uint8_t *init_iv) { int8_t i = 0; @@ -573,9 +631,9 @@ QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev, uint8_t bssid_mac[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; if (!vdev || !macaddr || (key_idx >= WLAN_CRYPTO_MAXKEYIDX)) { - qdf_print("%s[%d] Invalid params vdev %p, macaddr %p keyidx %d", - __func__, __LINE__, vdev, - macaddr, key_idx); + qdf_print("%s[%d] Invalid params vdev %p, macaddr %p keyidx %d\n", + __func__, __LINE__, vdev, + macaddr, key_idx); return QDF_STATUS_E_INVAL; } @@ -673,9 +731,8 @@ QDF_STATUS wlan_crypto_default_key(struct wlan_objmgr_vdev *vdev, wlan_vdev_obj_unlock(vdev); if (!vdev || !macaddr || (key_idx >= WLAN_CRYPTO_MAXKEYIDX)) { - qdf_print("%s[%d] Invalid params vdev %p, macaddr %p keyidx %d", - __func__, __LINE__, vdev, - macaddr, key_idx); + qdf_print("%s[%d] Invalid params vdev %p, macaddr %p keyidx %d\n", + __func__, __LINE__, vdev, macaddr, key_idx); return QDF_STATUS_E_INVAL; } if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)macaddr)) {