summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorbibhayr <bibhayr@nvidia.com>2013-07-24 12:55:53 +0530
committerHarshada Kale <hkale@nvidia.com>2013-08-02 07:58:35 -0700
commitac1d54e349062098ca7666d06def740a04da01b0 (patch)
treeeba28a61b705c1137a2d25cead6101e89ab6d798 /drivers
parent12cc4d1f5ad4afd8bcc145bb23e570fcdc97dd1b (diff)
bcmdhd: adds sysfs control "idletime" at "/sys/kernel/bcmdhd/idletime"
1.idletime can be controlled by accessing this file on the sysfs 2.read current value by "cat /sys/kernel/bcmdhd/idletime" 3.set by "echo X > /sys/kernel/bcmdhd/idletime" set idletime value to "0" before starting sd tuning. After sd tuning done, restore idletime value(currently, it is "5"). Bug 1332062 Change-Id: Ifb74ee3e30a8f2b5a064d476d6253bd085f6bda8 Signed-off-by: bibhayr <bibhayr@nvidia.com> Reviewed-on: http://git-master/r/252786 GVS: Gerrit_Virtual_Submit Tested-by: Naveen Kumar Arepalli <naveenk@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Kumar <krakesh@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/bcmdhd/Makefile1
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c117
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_sdio.c26
3 files changed, 142 insertions, 2 deletions
diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile
index 8dcbc9dbe43b..914f045d9f75 100644
--- a/drivers/net/wireless/bcmdhd/Makefile
+++ b/drivers/net/wireless/bcmdhd/Makefile
@@ -43,6 +43,7 @@ DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=28000
DHDCFLAGS += -DQUEUE_BW
#DHDCFLAGS += -DVSDB_BW_ALLOCATE_ENABLE
DHDCFLAGS += -DP2P_DISCOVERY_WAR
+DHDCFLAGS += -DSYSFS_IDLETIME
#DHDCFLAGS += -DRSSI_OFFSET=5
#endif
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index f0327bbbe5cd..05dd1eb74a0d 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -519,7 +519,10 @@ static void dhd_dump_htsfhisto(histo_t *his, char *s);
int dhd_monitor_init(void *dhd_pub);
int dhd_monitor_uninit(void);
-
+#ifdef SYSFS_IDLETIME
+int dhd_sysfs_init(dhd_pub_t *dhdp);
+int dhd_sysfs_deinit(void);
+#endif /* SYSFS_IDLETIME */
#if defined(WL_WIRELESS_EXT)
struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev);
@@ -3143,6 +3146,10 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen, void *dev)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1)
INIT_WORK(&dhd->work_hang, dhd_hang_process);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+
+#ifdef SYSFS_IDLETIME
+ dhd_sysfs_init(&dhd->pub);
+#endif /* SYSFS_IDLETIME */
/*
* Save the dhd_info into the priv
*/
@@ -4306,6 +4313,10 @@ void dhd_detach(dhd_pub_t *dhdp)
wake_lock_destroy(&dhd->wl_wdwake);
#endif /* CONFIG_HAS_WAKELOCK */
}
+
+#ifdef SYSFS_IDLETIME
+ dhd_sysfs_deinit();
+#endif /* SYSFS_IDLETIME */
}
@@ -6058,3 +6069,107 @@ void htsf_update(dhd_info_t *dhd, void *data)
}
#endif /* WLMEDIA_HTSF */
+
+#ifdef SYSFS_IDLETIME
+typedef struct dhd_sysfs {
+ struct kobject *dhd_sysfs_kobj;
+ dhd_pub_t *dhdp;
+} dhd_sysfs_t;
+
+dhd_sysfs_t g_sysfs = {0,};
+
+extern int32 dhd_get_bus_idletime(dhd_pub_t *dhdp);
+extern int32 dhd_set_bus_idletime(dhd_pub_t *dhdp, int32 idletime);
+
+static ssize_t
+dhd_sysfs_idletime_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int32 idletime;
+
+ DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+ if (!g_sysfs.dhdp) {
+ DHD_ERROR(("%s: not initialized yet\n", __FUNCTION__));
+ return -EFAULT;
+ }
+ if (sscanf(buf, "%d", &idletime) < 1) {
+ DHD_ERROR(("%s: failed to parse write value\n", __FUNCTION__));
+ return -EFAULT;
+ }
+
+ DHD_INFO(("%s: idletime:%d\n", __FUNCTION__, idletime));
+
+ dhd_set_bus_idletime(g_sysfs.dhdp, idletime);
+
+ return count;
+}
+
+static ssize_t
+dhd_sysfs_idletime_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ int32 idletime;
+
+ DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+ if (!g_sysfs.dhdp) {
+ DHD_ERROR(("%s: not initialized yet\n", __FUNCTION__));
+ return -EFAULT;
+ }
+
+ idletime = dhd_get_bus_idletime(g_sysfs.dhdp);
+ DHD_INFO(("%s: idletime:%d\n", __FUNCTION__, idletime));
+
+ return sprintf(buf, "%d\n", idletime);
+}
+
+static struct kobj_attribute dhd_sysfs_idletime_attribute =
+ __ATTR(idletime, 0644, dhd_sysfs_idletime_show, dhd_sysfs_idletime_store);
+
+static struct attribute *dhd_sysfs_attrs[] = {
+ &dhd_sysfs_idletime_attribute.attr,
+ NULL,
+};
+
+static struct attribute_group dhd_sysfs_attr_group = {
+ .attrs = dhd_sysfs_attrs,
+};
+
+int dhd_sysfs_deinit(void)
+{
+ DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+ if (g_sysfs.dhd_sysfs_kobj) {
+ kobject_put(g_sysfs.dhd_sysfs_kobj);
+ g_sysfs.dhd_sysfs_kobj = NULL;
+ }
+
+ g_sysfs.dhdp = NULL;
+
+ return 0;
+}
+
+int dhd_sysfs_init(dhd_pub_t *dhdp)
+{
+ int ret;
+ DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+ g_sysfs.dhd_sysfs_kobj = kobject_create_and_add(KBUILD_MODNAME, kernel_kobj);
+ if (!g_sysfs.dhd_sysfs_kobj) {
+ DHD_ERROR(("%s: kobject_create_and_add() failed\n", __FUNCTION__));
+ return -ENOMEM;
+ }
+
+ ret = sysfs_create_group(g_sysfs.dhd_sysfs_kobj, &dhd_sysfs_attr_group);
+ if (ret) {
+ DHD_ERROR(("%s: sysfs_create_group() failed\n", __FUNCTION__));
+ dhd_sysfs_deinit();
+ return ret;
+ }
+
+ g_sysfs.dhdp = dhdp;
+
+ return 0;
+}
+#endif /* SYSFS_IDLETIME */
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index a5d5df22b36c..b2d2cdbdb907 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -6350,7 +6350,7 @@ dhd_bus_watchdog(dhd_pub_t *dhdp)
else {
bus->idlecount++;
- if (bus->idlecount >= bus->idletime) {
+ if ((bus->idletime > 0) && (bus->idlecount >= bus->idletime)) {
DHD_TIMER(("%s: DHD Idle state!!\n", __FUNCTION__));
if (SLPAUTO_ENAB(bus)) {
@@ -7736,3 +7736,27 @@ dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint si
bus = dhdp->bus;
return dhdsdio_membytes(bus, set, address, data, size);
}
+
+#ifdef SYSFS_IDLETIME
+int32 dhd_get_bus_idletime(dhd_pub_t *dhdp)
+{
+ dhd_bus_t *bus = dhdp->bus;
+
+ return bus->idletime;
+}
+
+int32 dhd_set_bus_idletime(dhd_pub_t *dhdp, int32 idletime)
+{
+ dhd_bus_t *bus = dhdp->bus;
+
+ bus->idletime = idletime;
+
+ if (dhdp->busstate != DHD_BUS_DOWN && idletime == 0) {
+ dhd_os_sdlock(dhdp);
+ BUS_WAKE(bus);
+ dhd_os_sdunlock(dhdp);
+ }
+
+ return 0;
+}
+#endif /* SYSFS_IDLETIME */