diff options
author | bibhayr <bibhayr@nvidia.com> | 2013-07-24 12:55:53 +0530 |
---|---|---|
committer | Harshada Kale <hkale@nvidia.com> | 2013-08-02 07:58:35 -0700 |
commit | ac1d54e349062098ca7666d06def740a04da01b0 (patch) | |
tree | eba28a61b705c1137a2d25cead6101e89ab6d798 /drivers | |
parent | 12cc4d1f5ad4afd8bcc145bb23e570fcdc97dd1b (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/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_linux.c | 117 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_sdio.c | 26 |
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 */ |