1 /*
2  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: wlan_cfg80211_wifi_pos.c
21  * defines wifi-pos module related driver functions interfacing with linux
22  * kernel
23  */
24 #include "wlan_cfg80211.h"
25 #include "wlan_objmgr_psoc_obj.h"
26 #include "wlan_cfg80211_wifi_pos.h"
27 #include "wlan_cmn_ieee80211.h"
28 #include "wifi_pos_ucfg_i.h"
29 
30 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT)
31 
32 u8 wlan_extended_caps_iface[WLAN_EXTCAP_IE_MAX_LEN] = {0};
33 u8 wlan_extended_caps_iface_mask[WLAN_EXTCAP_IE_MAX_LEN] = {0};
34 
35 struct wiphy_iftype_ext_capab iftype_ext_cap;
36 
37 #if !defined(CNSS_GENL) && (LINUX_VERSION_CODE == KERNEL_VERSION(5, 4, 0))
38 /**
39  * wlan_wifi_pos_cfg80211_set_auth_deauth_random_ta_flag() - API to set
40  * NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA flag
41  * @wiphy: Pointer to wiphy
42  * @psoc: Pointer to psoc
43  *
44  * Allow random TA to be used with authentication and deauthentication frames
45  * when MAC secured or MAC_PHY secured ranging is supported.
46  *
47  * Return: None
48  */
49 static void
wlan_wifi_pos_cfg80211_set_auth_deauth_random_ta_flag(struct wiphy * wiphy,struct wlan_objmgr_psoc * psoc)50 wlan_wifi_pos_cfg80211_set_auth_deauth_random_ta_flag(
51 		struct wiphy *wiphy,
52 		struct wlan_objmgr_psoc *psoc)
53 {
54 	if (wlan_psoc_nif_fw_ext2_cap_get(psoc, WLAN_RTT_11AZ_MAC_SEC_SUPPORT) ||
55 	    wlan_psoc_nif_fw_ext2_cap_get(psoc, WLAN_RTT_11AZ_MAC_PHY_SEC_SUPPORT))
56 		wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA);
57 }
58 #else
59 static void
wlan_wifi_pos_cfg80211_set_auth_deauth_random_ta_flag(struct wiphy * wiphy,struct wlan_objmgr_psoc * psoc)60 wlan_wifi_pos_cfg80211_set_auth_deauth_random_ta_flag(
61 		struct wiphy *wiphy,
62 		struct wlan_objmgr_psoc *psoc)
63 {
64 }
65 #endif
66 
67 #define WLAN_EXT_RANGING_CAP_IDX  11
68 void
wlan_wifi_pos_cfg80211_set_wiphy_ext_feature(struct wiphy * wiphy,struct wlan_objmgr_psoc * psoc)69 wlan_wifi_pos_cfg80211_set_wiphy_ext_feature(struct wiphy *wiphy,
70 					     struct wlan_objmgr_psoc *psoc)
71 {
72 	uint32_t enable_rsta_11az_ranging;
73 
74 	enable_rsta_11az_ranging = ucfg_wifi_pos_get_rsta_11az_ranging_cap();
75 	if (!enable_rsta_11az_ranging)
76 		return;
77 
78 	if ((enable_rsta_11az_ranging & CFG_RESPONDER_11AZ_NTB_SUPPORT) &&
79 	    (wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_RTT_11AZ_NTB_SUPPORT))) {
80 		wlan_extended_caps_iface[WLAN_EXT_RANGING_CAP_IDX] |=
81 					WLAN_EXT_CAPA11_NTB_RANGING_RESPONDER;
82 		wlan_extended_caps_iface_mask[WLAN_EXT_RANGING_CAP_IDX] |=
83 					WLAN_EXT_CAPA11_NTB_RANGING_RESPONDER;
84 	}
85 
86 	if ((enable_rsta_11az_ranging & CFG_RESPONDER_11AZ_TB_SUPPORT) &&
87 	    (wlan_psoc_nif_fw_ext2_cap_get(psoc, WLAN_RTT_11AZ_TB_SUPPORT) ||
88 	    wlan_psoc_nif_fw_ext2_cap_get(psoc,
89 					  WLAN_RTT_11AZ_TB_RSTA_SUPPORT))) {
90 		wlan_extended_caps_iface[WLAN_EXT_RANGING_CAP_IDX] |=
91 					WLAN_EXT_CAPA11_TB_RANGING_RESPONDER;
92 		wlan_extended_caps_iface_mask[WLAN_EXT_RANGING_CAP_IDX] |=
93 					WLAN_EXT_CAPA11_TB_RANGING_RESPONDER;
94 	}
95 
96 	wlan_wifi_pos_cfg80211_set_auth_deauth_random_ta_flag(wiphy, psoc);
97 
98 	iftype_ext_cap.iftype = NL80211_IFTYPE_AP;
99 	iftype_ext_cap.extended_capabilities =
100 				wlan_extended_caps_iface,
101 	iftype_ext_cap.extended_capabilities_mask =
102 				wlan_extended_caps_iface_mask,
103 	iftype_ext_cap.extended_capabilities_len =
104 				ARRAY_SIZE(wlan_extended_caps_iface),
105 
106 	wiphy->num_iftype_ext_capab = 0;
107 	wiphy->iftype_ext_capab = &iftype_ext_cap;
108 	wiphy->num_iftype_ext_capab++;
109 }
110 
111 #define NUM_BITS_IN_BYTE       8
112 static void
wlan_wifi_pos_set_feature_flags(uint8_t * feature_flags,enum qca_wlan_vendor_features feature)113 wlan_wifi_pos_set_feature_flags(uint8_t *feature_flags,
114 				enum qca_wlan_vendor_features feature)
115 {
116 	uint32_t index;
117 	uint8_t bit_mask;
118 
119 	index = feature / NUM_BITS_IN_BYTE;
120 	bit_mask = 1 << (feature % NUM_BITS_IN_BYTE);
121 	feature_flags[index] |= bit_mask;
122 }
123 
wlan_wifi_pos_cfg80211_set_features(struct wlan_objmgr_psoc * psoc,uint8_t * feature_flags)124 void wlan_wifi_pos_cfg80211_set_features(struct wlan_objmgr_psoc *psoc,
125 					 uint8_t *feature_flags)
126 {
127 	bool rsta_secure_ltf_support, enable_rsta_11az_ranging;
128 
129 	enable_rsta_11az_ranging = ucfg_wifi_pos_get_rsta_11az_ranging_cap();
130 	rsta_secure_ltf_support = enable_rsta_11az_ranging &&
131 				wifi_pos_get_rsta_sec_ltf_cap();
132 	if (wlan_psoc_nif_fw_ext2_cap_get(psoc,
133 					  WLAN_RTT_11AZ_MAC_PHY_SEC_SUPPORT)) {
134 		wlan_wifi_pos_set_feature_flags(feature_flags,
135 						QCA_WLAN_VENDOR_FEATURE_SECURE_LTF_STA);
136 		if (rsta_secure_ltf_support)
137 			wlan_wifi_pos_set_feature_flags(feature_flags,
138 							QCA_WLAN_VENDOR_FEATURE_SECURE_LTF_AP);
139 	}
140 
141 	if (wlan_psoc_nif_fw_ext2_cap_get(psoc,
142 					  WLAN_RTT_11AZ_MAC_SEC_SUPPORT)) {
143 		wlan_wifi_pos_set_feature_flags(feature_flags,
144 			QCA_WLAN_VENDOR_FEATURE_PROT_RANGE_NEGO_AND_MEASURE_STA);
145 		if (rsta_secure_ltf_support)
146 			wlan_wifi_pos_set_feature_flags(feature_flags,
147 							QCA_WLAN_VENDOR_FEATURE_PROT_RANGE_NEGO_AND_MEASURE_AP);
148 	}
149 }
150 #endif
151