Merge "Added support to set and get IP configuration details." into tizen
[platform/core/connectivity/net-config.git] / src / wifi-firmware.c
index 8583865..812755f 100755 (executable)
@@ -20,6 +20,8 @@
 #include <errno.h>
 #include <vconf.h>
 #include <vconf-keys.h>
+#include <stdio.h>
+#include <fcntl.h>
 
 #include "log.h"
 #include "util.h"
 #include "netsupplicant.h"
 #include "wifi-firmware.h"
 #include "network-statistics.h"
-#if defined WLAN_CHECK_POWERSAVE
-#include "wifi-powersave.h"
-#endif
 
 #define WLAN_DRIVER_SCRIPT                     "/usr/bin/wlan.sh"
 #define WLAN_IFACE_NAME                                "wlan0"
-#define WLAN_P2P_IFACE_NAME                    "p2p0"
+
+#define WLAN_P2P_IFACE_NAME_TV                 "p2p0"
+#define WLAN_P2P_IFACE_NAME_COMMON                     "wlan0"
+#define WLAN_P2P_IFACE_NAME ((TIZEN_TV) ? (WLAN_P2P_IFACE_NAME_TV) : (WLAN_P2P_IFACE_NAME_COMMON))
+#define QUAD_CPUS_COUNT                        4
+#define TEMP_BUFFER_LEN                        100
+#define WIFI_MAC_ADD_PATH              "/sys/class/net/wlan0/address"
 
 static int __netconfig_sta_firmware_start(void)
 {
@@ -80,7 +85,9 @@ static int __netconfig_sta_firmware_stop(void)
 
 static int __netconfig_p2p_firmware_start(void)
 {
-#if defined TIZEN_P2P_ENABLE
+       if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT))
+               return -ENODEV;
+
        int rv = 0;
        const char *path = WLAN_DRIVER_SCRIPT;
        char *const args[] = { "/usr/bin/wlan.sh", "p2p", NULL };
@@ -90,10 +97,6 @@ static int __netconfig_p2p_firmware_start(void)
        if (rv < 0)
                return -EIO;
 
-       rv = netconfig_interface_up(WLAN_IFACE_NAME);
-       if (rv != TRUE)
-               return -EIO;
-
 #if defined TIZEN_WLAN_USE_P2P_INTERFACE
        rv = netconfig_interface_up(WLAN_P2P_IFACE_NAME);
        if (rv != TRUE)
@@ -102,14 +105,13 @@ static int __netconfig_p2p_firmware_start(void)
 
        DBG("Successfully loaded p2p device driver");
        return 0;
-#else
-       return -ENODEV;
-#endif
 }
 
 static int __netconfig_p2p_firmware_stop(void)
 {
-#if defined TIZEN_P2P_ENABLE
+       if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT))
+               return -ENODEV;
+
        int rv = 0;
        const char *path = WLAN_DRIVER_SCRIPT;
        char *const args[] = { "/usr/bin/wlan.sh", "stop", NULL };
@@ -125,14 +127,13 @@ static int __netconfig_p2p_firmware_stop(void)
 
        DBG("Successfully removed p2p device driver");
        return 0;
-#else
-       return -ENODEV;
-#endif
 }
 
 static int __netconfig_softap_firmware_start(void)
 {
-#if defined TIZEN_TETHERING_ENABLE
+       if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_TETHERING))
+               return -ENODEV;
+
        int rv = 0;
        const char *path = WLAN_DRIVER_SCRIPT;
        char *const args[] = { "/usr/bin/wlan.sh", "softap", NULL };
@@ -147,14 +148,13 @@ static int __netconfig_softap_firmware_start(void)
 
        DBG("Successfully loaded softap device driver");
        return 0;
-#else
-       return -ENODEV;
-#endif
 }
 
 static int __netconfig_softap_firmware_stop(void)
 {
-#if defined TIZEN_TETHERING_ENABLE
+       if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_TETHERING))
+               return -ENODEV;
+
        int rv = 0;
        const char *path = WLAN_DRIVER_SCRIPT;
        char *const args[] = { "/usr/bin/wlan.sh", "stop", NULL };
@@ -170,14 +170,11 @@ static int __netconfig_softap_firmware_stop(void)
 
        DBG("Successfully removed softap device driver");
        return 0;
