summaryrefslogtreecommitdiff
path: root/wcn6740
diff options
context:
space:
mode:
authorHsiu-Chang Chen <hsiuchangchen@google.com>2022-08-03 18:30:05 +0800
committerHsiu-Chang Chen <hsiuchangchen@google.com>2022-08-10 04:19:09 +0000
commit65cb184213990a90ea031c9f2337d463557483fb (patch)
treec626ae71caa73049112e646559d6158203187341 /wcn6740
parent7ecdf23eccadac177efa843060ef34cb6888c0d9 (diff)
downloadwlan-65cb184213990a90ea031c9f2337d463557483fb.tar.gz
WifiHal: Update the wifihal for wcn6740 to CS release
CLs list: wifi: Fix for compiling issue WifiHal: Add wifi_get_usable_channels into func pointers table wpa_supplicant_lib: Avoid double free when nl msg send fail wpa_supplicant_lib: peer flush tid queue command wifi_hal: fix potential memory leak wifi_hal: fix static analysis issues wpa_supplicant_lib_8: Do not print all parameters in TWT setup failure Subject: Implement standalone build files Bug: 241212055 Bug: 241724304 Test: Regression Test Change-Id: I6e10437ff741d3e4805da4cd3458d1be1c89c8fe
Diffstat (limited to 'wcn6740')
-rw-r--r--wcn6740/qcwcn/wifi_hal/radio_mode.cpp26
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifi_hal.cpp316
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c13
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am11
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac8
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c170
6 files changed, 362 insertions, 182 deletions
diff --git a/wcn6740/qcwcn/wifi_hal/radio_mode.cpp b/wcn6740/qcwcn/wifi_hal/radio_mode.cpp
index 913ddfd..f758073 100644
--- a/wcn6740/qcwcn/wifi_hal/radio_mode.cpp
+++ b/wcn6740/qcwcn/wifi_hal/radio_mode.cpp
@@ -169,7 +169,8 @@ int RADIOModeCommand::handleEvent(WifiEvent &event)
{
ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID"
" not found", __FUNCTION__);
- return WIFI_ERROR_INVALID_ARGS;
+ ret = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
}
mode_info.wlan_mac_id = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID]);
ALOGV("mac_id[%d]: %d ", num_of_mac, mode_info.wlan_mac_id);
@@ -178,7 +179,8 @@ int RADIOModeCommand::handleEvent(WifiEvent &event)
{
ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND"
" NOT FOUND", __FUNCTION__);
- return WIFI_ERROR_INVALID_ARGS;
+ ret = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
}
mode_info.mac_band = (wlan_mac_band) nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND]);
ALOGV("mac_band[%d]: %d ", num_of_mac, mode_info.mac_band);
@@ -203,7 +205,8 @@ int RADIOModeCommand::handleEvent(WifiEvent &event)
{
ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX"
" NOT FOUND", __FUNCTION__);
- return WIFI_ERROR_INVALID_ARGS;
+ ret = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
}
if (if_indextoname(nla_get_u32(tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX]),
miface_info.iface_name) == NULL)
@@ -217,7 +220,8 @@ int RADIOModeCommand::handleEvent(WifiEvent &event)
{
ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ"
" NOT FOUND", __FUNCTION__);
- return WIFI_ERROR_INVALID_ARGS;
+ ret = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
}
miface_info.channel = nla_get_u32(tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ]);
ALOGV("channel[%d]: %d ", num_of_iface, miface_info.channel);
@@ -252,13 +256,9 @@ int RADIOModeCommand::handleEvent(WifiEvent &event)
if (mHandler.on_radio_mode_change && num_of_mac) {
(*mHandler.on_radio_mode_change)(mreqId, num_of_mac, mwifi_iface_mac_info);
- free(mwifi_iface_mac_info);
- mwifi_iface_mac_info = NULL;
}
else {
ALOGE("No Callback registered: on radio mode change");
- free(mwifi_iface_mac_info);
- mwifi_iface_mac_info = NULL;
}
}
break;
@@ -268,6 +268,16 @@ int RADIOModeCommand::handleEvent(WifiEvent &event)
ALOGE("%s: Wrong subcmd received %d", __FUNCTION__, mSubcmd);
}
+cleanup:
+ if (mode_info.iface_info != NULL) {
+ free(mode_info.iface_info);
+ mode_info.iface_info = NULL;
+ }
+ if (mwifi_iface_mac_info != NULL) {
+ free(mwifi_iface_mac_info);
+ mwifi_iface_mac_info = NULL;
+ }
+
return ret;
}
diff --git a/wcn6740/qcwcn/wifi_hal/wifi_hal.cpp b/wcn6740/qcwcn/wifi_hal/wifi_hal.cpp
index e43b770..9288aed 100644
--- a/wcn6740/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/wcn6740/qcwcn/wifi_hal/wifi_hal.cpp
@@ -146,11 +146,6 @@ static int wifi_is_nan_ext_cmd_supported(wifi_interface_handle handle);
wifi_error
wifi_init_tcp_param_change_event_handler(wifi_interface_handle iface);
-wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask,
- u32 iface_mode_mask, u32 filter_mask,
- u32 max_size, u32* size,
- wifi_usable_channel* channels);
-
/* Initialize/Cleanup */
wifi_interface_handle wifi_get_iface_handle(wifi_handle handle, char *name)
@@ -807,6 +802,161 @@ cleanup:
return ret;
}
+static u32 get_nl_band_mask(u32 in_mask)
+{
+ u32 op_mask = 0;
+
+ if (in_mask & WLAN_MAC_2_4_BAND)
+ op_mask |= BIT(NL80211_BAND_2GHZ);
+ if (in_mask & WLAN_MAC_5_0_BAND)
+ op_mask |= BIT(NL80211_BAND_5GHZ);
+ if (in_mask & WLAN_MAC_6_0_BAND)
+ op_mask |= BIT(NL80211_BAND_6GHZ);
+ if (in_mask & WLAN_MAC_60_0_BAND)
+ op_mask |= BIT(NL80211_BAND_60GHZ);
+
+ return op_mask;
+}
+
+static u32 get_nl_iftype_mode_masks(u32 in_mask)
+{
+ u32 op_mask = 0;
+
+ if (in_mask & BIT(WIFI_INTERFACE_STA) ||
+ in_mask & BIT(WIFI_INTERFACE_TDLS))
+ op_mask |= BIT(NL80211_IFTYPE_STATION);
+ if (in_mask & BIT(WIFI_INTERFACE_SOFTAP))
+ op_mask |= BIT(NL80211_IFTYPE_AP);
+ if (in_mask & BIT(WIFI_INTERFACE_P2P_CLIENT))
+ op_mask |= BIT(NL80211_IFTYPE_P2P_CLIENT);
+ if (in_mask & BIT(WIFI_INTERFACE_P2P_GO))
+ op_mask |= BIT(NL80211_IFTYPE_P2P_GO);
+ if (in_mask & BIT(WIFI_INTERFACE_NAN))
+ op_mask |= BIT(NL80211_IFTYPE_NAN);
+
+ return op_mask;
+}
+
+static u32 get_vendor_filter_mask(u32 in_mask)
+{
+ u32 op_mask = 0;
+
+ if (in_mask & WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE)
+ op_mask |= BIT(QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX);
+ if (in_mask & WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY)
+ op_mask |= BIT(QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY);
+
+ return op_mask;
+}
+
+wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask,
+ u32 iface_mode_mask, u32 filter_mask,
+ u32 max_size, u32* size,
+ wifi_usable_channel* channels)
+{
+ wifi_error ret = WIFI_ERROR_UNKNOWN;
+ WifihalGeneric *cmd = NULL;
+ struct nlattr *nl_data = NULL;
+ hal_info *info = NULL;
+ u32 band = 0, iface_mask = 0, filter = 0;
+
+ if (!handle) {
+ ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__);
+ goto cleanup;
+ }
+
+ info = getHalInfo(handle);
+ if (!info || info->num_interfaces < 1) {
+ ALOGE("%s: Error, wifi_handle NULL or base wlan interface not present",
+ __FUNCTION__);
+ goto cleanup;
+ }
+
+ if (!max_size) {
+ ALOGE("%s: max channel size is zero", __FUNCTION__);
+ ret = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
+ }
+
+ if (!channels) {
+ ALOGE("%s: user input channel buffer NULL", __FUNCTION__);
+ ret = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
+ }
+
+ cmd = new WifihalGeneric(handle, get_requestid(), OUI_QCA,
+ QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS);
+ if (cmd == NULL) {
+ ALOGE("%s: Error, created command NULL", __FUNCTION__);
+ ret = WIFI_ERROR_OUT_OF_MEMORY;
+ goto cleanup;
+ }
+
+ /* Create the NL message. */
+ ret = cmd->create();
+ if (ret < 0) {
+ ALOGE("%s: failed to create NL msg due to error: (%d)",
+ __FUNCTION__, ret);
+ goto cleanup;
+ }
+
+ /* Add the vendor specific attributes for the NL command. */
+ nl_data = cmd->attr_start(NL80211_ATTR_VENDOR_DATA);
+ if (!nl_data) {
+ ALOGE("%s: failed attr_start for VENDOR_DATA due to error",
+ __FUNCTION__);
+ ret = WIFI_ERROR_OUT_OF_MEMORY;
+ goto cleanup;
+ }
+
+ band = get_nl_band_mask(band_mask);
+ ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK,
+ band);
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: failed to put vendor data due to error:%d",
+ __FUNCTION__, ret);
+ goto cleanup;
+ }
+
+ iface_mask = get_nl_iftype_mode_masks(iface_mode_mask);
+ ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK,
+ iface_mask);
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: failed to put vendor data due to error:%d",
+ __FUNCTION__, ret);
+ goto cleanup;
+ }
+
+ filter = get_vendor_filter_mask(filter_mask);
+ ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK,
+ filter);
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: failed to put vendor data due to error:%d",
+ __FUNCTION__, ret);
+ goto cleanup;
+ }
+
+ cmd->attr_end(nl_data);
+
+ /* Populate the input received from caller/framework. */
+ cmd->setMaxSetSize(max_size);
+ cmd->set_channels_buff(channels);
+
+ /* Send the msg and wait for a response. */
+ ret = cmd->requestResponse();
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: Error %d waiting for response.", __FUNCTION__, ret);
+ goto cleanup;
+ }
+
+ *size = cmd->get_results_size();
+
+cleanup:
+ if (cmd)
+ delete cmd;
+ return ret;
+}
+
/*initialize function pointer table with Qualcomm HAL API*/
wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) {
if (fn == NULL) {
@@ -914,6 +1064,7 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) {
fn->wifi_multi_sta_set_use_case = wifi_multi_sta_set_use_case;
fn->wifi_set_coex_unsafe_channels = wifi_set_coex_unsafe_channels;
fn->wifi_set_dtim_config = wifi_set_dtim_config;
+ fn->wifi_get_usable_channels = wifi_get_usable_channels;
return WIFI_SUCCESS;
}
@@ -1263,6 +1414,7 @@ unload:
}
if (info->pkt_stats) free(info->pkt_stats);
if (info->rx_aggr_pkts) free(info->rx_aggr_pkts);
+ if (info->wifihal_ctrl_sock.s) close(info->wifihal_ctrl_sock.s);
wifi_logger_ring_buffers_deinit(info);
cleanupGscanHandlers(info);
cleanupRSSIMonitorHandler(info);
@@ -1300,12 +1452,14 @@ static int wifi_update_driver_state(const char *state) {
if (fd < 0) {
ALOGE("Failed to open driver state control param at %s",
WIFI_DRIVER_STATE_CTRL_PARAM);
+ close(fd);
return -1;
}
len = strlen(state) + 1;
if (TEMP_FAILURE_RETRY(write(fd, state, len)) != len) {
ALOGE("Failed to write driver state control param at %s",
WIFI_DRIVER_STATE_CTRL_PARAM);
+ close(fd);
ret = -1;
}
close(fd);
@@ -3111,158 +3265,6 @@ static int wifi_is_nan_ext_cmd_supported(wifi_interface_handle iface_handle)
}
}
-static u32 get_nl_band_mask(u32 in_mask)
-{
- u32 op_mask = 0;
-
- if (in_mask & WLAN_MAC_2_4_BAND)
- op_mask |= BIT(NL80211_BAND_2GHZ);
- if (in_mask & WLAN_MAC_5_0_BAND)
- op_mask |= BIT(NL80211_BAND_5GHZ);
- if (in_mask & WLAN_MAC_6_0_BAND)
- op_mask |= BIT(NL80211_BAND_6GHZ);
- if (in_mask & WLAN_MAC_60_0_BAND)
- op_mask |= BIT(NL80211_BAND_60GHZ);
-
- return op_mask;
-}
-
-static u32 get_nl_iftype_mode_masks(u32 in_mask)
-{
- u32 op_mask = 0;
-
- if (in_mask & BIT(WIFI_INTERFACE_STA) ||
- in_mask & BIT(WIFI_INTERFACE_TDLS))
- op_mask |= BIT(NL80211_IFTYPE_STATION);
- if (in_mask & BIT(WIFI_INTERFACE_SOFTAP))
- op_mask |= BIT(NL80211_IFTYPE_AP);
- if (in_mask & BIT(WIFI_INTERFACE_P2P_CLIENT))
- op_mask |= BIT(NL80211_IFTYPE_P2P_CLIENT);
- if (in_mask & BIT(WIFI_INTERFACE_P2P_GO))
- op_mask |= BIT(NL80211_IFTYPE_P2P_GO);
- if (in_mask & BIT(WIFI_INTERFACE_NAN))
- op_mask |= BIT(NL80211_IFTYPE_NAN);
-
- return op_mask;
-}
-
-static u32 get_vendor_filter_mask(u32 in_mask)
-{
- u32 op_mask = 0;
-
- if (in_mask & WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE)
- op_mask |= BIT(QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX);
- if (in_mask & WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY)
- op_mask |= BIT(QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY);
-
- return op_mask;
-}
-
-wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask,
- u32 iface_mode_mask, u32 filter_mask,
- u32 max_size, u32* size,
- wifi_usable_channel* channels)
-{
- wifi_error ret;
- WifihalGeneric *cmd = NULL;
- struct nlattr *nl_data;
- hal_info *info = NULL;
- u32 band = 0, iface_mask = 0, filter = 0;
-
- if (!handle) {
- ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__);
- return WIFI_ERROR_UNKNOWN;
- }
-
- info = getHalInfo(handle);
- if (!info || info->num_interfaces < 1) {
- ALOGE("%s: Error, wifi_handle NULL or base wlan interface not present",
- __FUNCTION__);
- return WIFI_ERROR_UNKNOWN;
- }
-
- if (!max_size) {
- ALOGE("%s: max channel size is zero", __FUNCTION__);
- ret = WIFI_ERROR_INVALID_ARGS;
- goto cleanup;
- }
-
- if (!channels) {
- ALOGE("%s: user input channel buffer NULL", __FUNCTION__);
- ret = WIFI_ERROR_INVALID_ARGS;
- goto cleanup;
- }
-
- cmd = new WifihalGeneric(handle, get_requestid(), OUI_QCA,
- QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS);
- if (cmd == NULL) {
- ALOGE("%s: Error, created command NULL", __FUNCTION__);
- return WIFI_ERROR_OUT_OF_MEMORY;
- }
-
- /* Create the NL message. */
- ret = cmd->create();
- if (ret < 0) {
- ALOGE("%s: failed to create NL msg due to error: (%d)",
- __FUNCTION__, ret);
- goto cleanup;
- }
-
- /* Add the vendor specific attributes for the NL command. */
- nl_data = cmd->attr_start(NL80211_ATTR_VENDOR_DATA);
- if (!nl_data) {
- ALOGE("%s: failed attr_start for VENDOR_DATA due to error: (%d)",
- __FUNCTION__, ret);
- goto cleanup;
- }
-
- band = get_nl_band_mask(band_mask);
- ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK,
- band);
- if (ret != WIFI_SUCCESS) {
- ALOGE("%s: failed to put vendor data due to error:%d",
- __FUNCTION__, ret);
- goto cleanup;
- }
-
- iface_mask = get_nl_iftype_mode_masks(iface_mode_mask);
- ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK,
- iface_mask);
- if (ret != WIFI_SUCCESS) {
- ALOGE("%s: failed to put vendor data due to error:%d",
- __FUNCTION__, ret);
- goto cleanup;
- }
-
- filter = get_vendor_filter_mask(filter_mask);
- ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK,
- filter);
- if (ret != WIFI_SUCCESS) {
- ALOGE("%s: failed to put vendor data due to error:%d",
- __FUNCTION__, ret);
- goto cleanup;
- }
-
- cmd->attr_end(nl_data);
-
- /* Populate the input received from caller/framework. */
- cmd->setMaxSetSize(max_size);
- cmd->set_channels_buff(channels);
-
- /* Send the msg and wait for a response. */
- ret = cmd->requestResponse();
- if (ret != WIFI_SUCCESS) {
- ALOGE("%s: Error %d waiting for response.", __FUNCTION__, ret);
- goto cleanup;
- }
-
- *size = cmd->get_results_size();
-
-cleanup:
- delete cmd;
- return ret;
-}
-
wifi_error wifi_get_radar_history(wifi_interface_handle handle,
radar_history_result *resultBuf, int resultBufSize, int *numResults)
{
diff --git a/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c b/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c
index ddc0062..2ad9c38 100644
--- a/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c
+++ b/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c
@@ -114,9 +114,7 @@ try_again:
pwd_system = getpwnam("system");
uid_system = pwd_system ? pwd_system->pw_uid : 0;
if (!gid_wifi || !uid_system) {
- close(ctrl->s);
- unlink(ctrl->local.sun_path);
- free(ctrl);
+ wifihal_ctrl_close(ctrl);
return NULL;
}
chown(ctrl->local.sun_path, -1, gid_wifi);
@@ -124,7 +122,7 @@ try_again:
if (*ctrl_path != '/') {
- free(ctrl);
+ wifihal_ctrl_close(ctrl);
return NULL;
}
#endif /* ANDROID */
@@ -133,15 +131,12 @@ try_again:
res = strlcpy(ctrl->dest.sun_path, ctrl_path,
sizeof(ctrl->dest.sun_path));
if (res >= sizeof(ctrl->dest.sun_path)) {
- close(ctrl->s);
- free(ctrl);
+ wifihal_ctrl_close(ctrl);
return NULL;
}
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
sizeof(ctrl->dest)) < 0) {
- close(ctrl->s);
- unlink(ctrl->local.sun_path);
- free(ctrl);
+ wifihal_ctrl_close(ctrl);
return NULL;
}
/*
diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am b/wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am
index e314452..8c09e3e 100644
--- a/wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am
+++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am
@@ -20,6 +20,17 @@ library_include_HEADERS = $(h_sources)
libwpa_supplicant_8_lib_la_SOURCES = driver_cmd_nl80211.c
libwpa_supplicant_8_lib_la_SOURCES += driver_cmd_nl80211_extn.c
libwpa_supplicant_8_lib_la_CFLAGS = ${AM_CFLAGS} ${LIBNL_CFLAGS}
+
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src/common"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src/drivers"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src/l2_packet"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src/utils"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src/wps"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/wpa_supplicant"
+libwpa_supplicant_8_lib_la_CFLAGS += "-DLINUX_EMBEDDED"
+
+
libwpa_supplicant_8_lib_la_LIBADD = ${LIBNL_LIBS}
lib_LTLIBRARIES = libwpa_supplicant_8_lib.la
diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac b/wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac
index 2be9651..76eda02 100644
--- a/wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac
+++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac
@@ -42,13 +42,9 @@ if (test "$has_libnl_ver" -eq 0); then
AC_MSG_ERROR(libnl and libnl-genl are required but were not found)
fi
-if (test "$has_libnl_ver" -gt 1); then
- AC_DEFINE([HAVE_LIBNL20], [1], [Define if you have libnl-2.0 or higher])
-fi
-if (test "$has_libnl_ver" -gt 2); then
- AC_DEFINE([HAVE_LIBNL30], [1], [Define if you have libnl-3.0 or higher])
-fi
+AC_ARG_VAR(WPA_SUPPLICANT_DIR,[Path to Wpa-supplicant-dir ])
+AS_IF([test "${WPA_SUPPLICANT_DIR}" = ""],[AC_MSG_ERROR("Provide WPA_SUPPLICANT_DIR=path to wpa_supplicant dir")])
AC_SUBST([LIBNL_CFLAGS])
AC_SUBST([LIBNL_LIBS])
diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c
index 7315a54..9656710 100644
--- a/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c
+++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c
@@ -4021,6 +4021,12 @@ static int wpa_get_twt_setup_resp_val(struct nlattr **tb2, char *buf,
if (!buf)
return -EINVAL;
+ /* In case of failure only status is updated */
+ if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
+ *buf = '\0';
+ return 0;
+ }
+
cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESP_TYPE;
if (!tb2[cmd_id]) {
wpa_printf(MSG_ERROR, "TWT resp type missing");
@@ -5199,7 +5205,7 @@ static int wpa_driver_form_clear_mcc_quota_msg(struct i802_bss *bss,
if (ret) {
wpa_printf(MSG_ERROR, "mcc_quota: Error sending nlmsg %d", ret);
- goto fail;
+ return ret;
}
return 0;
@@ -5340,7 +5346,7 @@ static int wpa_driver_form_set_mcc_quota_msg(struct i802_bss *bss,
if (ret) {
wpa_printf(MSG_ERROR, "mcc_quota: Error sending nlmsg %d", ret);
- goto fail;
+ return ret;
}
return 0;
@@ -5372,6 +5378,159 @@ int wpa_driver_cmd_send_mcc_quota(struct i802_bss *bss,
return -EINVAL;
}
+static int wpa_driver_form_flush_queue_config_msg(struct i802_bss *bss, char *cmd)
+{
+ uint32_t tid_mask = 0, flush_policy = 0;
+ u8 mac[MAC_ADDR_LEN], ac_mask = 0;
+ struct nl_msg *nlmsg = NULL;
+ struct nlattr *nl_attr;
+ char *ptr = cmd;
+ int ret;
+
+ wpa_printf(MSG_DEBUG, "flush_queue_config: %s", cmd);
+
+ /* First parameter: MAC address of peer */
+ if (os_strncasecmp(cmd, "peer", 4) == 0) {
+ cmd = move_to_next_str(cmd);
+ if ((strlen(cmd) < (MAC_ADDR_LEN * 2 + MAC_ADDR_LEN - 1)) ||
+ convert_string_to_bytes(mac, cmd, MAC_ADDR_LEN) !=
+ MAC_ADDR_LEN) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: Invalid MAC address");
+ wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+ return -EINVAL;
+ }
+ cmd = move_to_next_str(cmd);
+ } else {
+ wpa_printf(MSG_ERROR, "flush_queue_config: peer MAC address is missing");
+ wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+ return -EINVAL;
+ }
+
+ /* Second parameter: flush config */
+ if (os_strncasecmp(cmd, "policy", 6) == 0) {
+ cmd = move_to_next_str(cmd);
+ flush_policy = get_u32_from_string(cmd, &ret);
+ if (ret < 0) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: Invalid flush policy");
+ wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+ return ret;
+ }
+ cmd = move_to_next_str(cmd);
+ }
+
+ /* Third parameter: Follow QCA_WLAN_VENDOR_ATTR_AC for ac bit mask */
+ if (os_strncasecmp(cmd, "ac", 2) == 0) {
+ cmd = move_to_next_str(cmd);
+ ac_mask = get_u8_from_string(cmd, &ret);
+ if (ret < 0) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: AC mask error");
+ wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+ return ret;
+ }
+
+ if (!(ac_mask & (BIT(QCA_WLAN_VENDOR_TOS_BK) | BIT(QCA_WLAN_VENDOR_TOS_BE) |
+ BIT(QCA_WLAN_VENDOR_TOS_VI) | BIT(QCA_WLAN_VENDOR_TOS_VO)))) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: Invalid AC mask");
+ wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+ return -EINVAL;
+ }
+ cmd = move_to_next_str(cmd);
+ }
+
+ /* Fourth parameter: tid mask */
+ if (os_strncasecmp(cmd, "tid", 3) == 0) {
+ cmd = move_to_next_str(cmd);
+ tid_mask = get_u32_from_string(cmd, &ret);
+ if (ret < 0) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: TID mask error");
+ wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+ return ret;
+ }
+ cmd = move_to_next_str(cmd);
+ }
+
+ if (!tid_mask && !ac_mask) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: Neither TID not AC mask provided");
+ wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+ return -EINVAL;
+ }
+
+ nlmsg =
+ prepare_vendor_nlmsg(bss->drv, bss->ifname,
+ QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING);
+ if (!nlmsg) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: Failed to allocate nl message");
+ return -ENOMEM;
+ }
+
+ nl_attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA);
+ if (!nl_attr) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: Failed to alloc nlattr");
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ /* Put the peer MAC address */
+ ret = nla_put(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_ADDR, MAC_ADDR_LEN, mac);
+ if (ret) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: Error add hw addr attr %d", ret);
+ goto fail;
+ }
+
+ /* Put the flush_policy */
+ ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY,
+ flush_policy);
+ if (ret) {
+ wpa_printf(MSG_ERROR,
+ "flush_queue_config: Error add policy attr %d", ret);
+ goto fail;
+ }
+
+ if (tid_mask) {
+ /* Put the tid mask */
+ ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_TID_MASK,
+ tid_mask);
+ if (ret) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: Error add tid mask attr %d", ret);
+ goto fail;
+ }
+ } else {
+ /* Put the ac mask */
+ ret = nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_AC, ac_mask);
+ if (ret) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: Error add ac attr %d", ret);
+ goto fail;
+ }
+ }
+
+ nla_nest_end(nlmsg, nl_attr);
+ ret = send_nlmsg((struct nl_sock *)bss->drv->global->nl, nlmsg,
+ NULL, NULL);
+ if (ret) {
+ wpa_printf(MSG_ERROR, "flush_queue_config: Error sending nlmsg %d", ret);
+ return ret;
+ }
+ return 0;
+fail:
+ if (nlmsg)
+ nlmsg_free(nlmsg);
+ return ret;
+}
+
+int wpa_driver_cmd_send_peer_flush_queue_config(struct i802_bss *bss, char *cmd)
+{
+ int ret;
+
+ if (os_strncasecmp(cmd, "set", 3) == 0) {
+ cmd = move_to_next_str(cmd);
+ ret = wpa_driver_form_flush_queue_config_msg(bss, cmd);
+ return ret;
+ }
+
+ wpa_printf(MSG_ERROR, "peer_flush_config: Unknown operation");
+ return -EINVAL;
+}
+
int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
size_t buf_len )
{
@@ -5671,6 +5830,13 @@ int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
/* Move cmd by string len and space */
cmd += 10;
return wpa_driver_cmd_send_mcc_quota(priv, cmd);
+ } else if (os_strncasecmp(cmd, "FLUSH_QUEUE_CONFIG", 18) == 0) {
+ /* DRIVER FLUSH_QUEUE_CONFIG set peer <mac addr> policy <val>
+ * tid <tid mask> ac <ac mask>
+ */
+ /* Move cmd by string len and space */
+ cmd += 19;
+ return wpa_driver_cmd_send_peer_flush_queue_config(priv, cmd);
} else { /* Use private command */
memset(&ifr, 0, sizeof(ifr));
memset(&priv_cmd, 0, sizeof(priv_cmd));