diff options
author | Hsiu-Chang Chen <hsiuchangchen@google.com> | 2022-08-03 18:30:05 +0800 |
---|---|---|
committer | Hsiu-Chang Chen <hsiuchangchen@google.com> | 2022-08-10 04:19:09 +0000 |
commit | 65cb184213990a90ea031c9f2337d463557483fb (patch) | |
tree | c626ae71caa73049112e646559d6158203187341 /wcn6740 | |
parent | 7ecdf23eccadac177efa843060ef34cb6888c0d9 (diff) | |
download | wlan-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.cpp | 26 | ||||
-rw-r--r-- | wcn6740/qcwcn/wifi_hal/wifi_hal.cpp | 316 | ||||
-rw-r--r-- | wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c | 13 | ||||
-rw-r--r-- | wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am | 11 | ||||
-rw-r--r-- | wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac | 8 | ||||
-rw-r--r-- | wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c | 170 |
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)); |