summaryrefslogtreecommitdiff
path: root/qcwcn/wifi_hal/wifi_hal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qcwcn/wifi_hal/wifi_hal.cpp')
-rw-r--r--qcwcn/wifi_hal/wifi_hal.cpp108
1 files changed, 96 insertions, 12 deletions
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp
index 1a5811c..198ab01 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/qcwcn/wifi_hal/wifi_hal.cpp
@@ -52,7 +52,6 @@
#include "cpp_bindings.h"
#include "ifaceeventhandler.h"
#include "wifiloggercmd.h"
-#include "vendor_definitions.h"
/*
BUGBUG: normally, libnl allocates ports for all connections it makes; but
@@ -66,6 +65,7 @@
#define WIFI_HAL_CMD_SOCK_PORT 644
#define WIFI_HAL_EVENT_SOCK_PORT 645
+#define MAX_HW_VER_LENGTH 100
/*
* Defines for wifi_wait_for_driver_ready()
* Specify durations between polls and max wait time
@@ -196,6 +196,38 @@ cleanup:
return ret;
}
+static wifi_error acquire_driver_supported_features(wifi_interface_handle iface,
+ features_info *driver_features)
+{
+ wifi_error ret;
+ interface_info *iinfo = getIfaceInfo(iface);
+ wifi_handle handle = getWifiHandle(iface);
+
+ WifihalGeneric driverFeatures(handle, 0,
+ OUI_QCA,
+ QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES);
+
+ /* create the message */
+ ret = driverFeatures.create();
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ ret = driverFeatures.set_iface_id(iinfo->name);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ ret = driverFeatures.requestResponse();
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: requestResponse Error:%d",__func__, ret);
+ goto cleanup;
+ }
+
+ driverFeatures.getDriverFeatures(driver_features);
+
+cleanup:
+ return mapKernelErrortoWifiHalError(ret);
+}
+
static wifi_error wifi_get_capabilities(wifi_interface_handle handle)
{
wifi_error ret;
@@ -425,6 +457,7 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) {
fn->wifi_select_tx_power_scenario = wifi_select_tx_power_scenario;
fn->wifi_reset_tx_power_scenario = wifi_reset_tx_power_scenario;
fn->wifi_set_radio_mode_change_handler = wifi_set_radio_mode_change_handler;
+ fn->wifi_set_latency_mode = wifi_set_latency_mode;
return WIFI_SUCCESS;
}
@@ -454,7 +487,6 @@ static int wifi_get_iface_id(hal_info *info, const char *iface)
wifi_error wifi_initialize(wifi_handle *handle)
{
- int err = 0;
wifi_error ret = WIFI_SUCCESS;
wifi_interface_handle iface_handle;
struct nl_sock *cmd_sock = NULL;
@@ -462,6 +494,8 @@ wifi_error wifi_initialize(wifi_handle *handle)
struct nl_cb *cb = NULL;
int status = 0;
int index;
+ char hw_ver_type[MAX_HW_VER_LENGTH];
+ char *hw_name = NULL;
ALOGI("Initializing wifi");
hal_info *info = (hal_info *)malloc(sizeof(hal_info));
@@ -509,11 +543,11 @@ wifi_error wifi_initialize(wifi_handle *handle)
goto unload;
}
- err = 1;
+ info->event_sock_arg = 1;
nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
- nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
- nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
- nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
+ nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &info->event_sock_arg);
+ nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &info->event_sock_arg);
+ nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &info->event_sock_arg);
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, internal_valid_message_handler,
info);
@@ -626,11 +660,36 @@ wifi_error wifi_initialize(wifi_handle *handle)
ret = WIFI_SUCCESS;
}
+ ret = acquire_driver_supported_features(iface_handle,
+ &info->driver_supported_features);
+ if (ret != WIFI_SUCCESS) {
+ ALOGI("Failed to get vendor feature set : %d", ret);
+ ret = WIFI_SUCCESS;
+ }
+
ret = wifi_get_logger_supported_feature_set(iface_handle,
&info->supported_logger_feature_set);
if (ret != WIFI_SUCCESS)
ALOGE("Failed to get supported logger feature set: %d", ret);
+ ret = wifi_get_firmware_version(iface_handle, hw_ver_type,
+ MAX_HW_VER_LENGTH);
+ if (ret == WIFI_SUCCESS) {
+ hw_name = strstr(hw_ver_type, "HW:");
+ if (hw_name) {
+ hw_name += strlen("HW:");
+ if (strncmp(hw_name, "QCA6174", 7) == 0)
+ info->pkt_log_ver = PKT_LOG_V1;
+ else
+ info->pkt_log_ver = PKT_LOG_V2;
+ } else {
+ info->pkt_log_ver = PKT_LOG_V0;
+ }
+ ALOGV("%s: hardware version type %d", __func__, info->pkt_log_ver);
+ } else {
+ ALOGE("Failed to get supported logger feature set: %d", ret);
+ }
+
ret = get_firmware_bus_max_size_supported(iface_handle);
if (ret != WIFI_SUCCESS) {
ALOGE("Failed to get supported bus size, error : %d", ret);
@@ -715,6 +774,10 @@ unload:
cleanupGscanHandlers(info);
cleanupRSSIMonitorHandler(info);
free(info->event_cb);
+ if (info->driver_supported_features.flags) {
+ free(info->driver_supported_features.flags);
+ info->driver_supported_features.flags = NULL;
+ }
free(info);
}
}
@@ -812,6 +875,11 @@ static void internal_cleaned_up_handler(wifi_handle handle)
info->pkt_fate_stats = NULL;
}
+ if (info->driver_supported_features.flags) {
+ free(info->driver_supported_features.flags);
+ info->driver_supported_features.flags = NULL;
+ }
+
(*cleaned_up_handler)(handle);
pthread_mutex_destroy(&info->cb_lock);
pthread_mutex_destroy(&info->pkt_fate_stats_lock);
@@ -1300,6 +1368,7 @@ cleanup:
wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id,
wifi_interface_handle iface,
+ u16 ether_type,
u8 *ip_packet,
u16 ip_packet_len,
u8 *src_mac_addr,
@@ -1318,6 +1387,7 @@ wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id,
return ret;
}
+ ALOGV("ether type 0x%04x\n", ether_type);
ALOGV("ip packet length : %u\nIP Packet:", ip_packet_len);
hexdump(ip_packet, ip_packet_len);
ALOGV("Src Mac Address: " MAC_ADDR_STR "\nDst Mac Address: " MAC_ADDR_STR
@@ -1341,8 +1411,14 @@ wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id,
if (ret != WIFI_SUCCESS)
goto cleanup;
+ ret = vCommand->put_u16(
+ QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_ETHER_PROTO_TYPE,
+ ether_type);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
ret = vCommand->put_bytes(
- QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET,
+ QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA,
(const char *)ip_packet, ip_packet_len);
if (ret != WIFI_SUCCESS)
goto cleanup;
@@ -1419,6 +1495,8 @@ cleanup:
return ret;
}
+#define PACKET_FILTER_ID 0
+
static wifi_error wifi_set_packet_filter(wifi_interface_handle iface,
const u8 *program, u32 len)
{
@@ -1458,7 +1536,7 @@ static wifi_error wifi_set_packet_filter(wifi_interface_handle iface,
PACKET_FILTER_ID);
if (ret != WIFI_SUCCESS)
goto cleanup;
- ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH,
+ ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE,
len);
if (ret != WIFI_SUCCESS)
goto cleanup;
@@ -1541,7 +1619,7 @@ static wifi_error wifi_get_packet_filter_capabilities(
goto cleanup;
ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD,
- QCA_WLAN_GET_PACKET_FILTER_SIZE);
+ QCA_WLAN_GET_PACKET_FILTER);
if (ret != WIFI_SUCCESS)
goto cleanup;
@@ -1669,7 +1747,7 @@ wifi_error wifi_write_packet_filter(wifi_interface_handle iface,
PACKET_FILTER_ID);
if (ret != WIFI_SUCCESS)
goto cleanup;
- ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH,
+ ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE,
len);
if (ret != WIFI_SUCCESS)
goto cleanup;
@@ -1784,13 +1862,19 @@ cleanup:
static wifi_error wifi_read_packet_filter(wifi_interface_handle handle,
u32 src_offset, u8 *host_dst, u32 length)
{
- wifi_error ret;
+ wifi_error ret = WIFI_SUCCESS;
struct nlattr *nlData;
WifihalGeneric *vCommand = NULL;
interface_info *ifaceInfo = getIfaceInfo(handle);
wifi_handle wifiHandle = getWifiHandle(handle);
hal_info *info = getHalInfo(wifiHandle);
+ /* Length to be passed to this function should be non-zero
+ * Return invalid argument if length is passed as zero
+ */
+ if (length == 0)
+ return WIFI_ERROR_INVALID_ARGS;
+
/*Temporary varibles to support the read complete length in chunks */
u8 *temp_host_dst;
u32 remainingLengthToBeRead, currentLength;
@@ -1844,7 +1928,7 @@ static wifi_error wifi_read_packet_filter(wifi_interface_handle handle,
currentLength = min(remainingLengthToBeRead, info->firmware_bus_max_size);
- ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH,
+ ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE,
currentLength);
if (ret != WIFI_SUCCESS)
break;