-#else
-       return -ENODEV;
-#endif
 }
 
 static int __netconfig_wifi_firmware_start(enum netconfig_wifi_firmware type)
 {
-       if (netconfig_emulator_is_emulated() == TRUE)
+       if (emulator_is_emulated() == TRUE)
                return -EIO;
 
        switch (type) {
@@ -196,7 +193,7 @@ static int __netconfig_wifi_firmware_start(enum netconfig_wifi_firmware type)
 
 static int __netconfig_wifi_firmware_stop(enum netconfig_wifi_firmware type)
 {
-       if (netconfig_emulator_is_emulated() == TRUE)
+       if (emulator_is_emulated() == TRUE)
                return -EIO;
 
        switch (type) {
@@ -213,19 +210,76 @@ static int __netconfig_wifi_firmware_stop(enum netconfig_wifi_firmware type)
        return -ENXIO;
 }
 
+static int __netconfig_set_rps_cpus(void)
+{
+       int fd, curr;
+       ssize_t count;
+       char t_buf[TEMP_BUFFER_LEN];
+       char r_buf[TEMP_BUFFER_LEN];
+
+       if (access(WIFI_MAC_ADD_PATH, F_OK) != 0) {
+               DBG("WiFi driver is not loaded... ");
+               return -1;
+       } else {
+               DBG("WiFi driver loaded... ");
+       }
+
+       snprintf(t_buf, TEMP_BUFFER_LEN, "/sys/class/net/wlan0/queues/rx-0/rps_cpus");
+       DBG("Command : [%s]", t_buf);
+       curr = 0;
+
+       while ((fd = open(t_buf, O_RDWR | O_CLOEXEC)) >= 0) {
+               curr++;
+               count = read(fd, r_buf, 1);
+
+               if (count < 0) {
+                       DBG("read failed");
+                       close(fd);
+                       return -1;
+               } else {
+                       DBG("read size = %d", count);
+               }
+
+               if (r_buf[0] == 'e') {
+                       close(fd);
+                       DBG("e is already written");
+                       snprintf(t_buf, TEMP_BUFFER_LEN, "/sys/class/net/wlan0/queues/rx-%d/rps_cpus", curr);
+                       DBG("Command : [%s]", t_buf);
+                       continue;
+               } else {
+                       DBG("writing e");
+               }
+
+               if (lseek(fd, 0, SEEK_SET) < 0) {
+                       DBG("lseek failed");
+                       close(fd);
+                       return -1;
+               }
+
+               count = write(fd, "e", 1);
+
+               if (count < 0) {
+                       DBG("write failed");
+                       close(fd);
+                       return -1;
+               } else {
+                       DBG("write size = %d", count);
+               }
+
+               close(fd);
+               snprintf(t_buf, TEMP_BUFFER_LEN, "/sys/class/net/wlan0/queues/rx-%d/rps_cpus", curr);
+               DBG("Command : [%s]", t_buf);
+       }
+
+       return 0;
+}
+
 int netconfig_wifi_firmware(enum netconfig_wifi_firmware type, gboolean enable)
 {
        int err;
        static enum netconfig_wifi_firmware current_driver = NETCONFIG_WIFI_OFF;
        enum netconfig_wifi_firmware alias = type;
 
-#if defined WLAN_CONCURRENT_MODE
-       int flight_mode = 0;
-
-       if (type == NETCONFIG_WIFI_P2P)
-               alias = NETCONFIG_WIFI_STA;
-#endif
-
        DBG("Wi-Fi current firmware %d (type: %d %s)", current_driver, type,
                                                        enable == TRUE ? "enable" : "disable");
 
@@ -233,34 +287,7 @@ int netconfig_wifi_firmware(enum netconfig_wifi_firmware type, gboolean enable)
                if (current_driver == NETCONFIG_WIFI_OFF) {
                        return -EALREADY;
                } else if (current_driver == alias) {
-#if defined WLAN_CHECK_POWERSAVE
-                       if (type == NETCONFIG_WIFI_STA &&
-                                       netconfig_wifi_is_powersave_mode() == TRUE) {
-                               netconfig_interface_down(WIFI_IFNAME);
 
-                               return -EALREADY;
-                       }
-#endif
-
-#if defined WLAN_CONCURRENT_MODE
-#if defined TIZEN_TELEPHONY_ENABLE
-                       vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &flight_mode);
-#endif
-                       if (flight_mode == 0 && type == NETCONFIG_WIFI_STA &&
-                                       netconfig_is_wifi_direct_on() == TRUE) {
-                               netconfig_interface_down(WIFI_IFNAME);
-
-                               return -EALREADY;
-                       }
-
-                       if (type == NETCONFIG_WIFI_P2P &&
-                                       netconfig_wifi_state_get_technology_state() >
-                                               NETCONFIG_WIFI_TECH_OFF) {
-                               netconfig_interface_down(WLAN_P2P_IFACE_NAME);
-
-                               return -EALREADY;
-                       }
-#endif
                        err = __netconfig_wifi_firmware_stop(type);
                        if (err < 0 && err != -EALREADY)
                                return err;
@@ -274,26 +301,8 @@ int netconfig_wifi_firmware(enum netconfig_wifi_firmware type, gboolean enable)
        }
 
        if (current_driver > NETCONFIG_WIFI_OFF) {
-               if (current_driver == alias) {
-#if defined WLAN_CHECK_POWERSAVE
-                       if (type == NETCONFIG_WIFI_STA &&
-                                       netconfig_wifi_is_powersave_mode() == TRUE) {
-                               netconfig_interface_up(WIFI_IFNAME);
-
-                               return -EALREADY;
-                       }
-#endif
-
-#if defined WLAN_CONCURRENT_MODE
-                       if (type == NETCONFIG_WIFI_STA)
-                               netconfig_interface_up(WIFI_IFNAME);
-#if defined TIZEN_P2P_ENABLE
-                       else if (type == NETCONFIG_WIFI_P2P)
-                               netconfig_interface_up(WLAN_P2P_IFACE_NAME);
-#endif
-#endif
+               if (current_driver == alias)
                        return -EALREADY;
-               }
 
                return -EIO;
        }
@@ -304,6 +313,9 @@ int netconfig_wifi_firmware(enum netconfig_wifi_firmware type, gboolean enable)
        else
                current_driver = alias;
 
+       if (__netconfig_set_rps_cpus() < 0)
+               DBG("Failed to set rps_cpus");
+
        return err;
 }
 
@@ -311,7 +323,7 @@ gboolean handle_start(WifiFirmware *firmware, GDBusMethodInvocation *context, co
 {
        int err;
 
-       g_return_val_if_fail(firmware != NULL, FALSE);
+       g_return_val_if_fail(firmware != NULL, TRUE);
 
        DBG("Wi-Fi firmware start %s", device != NULL ? device : "null");
 
@@ -325,11 +337,16 @@ gboolean handle_start(WifiFirmware *firmware, GDBusMethodInvocation *context, co
        if (err < 0) {
                if (err == -EALREADY)
                        netconfig_error_already_exists(context);
-               else
+               else if (g_strcmp0("softap", device) == 0 && err == -EIO && netconfig_is_wifi_direct_on() == FALSE) {
+                       if (netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, FALSE) == 0 && netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, TRUE) == 0) {
+                               wifi_firmware_complete_start(firmware, context);
+                               return TRUE;
+                       } else
+                               netconfig_error_wifi_driver_failed(context);
+               } else
                        netconfig_error_wifi_driver_failed(context);
 
-               wifi_firmware_complete_start(firmware, context);
-               return FALSE;
+               return TRUE;
        }
 
        wifi_firmware_complete_start(firmware, context);
@@ -340,7 +357,7 @@ gboolean handle_stop(WifiFirmware *firmware, GDBusMethodInvocation *context, con
 {
        int err;
 
-       g_return_val_if_fail(firmware != NULL, FALSE);
+       g_return_val_if_fail(firmware != NULL, TRUE);
 
        DBG("Wi-Fi firmware stop %s", device != NULL ? device : "null");
 
@@ -357,10 +374,9 @@ gboolean handle_stop(WifiFirmware *firmware, GDBusMethodInvocation *context, con
                else
                        netconfig_error_wifi_driver_failed(context);
 
-               wifi_firmware_complete_start(firmware, context);
-               return FALSE;
+               return TRUE;
        }
 
-       wifi_firmware_complete_start(firmware, context);
+       wifi_firmware_complete_stop(firmware, context);
        return TRUE;
 }