blob: 533942a9059851319a0909d39c567c4b5133a14c [file] [log] [blame]
Srinivas Dasaridc488942018-01-24 19:35:19 +05301/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved.
Ahmad Kholaif159de4f2015-03-23 16:02:05 -07002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "sync.h"
30#define LOG_TAG "WifiHAL"
31#include <utils/Log.h>
32#include <time.h>
Ajay Dudani65b8c552015-04-11 22:52:06 -070033#include <errno.h>
Amarnath Hullur Subramanyamb131c772015-08-06 14:22:50 -070034#include <stdlib.h>
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -080035#include <unistd.h>
Khanjan Desai80f78492020-03-03 00:04:51 +053036#include <string>
37#include <net/if.h>
38#include <vector>
Khanjan Desai3dfdeb32021-10-13 15:03:09 +053039#include <sys/ioctl.h>
40#include <net/if.h>
41#include <net/if_arp.h>
42#include <sys/socket.h>
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070043#include "wificonfigcommand.h"
44
45/* Implementation of the API functions exposed in wifi_config.h */
46wifi_error wifi_extended_dtim_config_set(wifi_request_id id,
47 wifi_interface_handle iface,
48 int extended_dtim)
49{
Srinivas Dasari30b13c72017-08-08 15:44:23 +053050 wifi_error ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070051 WiFiConfigCommand *wifiConfigCommand;
52 struct nlattr *nlData;
53 interface_info *ifaceInfo = getIfaceInfo(iface);
54 wifi_handle wifiHandle = getWifiHandle(iface);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070055
Subhani Shaikeb97b6e2016-03-29 11:33:25 +053056 ALOGV("%s: extended_dtim:%d", __FUNCTION__, extended_dtim);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070057
58 wifiConfigCommand = new WiFiConfigCommand(
59 wifiHandle,
60 id,
61 OUI_QCA,
62 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
63
64 if (wifiConfigCommand == NULL) {
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +053065 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070066 return WIFI_ERROR_UNKNOWN;
67 }
68
69 /* Create the NL message. */
70 ret = wifiConfigCommand->create();
Srinivas Dasari30b13c72017-08-08 15:44:23 +053071 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070072 ALOGE("wifi_extended_dtim_config_set: failed to create NL msg. "
73 "Error:%d", ret);
74 goto cleanup;
75 }
76
77 /* Set the interface Id of the message. */
78 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
Srinivas Dasari30b13c72017-08-08 15:44:23 +053079 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070080 ALOGE("wifi_extended_dtim_config_set: failed to set iface id. "
81 "Error:%d", ret);
82 goto cleanup;
83 }
84
85 /* Add the vendor specific attributes for the NL command. */
86 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
87 if (!nlData) {
88 ALOGE("wifi_extended_dtim_config_set: failed attr_start for "
89 "VENDOR_DATA. Error:%d", ret);
90 goto cleanup;
91 }
92
Srinivas Dasari30b13c72017-08-08 15:44:23 +053093 ret = wifiConfigCommand->put_u32(
Srinivas Dasaric0854c72018-06-14 16:55:55 +053094 QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_DTIM, extended_dtim);
Srinivas Dasari30b13c72017-08-08 15:44:23 +053095 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070096 ALOGE("wifi_extended_dtim_config_set(): failed to put vendor data. "
97 "Error:%d", ret);
98 goto cleanup;
99 }
100 wifiConfigCommand->attr_end(nlData);
101
102 /* Send the NL msg. */
103 wifiConfigCommand->waitForRsp(false);
104 ret = wifiConfigCommand->requestEvent();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530105 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700106 ALOGE("wifi_extended_dtim_config_set(): requestEvent Error:%d", ret);
107 goto cleanup;
108 }
109
110cleanup:
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700111 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530112 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700113}
114
Peng Xu2eef57d2018-03-14 14:11:37 -0700115int check_feature(enum qca_wlan_vendor_features feature, features_info *info)
116{
117 size_t idx = feature / 8;
118
119 return (idx < info->flags_len) &&
120 (info->flags[idx] & BIT(feature % 8));
121}
122
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700123/* Set the country code to driver. */
124wifi_error wifi_set_country_code(wifi_interface_handle iface,
125 const char* country_code)
126{
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530127 int requestId;
128 wifi_error ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700129 WiFiConfigCommand *wifiConfigCommand;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700130 wifi_handle wifiHandle = getWifiHandle(iface);
Peng Xu2eef57d2018-03-14 14:11:37 -0700131 hal_info *info = getHalInfo(wifiHandle);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700132
Subhani Shaikeb97b6e2016-03-29 11:33:25 +0530133 ALOGV("%s: %s", __FUNCTION__, country_code);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700134
135 /* No request id from caller, so generate one and pass it on to the driver.
136 * Generate it randomly.
137 */
Amarnath Hullur Subramanyamb131c772015-08-06 14:22:50 -0700138 requestId = get_requestid();
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700139
140 wifiConfigCommand = new WiFiConfigCommand(
141 wifiHandle,
142 requestId,
143 OUI_QCA,
144 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
145 if (wifiConfigCommand == NULL) {
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530146 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700147 return WIFI_ERROR_UNKNOWN;
148 }
149
150 /* Create the NL message with NL80211_CMD_REQ_SET_REG NL cmd. */
151 ret = wifiConfigCommand->create_generic(NL80211_CMD_REQ_SET_REG);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530152 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700153 ALOGE("wifi_set_country_code: failed to create NL msg. Error:%d", ret);
154 goto cleanup;
155 }
156
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530157 ret = wifiConfigCommand->put_string(NL80211_ATTR_REG_ALPHA2, country_code);
158 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700159 ALOGE("wifi_set_country_code: put country code failed. Error:%d", ret);
160 goto cleanup;
161 }
162
Peng Xu2eef57d2018-03-14 14:11:37 -0700163 if (check_feature(QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY,
164 &info->driver_supported_features)) {
165 ret = wifiConfigCommand->put_u32(NL80211_ATTR_USER_REG_HINT_TYPE,
166 NL80211_USER_REG_HINT_CELL_BASE);
167 if (ret != WIFI_SUCCESS) {
168 ALOGE("wifi_set_country_code: put reg hint type failed. Error:%d",
169 ret);
170 goto cleanup;
171 }
172 }
173
174
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700175 /* Send the NL msg. */
176 wifiConfigCommand->waitForRsp(false);
177 ret = wifiConfigCommand->requestEvent();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530178 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700179 ALOGE("wifi_set_country_code(): requestEvent Error:%d", ret);
180 goto cleanup;
181 }
Srinivas Dasari02d14ee2015-08-19 16:52:08 +0530182 usleep(WAIT_TIME_FOR_SET_REG_DOMAIN);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700183
184cleanup:
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700185 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530186 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700187}
188
Jian Tang95979d72017-11-16 16:52:30 +0800189/*
190 * Set the powersave to driver.
191 */
192wifi_error wifi_set_qpower(wifi_interface_handle iface,
193 u8 powersave)
194{
195 int requestId, ret = 0;
196 WiFiConfigCommand *wifiConfigCommand;
197 struct nlattr *nlData;
198 interface_info *ifaceInfo = getIfaceInfo(iface);
199 wifi_handle wifiHandle = getWifiHandle(iface);
200 //hal_info *info = getHalInfo(wifiHandle);
201
202 ALOGD("%s: %d", __FUNCTION__, powersave);
203
204 requestId = get_requestid();
205
206 wifiConfigCommand = new WiFiConfigCommand(
207 wifiHandle,
208 requestId,
209 OUI_QCA,
210 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
211
212 if (wifiConfigCommand == NULL) {
213 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
214 return WIFI_ERROR_UNKNOWN;
215 }
216
217 /* Create the NL message. */
218 ret = wifiConfigCommand->create();
219 if (ret < 0) {
220 ALOGE("wifi_set_qpower: failed to create NL msg. "
221 "Error:%d", ret);
222 goto cleanup;
223 }
224
225 /* Set the interface Id of the message. */
226 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
227 if (ret < 0) {
228 ALOGE("wifi_set_qpower: failed to set iface id. "
229 "Error:%d", ret);
230 goto cleanup;
231 }
232
233 /* Add the vendor specific attributes for the NL command. */
234 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
235 if (!nlData) {
236 ALOGE("wifi_set_qpower: failed attr_start for "
237 "VENDOR_DATA. Error:%d", ret);
238 goto cleanup;
239 }
240
241 if (wifiConfigCommand->put_u8(
Srinivas Dasaric0854c72018-06-14 16:55:55 +0530242 QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER, powersave)) {
Jian Tang95979d72017-11-16 16:52:30 +0800243 ALOGE("wifi_set_qpower(): failed to put vendor data. "
244 "Error:%d", ret);
245 goto cleanup;
246 }
247 wifiConfigCommand->attr_end(nlData);
248
249 /* Send the NL msg. */
250 wifiConfigCommand->waitForRsp(false);
251 ret = wifiConfigCommand->requestEvent();
252 if (ret != 0) {
253 ALOGE("wifi_set_qpower(): requestEvent Error:%d", ret);
254 goto cleanup;
255 }
256
257cleanup:
258 delete wifiConfigCommand;
259 return (wifi_error)ret;
260
261}
262
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700263wifi_error wifi_set_beacon_wifi_iface_stats_averaging_factor(
264 wifi_request_id id,
265 wifi_interface_handle iface,
266 u16 factor)
267{
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530268 wifi_error ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700269 WiFiConfigCommand *wifiConfigCommand;
270 struct nlattr *nlData;
271 interface_info *ifaceInfo = getIfaceInfo(iface);
272 wifi_handle wifiHandle = getWifiHandle(iface);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700273
Subhani Shaikeb97b6e2016-03-29 11:33:25 +0530274 ALOGV("%s factor:%u", __FUNCTION__, factor);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700275 wifiConfigCommand = new WiFiConfigCommand(
276 wifiHandle,
277 id,
278 OUI_QCA,
279 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
280 if (wifiConfigCommand == NULL) {
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530281 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700282 return WIFI_ERROR_UNKNOWN;
283 }
284
285 /* Create the NL message. */
286 ret = wifiConfigCommand->create();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530287 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700288 ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed to "
289 "create NL msg. Error:%d", ret);
290 goto cleanup;
291 }
292
293 /* Set the interface Id of the message. */
294 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530295 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700296 ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed to "
297 "set iface id. Error:%d", ret);
298 goto cleanup;
299 }
300
301 /* Add the vendor specific attributes for the NL command. */
302 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
303 if (!nlData) {
304 ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed "
305 "attr_start for VENDOR_DATA. Error:%d", ret);
306 goto cleanup;
307 }
308
309 if (wifiConfigCommand->put_u32(
Srinivas Dasaric0854c72018-06-14 16:55:55 +0530310 QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR, factor)) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700311 ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor(): failed to "
312 "put vendor data. Error:%d", ret);
313 goto cleanup;
314 }
315 wifiConfigCommand->attr_end(nlData);
316
317 /* Send the NL msg. */
318 wifiConfigCommand->waitForRsp(false);
319 ret = wifiConfigCommand->requestEvent();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530320 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700321 ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor(): "
322 "requestEvent Error:%d", ret);
323 goto cleanup;
324 }
325
326cleanup:
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700327 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530328 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700329}
330
331wifi_error wifi_set_guard_time(wifi_request_id id,
332 wifi_interface_handle iface,
333 u32 guard_time)
334{
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530335 wifi_error ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700336 WiFiConfigCommand *wifiConfigCommand;
337 struct nlattr *nlData;
338 interface_info *ifaceInfo = getIfaceInfo(iface);
339 wifi_handle wifiHandle = getWifiHandle(iface);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700340
Subhani Shaikeb97b6e2016-03-29 11:33:25 +0530341 ALOGV("%s : guard_time:%u", __FUNCTION__, guard_time);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700342
343 wifiConfigCommand = new WiFiConfigCommand(
344 wifiHandle,
345 id,
346 OUI_QCA,
347 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
348 if (wifiConfigCommand == NULL) {
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530349 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700350 return WIFI_ERROR_UNKNOWN;
351 }
352
353 /* Create the NL message. */
354 ret = wifiConfigCommand->create();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530355 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700356 ALOGE("wifi_set_guard_time: failed to create NL msg. Error:%d", ret);
357 goto cleanup;
358 }
359
360 /* Set the interface Id of the message. */
361 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530362 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700363 ALOGE("wifi_set_guard_time: failed to set iface id. Error:%d", ret);
364 goto cleanup;
365 }
366
367 /* Add the vendor specific attributes for the NL command. */
368 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
369 if (!nlData) {
370 ALOGE("wifi_set_guard_time: failed attr_start for VENDOR_DATA. "
371 "Error:%d", ret);
372 goto cleanup;
373 }
374
375 if (wifiConfigCommand->put_u32(
Srinivas Dasaric0854c72018-06-14 16:55:55 +0530376 QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME, guard_time)) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700377 ALOGE("wifi_set_guard_time: failed to add vendor data.");
378 goto cleanup;
379 }
380 wifiConfigCommand->attr_end(nlData);
381
382 /* Send the NL msg. */
383 wifiConfigCommand->waitForRsp(false);
384 ret = wifiConfigCommand->requestEvent();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530385 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700386 ALOGE("wifi_set_guard_time(): requestEvent Error:%d", ret);
387 goto cleanup;
388 }
389
390cleanup:
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700391 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530392 return ret;
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -0800393}
394
395wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle,
396 wifi_power_scenario scenario)
397{
398 wifi_error ret;
399 WiFiConfigCommand *wifiConfigCommand;
400 struct nlattr *nlData;
401 interface_info *ifaceInfo = getIfaceInfo(handle);
402 wifi_handle wifiHandle = getWifiHandle(handle);
403 u32 bdf_file = 0;
404
zhangjie70cdc9c2021-06-07 09:52:45 +0800405 /* The set(0~4) we will read in bdwlan.bin */
406 u32 set_sar_number = 1;
407 u32 chip_mimo_number = 2;
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -0800408 ALOGV("%s : power scenario:%d", __FUNCTION__, scenario);
409
410 wifiConfigCommand = new WiFiConfigCommand(
411 wifiHandle,
412 1,
413 OUI_QCA,
414 QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS);
415 if (wifiConfigCommand == NULL) {
416 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
417 return WIFI_ERROR_UNKNOWN;
418 }
419
420 /* Create the NL message. */
421 ret = wifiConfigCommand->create();
422 if (ret != WIFI_SUCCESS) {
423 ALOGE("wifi_select_tx_power_scenario: failed to create NL msg. Error:%d", ret);
424 goto cleanup;
425 }
426
427 /* Set the interface Id of the message. */
428 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
429 if (ret != WIFI_SUCCESS) {
430 ALOGE("wifi_select_tx_power_scenario: failed to set iface id. Error:%d", ret);
431 goto cleanup;
432 }
433
434 /* Add the vendor specific attributes for the NL command. */
435 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
436 if (!nlData) {
437 ALOGE("wifi_select_tx_power_scenario: failed attr_start for VENDOR_DATA. "
438 "Error:%d", ret);
439 goto cleanup;
440 }
441
Srinivas Girigowda8e444fd2018-04-12 07:53:40 -0700442 switch (scenario) {
443 case WIFI_POWER_SCENARIO_VOICE_CALL:
444 case WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF:
zhangjie70cdc9c2021-06-07 09:52:45 +0800445 // bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0;
446 bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE;
447 set_sar_number = 1;
Srinivas Girigowda8e444fd2018-04-12 07:53:40 -0700448 break;
449
450 case WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON:
zhangjie70cdc9c2021-06-07 09:52:45 +0800451 // bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1;
452 bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0;
453 set_sar_number = 0;
Srinivas Girigowda8e444fd2018-04-12 07:53:40 -0700454 break;
455
456 case WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF:
457 bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2;
zhangjie70cdc9c2021-06-07 09:52:45 +0800458 set_sar_number = 3;
Srinivas Girigowda8e444fd2018-04-12 07:53:40 -0700459 break;
460
461 case WIFI_POWER_SCENARIO_ON_BODY_CELL_ON:
462 bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3;
zhangjie70cdc9c2021-06-07 09:52:45 +0800463 set_sar_number = 2;
Srinivas Girigowda8e444fd2018-04-12 07:53:40 -0700464 break;
465
466 default:
467 ALOGE("wifi_select_tx_power_scenario: invalid scenario %d", scenario);
468 ret = WIFI_ERROR_INVALID_ARGS;
469 goto cleanup;
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -0800470 }
Srinivas Girigowda8e444fd2018-04-12 07:53:40 -0700471
zhangjie70cdc9c2021-06-07 09:52:45 +0800472 wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS, chip_mimo_number);
473 struct nlattr *nlData_spec, *nlData_spec_attr;
474 nlData_spec = wifiConfigCommand->attr_start(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC);
475 for (int i = 0; i < chip_mimo_number; i++) {
476 nlData_spec_attr = wifiConfigCommand->attr_start(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX);
477 wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX, set_sar_number);
478 wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN, i);
479 wifiConfigCommand->attr_end(nlData_spec_attr);
480 }
481 wifiConfigCommand->attr_end(nlData_spec);
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -0800482 if (wifiConfigCommand->put_u32(
483 QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE,
zhangjie70cdc9c2021-06-07 09:52:45 +0800484 QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0)) {
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -0800485 ALOGE("failed to put SAR_ENABLE");
486 goto cleanup;
487 }
488 wifiConfigCommand->attr_end(nlData);
489
490 ret = wifiConfigCommand->requestEvent();
491 if (ret != WIFI_SUCCESS) {
492 ALOGE("wifi_select_tx_power_scenario(): requestEvent Error:%d", ret);
493 goto cleanup;
494 }
495
496cleanup:
497 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530498 return ret;
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -0800499}
500
501wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle)
502{
503 wifi_error ret;
504 WiFiConfigCommand *wifiConfigCommand;
505 struct nlattr *nlData;
506 interface_info *ifaceInfo = getIfaceInfo(handle);
507 wifi_handle wifiHandle = getWifiHandle(handle);
508
509 wifiConfigCommand = new WiFiConfigCommand(
510 wifiHandle,
511 1,
512 OUI_QCA,
513 QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS);
514 if (wifiConfigCommand == NULL) {
515 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
516 return WIFI_ERROR_UNKNOWN;
517 }
518
519 /* Create the NL message. */
520 ret = wifiConfigCommand->create();
521 if (ret != WIFI_SUCCESS) {
522 ALOGE("wifi_reset_tx_power_scenario: failed to create NL msg. Error:%d", ret);
523 goto cleanup;
524 }
525
526 /* Set the interface Id of the message. */
527 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
528 if (ret != WIFI_SUCCESS) {
529 ALOGE("wifi_reset_tx_power_scenario: failed to set iface id. Error:%d", ret);
530 goto cleanup;
531 }
532
533 /* Add the vendor specific attributes for the NL command. */
534 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
535 if (!nlData) {
536 ALOGE("wifi_reset_tx_power_scenario: failed attr_start for VENDOR_DATA. "
537 "Error:%d", ret);
538 goto cleanup;
539 }
540
541 if (wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE,
542 QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE)) {
543 ALOGE("failed to put SAR_ENABLE or NUM_SPECS");
544 goto cleanup;
545 }
546 wifiConfigCommand->attr_end(nlData);
547
548 ret = wifiConfigCommand->requestEvent();
549 if (ret != WIFI_SUCCESS) {
550 ALOGE("wifi_reset_tx_power_scenario(): requestEvent Error:%d", ret);
551 goto cleanup;
552 }
553
554cleanup:
555 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530556 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700557}
558
Vamsi Krishna4b90cd52020-02-03 10:11:34 +0530559wifi_error wifi_set_thermal_mitigation_mode(wifi_handle handle,
560 wifi_thermal_mode mode,
561 u32 completion_window)
562{
563 wifi_error ret;
564 WiFiConfigCommand *wifiConfigCommand;
565 struct nlattr *nlData;
566 u32 qca_vendor_thermal_level;
567 hal_info *info = getHalInfo(handle);
568
569 if (!info || info->num_interfaces < 1) {
570 ALOGE("%s: Error wifi_handle NULL or base wlan interface not present",
571 __FUNCTION__);
572 return WIFI_ERROR_UNKNOWN;
573 }
574
575 wifiConfigCommand = new WiFiConfigCommand(
576 handle,
577 1,
578 OUI_QCA,
579 QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD);
580 if (wifiConfigCommand == NULL) {
581 ALOGE("%s: Error, Failed to create wifiConfigCommand", __FUNCTION__);
582 return WIFI_ERROR_UNKNOWN;
583 }
584
585 /* Create the NL message. */
586 ret = wifiConfigCommand->create();
587 if (ret != WIFI_SUCCESS) {
588 ALOGE("Failed to create thermal vendor command, Error:%d", ret);
589 goto cleanup;
590 }
591
592 /* Set the interface Id of the message. */
593 if (wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
594 info->interfaces[0]->id)) {
595 ALOGE("%s: Failed to put iface id", __FUNCTION__);
596 goto cleanup;
597 }
598
599 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
600 if (!nlData) {
601 ALOGE("%s: Failed in attr_start for VENDOR_DATA, Error:%d",
602 __FUNCTION__, ret);
603 goto cleanup;
604 }
605
606 if (wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE,
607 QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL)) {
608 ALOGE("Failed to put THERMAL_LEVEL command type");
609 goto cleanup;
610 }
611
612 switch(mode) {
613 case WIFI_MITIGATION_NONE:
614 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE;
615 break;
616 case WIFI_MITIGATION_LIGHT:
617 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_LIGHT;
618 break;
619 case WIFI_MITIGATION_MODERATE:
620 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_MODERATE;
621 break;
622 case WIFI_MITIGATION_SEVERE:
623 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_SEVERE;
624 break;
625 case WIFI_MITIGATION_CRITICAL:
626 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_CRITICAL;
627 break;
628 case WIFI_MITIGATION_EMERGENCY:
629 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_EMERGENCY;
630 break;
631 default:
632 ALOGE("Unknown thermal mitigation level %d", mode);
633 ret = WIFI_ERROR_UNKNOWN;
634 goto cleanup;
635 }
636
637 if (wifiConfigCommand->put_u32(
638 QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL,
639 qca_vendor_thermal_level)) {
640 ALOGE("Failed to put thermal level");
641 goto cleanup;
642 }
643
644 if (wifiConfigCommand->put_u32(
645 QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW,
646 completion_window)) {
647 ALOGE("Failed to put thermal completion window");
648 goto cleanup;
649 }
650 wifiConfigCommand->attr_end(nlData);
651
652 wifiConfigCommand->waitForRsp(false);
653 ret = wifiConfigCommand->requestEvent();
654 if (ret != WIFI_SUCCESS) {
655 ALOGE("Failed to set thermal level with Error: %d", ret);
656 goto cleanup;
657 }
658
659cleanup:
660 delete wifiConfigCommand;
661 return ret;
662}
663
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700664WiFiConfigCommand::WiFiConfigCommand(wifi_handle handle,
665 int id, u32 vendor_id,
666 u32 subcmd)
667 : WifiVendorCommand(handle, id, vendor_id, subcmd)
668{
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700669 /* Initialize the member data variables here */
670 mWaitforRsp = false;
671 mRequestId = id;
672}
673
674WiFiConfigCommand::~WiFiConfigCommand()
675{
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700676 unregisterVendorHandler(mVendor_id, mSubcmd);
677}
678
679/* This function implements creation of Vendor command */
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530680wifi_error WiFiConfigCommand::create()
681{
682 wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
683 if (ret != WIFI_SUCCESS)
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700684 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700685
686 /* Insert the oui in the msg */
687 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530688 if (ret != WIFI_SUCCESS)
689 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700690 /* Insert the subcmd in the msg */
691 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530692
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700693 return ret;
694}
695
696/* This function implements creation of generic NL command */
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530697wifi_error WiFiConfigCommand::create_generic(u8 cmdId)
698{
699 wifi_error ret = mMsg.create(cmdId, 0, 0);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700700 return ret;
701}
702
703void WiFiConfigCommand::waitForRsp(bool wait)
704{
705 mWaitforRsp = wait;
706}
707
708/* Callback handlers registered for nl message send */
709static int error_handler_wifi_config(struct sockaddr_nl *nla,
710 struct nlmsgerr *err,
711 void *arg)
712{
713 struct sockaddr_nl *tmp;
714 int *ret = (int *)arg;
715 tmp = nla;
716 *ret = err->error;
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530717 ALOGE("%s: Error code:%d (%s)", __FUNCTION__, *ret, strerror(-(*ret)));
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700718 return NL_STOP;
719}
720
721/* Callback handlers registered for nl message send */
722static int ack_handler_wifi_config(struct nl_msg *msg, void *arg)
723{
724 int *ret = (int *)arg;
725 struct nl_msg * a;
726
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700727 a = msg;
728 *ret = 0;
729 return NL_STOP;
730}
731
732/* Callback handlers registered for nl message send */
733static int finish_handler_wifi_config(struct nl_msg *msg, void *arg)
734{
735 int *ret = (int *)arg;
736 struct nl_msg * a;
737
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700738 a = msg;
739 *ret = 0;
740 return NL_SKIP;
741}
742
743/*
744 * Override base class requestEvent and implement little differently here.
745 * This will send the request message.
746 * We don't wait for any response back in case of wificonfig,
747 * thus no wait for condition.
748 */
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530749wifi_error WiFiConfigCommand::requestEvent()
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700750{
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530751 int status;
752 wifi_error res = WIFI_SUCCESS;
Hu Wangc1a19012019-04-15 15:35:12 +0800753 struct nl_cb *cb = NULL;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700754
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700755 cb = nl_cb_alloc(NL_CB_DEFAULT);
756 if (!cb) {
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530757 ALOGE("%s: Callback allocation failed",__FUNCTION__);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530758 res = WIFI_ERROR_OUT_OF_MEMORY;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700759 goto out;
760 }
761
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530762 status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
763 if (status < 0) {
764 res = mapKernelErrortoWifiHalError(status);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700765 goto out;
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530766 }
767 status = 1;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700768
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530769 nl_cb_err(cb, NL_CB_CUSTOM, error_handler_wifi_config, &status);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700770 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_wifi_config,
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530771 &status);
772 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_wifi_config, &status);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700773
774 /* Err is populated as part of finish_handler. */
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530775 while (status > 0) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700776 nl_recvmsgs(mInfo->cmd_sock, cb);
777 }
778
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530779 if (status < 0) {
780 res = mapKernelErrortoWifiHalError(status);
781 goto out;
782 }
783
784 if (mWaitforRsp == true) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700785 struct timespec abstime;
786 abstime.tv_sec = 4;
787 abstime.tv_nsec = 0;
788 res = mCondition.wait(abstime);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530789 if (res == WIFI_ERROR_TIMED_OUT)
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530790 ALOGE("%s: Time out happened.", __FUNCTION__);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530791
Subhani Shaikeb97b6e2016-03-29 11:33:25 +0530792 ALOGV("%s: Command invoked return value:%d, mWaitForRsp=%d",
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530793 __FUNCTION__, res, mWaitforRsp);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700794 }
795out:
Hu Wangc1a19012019-04-15 15:35:12 +0800796 nl_cb_put(cb);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700797 /* Cleanup the mMsg */
798 mMsg.destroy();
799 return res;
800}
801
Khanjan Desai80f78492020-03-03 00:04:51 +0530802
803
804static std::vector<std::string> added_ifaces;
805
806static bool is_dynamic_interface(const char * ifname)
807{
808 for (const auto& iface : added_ifaces) {
809 if (iface == std::string(ifname))
810 return true;
811 }
812 return false;
813}
814
815void wifi_cleanup_dynamic_ifaces(wifi_handle handle)
816{
817 int len = added_ifaces.size();
818 while (len--) {
819 wifi_virtual_interface_delete(handle, added_ifaces.front().c_str());
820 }
821 added_ifaces.clear(); // could be redundent. But to be on safe side.
822}
823
Hu Wang2a4e1a82020-03-24 10:57:49 +0800824static wifi_error wifi_set_interface_mode(wifi_handle handle,
825 const char* ifname,
826 u32 iface_type)
827{
828 wifi_error ret;
829 WiFiConfigCommand *wifiConfigCommand;
830
831 ALOGD("%s: ifname=%s iface_type=%u", __FUNCTION__, ifname, iface_type);
832
833 wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0);
834 if (wifiConfigCommand == NULL) {
835 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
836 return WIFI_ERROR_UNKNOWN;
837 }
838
839 nl80211_iftype type;
840 switch(iface_type) {
841 case WIFI_INTERFACE_TYPE_STA: /* IfaceType:STA */
842 type = NL80211_IFTYPE_STATION;
843 break;
844 case WIFI_INTERFACE_TYPE_AP: /* IfaceType:AP */
845 type = NL80211_IFTYPE_AP;
846 break;
847 case WIFI_INTERFACE_TYPE_P2P: /* IfaceType:P2P */
848 type = NL80211_IFTYPE_P2P_DEVICE;
849 break;
850 case WIFI_INTERFACE_TYPE_NAN: /* IfaceType:NAN */
851 type = NL80211_IFTYPE_NAN;
852 break;
853 default:
854 ALOGE("%s: Wrong interface type %u", __FUNCTION__, iface_type);
855 ret = WIFI_ERROR_UNKNOWN;
856 goto done;
857 break;
858 }
859 wifiConfigCommand->create_generic(NL80211_CMD_SET_INTERFACE);
860 wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname));
861 wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE, type);
862
863 /* Send the NL msg. */
864 wifiConfigCommand->waitForRsp(false);
865 ret = wifiConfigCommand->requestEvent();
866 if (ret != WIFI_SUCCESS) {
867 ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
868 }
869
870done:
871 delete wifiConfigCommand;
872 return ret;
873}
874
Khanjan Desai80f78492020-03-03 00:04:51 +0530875wifi_error wifi_virtual_interface_create(wifi_handle handle,
876 const char* ifname,
877 wifi_interface_type iface_type)
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530878{
879 wifi_error ret;
880 WiFiConfigCommand *wifiConfigCommand;
Khanjan Desai3dfce202020-03-18 18:02:40 +0530881 hal_info *info = getHalInfo(handle);
882 if (!info || info->num_interfaces < 1) {
883 ALOGE("%s: Error wifi_handle NULL or base wlan interface not present", __FUNCTION__);
Khanjan Desai80f78492020-03-03 00:04:51 +0530884 return WIFI_ERROR_UNKNOWN;
885 }
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530886
Hu Wang2a4e1a82020-03-24 10:57:49 +0800887 // Already exists and set interface mode only
888 if (if_nametoindex(ifname) != 0) {
889 return wifi_set_interface_mode(handle, ifname, iface_type);
890 }
891
Khanjan Desai80f78492020-03-03 00:04:51 +0530892 ALOGD("%s: ifname=%s create", __FUNCTION__, ifname);
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530893
Khanjan Desai80f78492020-03-03 00:04:51 +0530894 wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0);
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530895 if (wifiConfigCommand == NULL) {
896 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
897 return WIFI_ERROR_UNKNOWN;
898 }
899
Khanjan Desai80f78492020-03-03 00:04:51 +0530900 nl80211_iftype type;
901 switch(iface_type) {
902 case WIFI_INTERFACE_TYPE_STA: /* IfaceType:STA */
903 type = NL80211_IFTYPE_STATION;
904 break;
905 case WIFI_INTERFACE_TYPE_AP: /* IfaceType:AP */
906 type = NL80211_IFTYPE_AP;
907 break;
908 case WIFI_INTERFACE_TYPE_P2P: /* IfaceType:P2P */
909 type = NL80211_IFTYPE_P2P_DEVICE;
910 break;
Swarn Singhc2c9bc82019-12-05 18:08:27 +0530911 case WIFI_INTERFACE_TYPE_NAN: /* IfaceType:NAN */
912 type = NL80211_IFTYPE_NAN;
913 break;
Khanjan Desai80f78492020-03-03 00:04:51 +0530914 default:
915 ALOGE("%s: Wrong interface type %u", __FUNCTION__, iface_type);
916 ret = WIFI_ERROR_UNKNOWN;
917 goto done;
918 break;
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530919 }
Khanjan Desai80f78492020-03-03 00:04:51 +0530920 wifiConfigCommand->create_generic(NL80211_CMD_NEW_INTERFACE);
Khanjan Desai3dfce202020-03-18 18:02:40 +0530921 wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,info->interfaces[0]->id);
Khanjan Desai80f78492020-03-03 00:04:51 +0530922 wifiConfigCommand->put_string(NL80211_ATTR_IFNAME, ifname);
923 wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE, type);
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530924 /* Send the NL msg. */
925 wifiConfigCommand->waitForRsp(false);
926 ret = wifiConfigCommand->requestEvent();
Khanjan Desai80f78492020-03-03 00:04:51 +0530927 if (ret != WIFI_SUCCESS) {
928 ALOGE("%s: requestEvent Error:%d", __FUNCTION__,ret);
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530929 }
Khanjan Desai80f78492020-03-03 00:04:51 +0530930 // Update dynamic interface list
931 added_ifaces.push_back(std::string(ifname));
Khanjan Desai3dfdeb32021-10-13 15:03:09 +0530932 if (iface_type == WIFI_INTERFACE_TYPE_STA) {
933 int sock = socket(AF_INET, SOCK_DGRAM, 0);
934 if(sock < 0) {
935 ALOGE("%s :socket error, Failed to bring up iface \n", __func__);
936 goto done;
937 }
938 struct ifreq ifr;
939 memset(&ifr, 0, sizeof(ifr));
940 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
941 if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
942 ALOGE("%s :Could not read interface %s flags \n", __func__, ifname);
943 goto done;
944 }
945 ifr.ifr_flags |= IFF_UP;
946 if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
947 ALOGE("%s :Could not bring iface %s up \n", __func__, ifname);
948 }
949 }
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530950
951done:
952 delete wifiConfigCommand;
953 return ret;
954}
Hu Wang38714b62018-11-08 19:57:21 +0800955
Khanjan Desai80f78492020-03-03 00:04:51 +0530956wifi_error wifi_virtual_interface_delete(wifi_handle handle,
957 const char* ifname)
958{
959 wifi_error ret;
960 WiFiConfigCommand *wifiConfigCommand;
Khanjan Desai3dfce202020-03-18 18:02:40 +0530961 if (!handle) {
962 ALOGE("%s: Error wifi_handle NULL", __FUNCTION__);
Khanjan Desai80f78492020-03-03 00:04:51 +0530963 return WIFI_ERROR_UNKNOWN;
964 }
965
966 ALOGD("%s: ifname=%s delete", __FUNCTION__, ifname);
967 if (if_nametoindex(ifname) && !is_dynamic_interface(ifname)) {
968 // Do not remove interface if it was not added dynamically.
969 return WIFI_SUCCESS;
970 }
971 wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0);
972 if (wifiConfigCommand == NULL) {
973 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
974 return WIFI_ERROR_UNKNOWN;
975 }
976 wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE);
977 wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname));
978 /* Send the NL msg. */
979 wifiConfigCommand->waitForRsp(false);
980 ret = wifiConfigCommand->requestEvent();
981 if (ret != WIFI_SUCCESS) {
982 ALOGE("%s: requestEvent Error:%d", __FUNCTION__,ret);
983 }
984 // Update dynamic interface list
985 added_ifaces.erase(std::remove(added_ifaces.begin(), added_ifaces.end(), std::string(ifname)),
986 added_ifaces.end());
987
988 delete wifiConfigCommand;
989 return ret;
990}
991
Hu Wang38714b62018-11-08 19:57:21 +0800992/**
993 * Set latency level
994 */
995wifi_error wifi_set_latency_mode(wifi_interface_handle iface,
996 wifi_latency_mode mode)
997{
998 int requestId, ret = 0;
Hu Wangc1936352019-04-25 15:26:03 +0800999 u16 level;
Hu Wang38714b62018-11-08 19:57:21 +08001000 WiFiConfigCommand *wifiConfigCommand;
1001 struct nlattr *nlData;
1002 interface_info *ifaceInfo = getIfaceInfo(iface);
1003 wifi_handle wifiHandle = getWifiHandle(iface);
Sunil Dutt2447fbc2020-08-27 12:42:10 +05301004 hal_info *info = getHalInfo(wifiHandle);
Hu Wang38714b62018-11-08 19:57:21 +08001005
1006 ALOGD("%s: %d", __FUNCTION__, mode);
1007
Sunil Dutt2447fbc2020-08-27 12:42:10 +05301008 if (!(info->supported_feature_set & WIFI_FEATURE_SET_LATENCY_MODE)) {
1009 ALOGE("%s: Latency Mode is not supported by driver", __FUNCTION__);
1010 return WIFI_ERROR_NOT_SUPPORTED;
1011 };
1012
Hu Wangc1936352019-04-25 15:26:03 +08001013 switch (mode) {
1014 case WIFI_LATENCY_MODE_NORMAL:
1015 level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
1016 break;
1017 case WIFI_LATENCY_MODE_LOW:
1018 level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW;
1019 break;
1020 default:
1021 ALOGI("%s: Unsupported latency mode=%d, resetting to NORMAL!", __FUNCTION__, mode);
1022 level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
1023 break;
1024 }
1025
Hu Wang38714b62018-11-08 19:57:21 +08001026 requestId = get_requestid();
1027
1028 wifiConfigCommand = new WiFiConfigCommand(
1029 wifiHandle,
1030 requestId,
1031 OUI_QCA,
1032 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
1033
1034 if (wifiConfigCommand == NULL) {
1035 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
1036 return WIFI_ERROR_UNKNOWN;
1037 }
1038
1039 /* Create the NL message. */
1040 ret = wifiConfigCommand->create();
1041 if (ret < 0) {
1042 ALOGE("%s: failed to create NL msg. Error:%d",
1043 __FUNCTION__, ret);
1044 goto cleanup;
1045 }
1046
1047 /* Set the interface Id of the message. */
1048 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
1049 if (ret < 0) {
1050 ALOGE("%s: failed to set iface id. Error:%d",
1051 __FUNCTION__, ret);
1052 goto cleanup;
1053 }
1054
1055 /* Add the vendor specific attributes for the NL command. */
1056 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
1057 if (!nlData) {
1058 ALOGE("%s: failed attr_start for VENDOR_DATA. Error:%d",
1059 __FUNCTION__, ret);
1060 goto cleanup;
1061 }
1062
1063 if (wifiConfigCommand->put_u16(
Hu Wangc1936352019-04-25 15:26:03 +08001064 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL, level)) {
Hu Wang38714b62018-11-08 19:57:21 +08001065 ALOGE("%s: failed to put vendor data. Error:%d",
1066 __FUNCTION__, ret);
1067 goto cleanup;
1068 }
1069 wifiConfigCommand->attr_end(nlData);
1070
1071 /* Send the NL msg. */
1072 wifiConfigCommand->waitForRsp(false);
1073 ret = wifiConfigCommand->requestEvent();
1074 if (ret != 0) {
1075 ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
1076 goto cleanup;
1077 }
1078
1079cleanup:
1080 delete wifiConfigCommand;
1081 return (wifi_error)ret;
1082}