diff options
author | Star Chang <starchang@google.com> | 2022-07-12 10:26:45 +0000 |
---|---|---|
committer | Star Chang <starchang@google.com> | 2022-11-02 03:44:53 +0000 |
commit | fed627ea259c92de1a58be53551e87187b941192 (patch) | |
tree | 43b40b9de7ddd1e3809300f22a8276ad98c06899 | |
parent | 09ddb91902e9eae9fc4b8b292d88a7fd7591603f (diff) | |
download | bcm4389-fed627ea259c92de1a58be53551e87187b941192.tar.gz |
bcmdhd: Add wlan_ptracker supported
Add bcmdhd driver register to wlan_ptracker for dynamic
setup twt.
Bug: 253348062
Test: Build/Test pass
Signed-off-by: Star Chang <starchang@google.com>
Change-Id: I7f2ef155337a7f3d6d0e9352bb189e613a660a92
-rw-r--r-- | Kbuild | 5 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | dhd_custom_google.c | 435 | ||||
-rw-r--r-- | dhd_linux_exportfs.c | 2 | ||||
-rw-r--r-- | dhd_pcie_linux.c | 3 | ||||
-rw-r--r-- | dhd_plat.h | 14 | ||||
-rw-r--r-- | wl_cfg80211.c | 6 | ||||
-rwxr-xr-x | wl_cfgvendor.c | 9 |
8 files changed, 476 insertions, 2 deletions
@@ -960,6 +960,11 @@ endif DHDCFLAGS := $(filter-out -DSIMPLE_MAC_PRINT ,$(DHDCFLAGS)) endif +ifneq ($(CONFIG_WLAN_TRACKER),) + WLAN_TRACKER_DIR=$(BCMDHD_ROOT)/../wlan_ptracker + DHDCFLAGS += -I$(WLAN_TRACKER_DIR)/ -DWLAN_TRACKER +endif + EXTRA_CFLAGS += $(DHDCFLAGS) -DDHD_DEBUG EXTRA_CFLAGS += -DDHD_COMPILED=\"$(BCMDHD_ROOT)\" EXTRA_CFLAGS += -I$(BCMDHD_ROOT)/include/ -I$(BCMDHD_ROOT)/ @@ -27,6 +27,10 @@ ifneq ($(KERNEL_SRC),) KBUILD_OPTIONS += BCMDHD_ROOT=$(shell cd $(KERNEL_SRC); readlink -e $(M)) endif +ifneq ($(CONFIG_WLAN_TRACKER),) +KBUILD_EXTRA_SYMBOLS=$(OUT_DIR)/../google-modules/wlan/wlan_ptracker/Module.symvers +endif + all: @echo "$(MAKE) -C $(KERNEL_SRC) M=$(M) modules $(KBUILD_OPTIONS)" @$(MAKE) -C $(KERNEL_SRC) M=$(M) modules $(KBUILD_OPTIONS) diff --git a/dhd_custom_google.c b/dhd_custom_google.c index 4bc0057..d31d238 100644 --- a/dhd_custom_google.c +++ b/dhd_custom_google.c @@ -870,6 +870,432 @@ struct wifi_platform_data dhd_wlan_control = { }; EXPORT_SYMBOL(dhd_wlan_control); + +#ifdef WLAN_TRACKER +#include <wlan_ptracker_client.h> +#include <wldev_common.h> +#include <wl_cfg80211.h> +#include <dhd_linux_priv.h> + +static int +dhd_twt_setup(void *priv, struct dytwt_setup_param *setup) +{ + wl_twt_config_t val; + struct net_device *dev = (struct net_device *)priv; + s32 bw; + u8 mybuf[WLC_IOCTL_SMLEN] = {0}; + u8 resp_buf[WLC_IOCTL_SMLEN] = {0}; + uint8 *rem = mybuf; + uint16 rem_len = sizeof(mybuf); + + bzero(&val, sizeof(val)); + val.version = WL_TWT_SETUP_VER; + val.length = sizeof(val.version) + sizeof(val.length); + + /* Default values, Override Below */ + val.desc.flow_flags = 0; + val.desc.wake_time_h = 0xFFFFFFFF; + val.desc.wake_time_l = 0xFFFFFFFF; + val.desc.wake_int_min = 0xFFFFFFFF; + val.desc.wake_int_max = 0xFFFFFFFF; + val.desc.wake_dur_min = 0xFFFFFFFF; + val.desc.wake_dur_max = 0xFFFFFFFF; + val.desc.avg_pkt_num = 0xFFFFFFFF; + val.desc.avg_pkt_size = 0xFFFFFFFF; + + /* Flow Flag for setup cmd: request, flow type: unannounced */ + val.desc.flow_flags |= WL_TWT_FLOW_FLAG_REQUEST; + val.desc.flow_flags |= WL_TWT_FLOW_FLAG_UNANNOUNCED; + /* Config ID */ + val.desc.configID = setup->config_id; + /* negotiation_type */ + val.desc.negotiation_type = setup->nego_type; + /* Wake Duration */ + val.desc.wake_dur = setup->wake_duration; + /* Wake interval */ + val.desc.wake_int = setup->wake_interval; + + bw = bcm_pack_xtlv_entry(&rem, &rem_len, WL_TWT_CMD_CONFIG, + sizeof(val), (uint8 *)&val, BCM_XTLV_OPTION_ALIGN32); + if (bw != BCME_OK) { + goto exit; + } + + bw = wldev_iovar_setbuf(dev, "twt", + mybuf, sizeof(mybuf) - rem_len, resp_buf, WLC_IOCTL_SMLEN, NULL); + if (bw < 0) { + pr_err("twt config set failed. ret:%d\n", bw); + } else { + pr_err("twt config setup succeeded, config ID %d " + "Negotiation type %d flow flags %d\n", val.desc.configID, + val.desc.negotiation_type, val.desc.flow_flags); + } +exit: + return bw; +} + +static int +dhd_twt_teardown(void *priv, struct dytwt_setup_param *setup) +{ + wl_twt_teardown_t val; + struct net_device *dev = (struct net_device *)priv; + s32 bw; + u8 mybuf[WLC_IOCTL_SMLEN] = {0}; + u8 res_buf[WLC_IOCTL_SMLEN] = {0}; + uint8 *rem = mybuf; + uint16 rem_len = sizeof(mybuf); + + bzero(&val, sizeof(val)); + val.version = WL_TWT_TEARDOWN_VER; + val.length = sizeof(val.version) + sizeof(val.length); + + /* Default values, Override Below */ + val.teardesc.flow_id = 0xFF; + val.teardesc.bid = 0xFF; + /* Config ID */ + val.configID = setup->config_id; + /* negotiation_type */ + val.teardesc.negotiation_type = setup->nego_type; + + bw = bcm_pack_xtlv_entry(&rem, &rem_len, WL_TWT_CMD_TEARDOWN, + sizeof(val), (uint8 *)&val, BCM_XTLV_OPTION_ALIGN32); + if (bw != BCME_OK) { + goto exit; + } + + bw = wldev_iovar_setbuf(dev, "twt", + mybuf, sizeof(mybuf) - rem_len, res_buf, WLC_IOCTL_SMLEN, NULL); + if (bw < 0) { + pr_err("twt teardown failed. ret:%d\n", bw); + } else { + pr_err("twt teardown succeeded, config ID %d " + "Negotiation type %d alltwt %d\n", val.configID, + val.teardesc.negotiation_type, val.teardesc.alltwt); + } +exit: + return bw; +} + +static void dhd_twt_stats2_dytwt(wl_twt_stats_v2_t *src, struct dytwt_stats *dest) +{ + wl_twt_peer_stats_v2_t *peer_stats = &src->peer_stats_list[0]; + + dest->sp_seq = peer_stats->sp_seq; + dest->tx_ucast_pkts = peer_stats->tx_ucast_pkts; + dest->tx_pkts_min = peer_stats->tx_pkts_min; + dest->tx_pkts_max = peer_stats->tx_pkts_max; + dest->tx_pkts_avg = peer_stats->tx_pkts_avg; + dest->tx_failures = peer_stats->tx_failures; + dest->rx_ucast_pkts = peer_stats->rx_ucast_pkts; + dest->rx_pkts_min = peer_stats->rx_pkts_min; + dest->rx_pkts_max = peer_stats->rx_pkts_max; + dest->rx_pkts_avg = peer_stats->rx_pkts_avg; + dest->rx_pkts_retried = peer_stats->rx_pkts_retried; + dest->tx_pkt_sz_avg = peer_stats->tx_pkt_sz_avg; + dest->rx_pkt_sz_avg = peer_stats->rx_pkt_sz_avg; + dest->eosp_dur_avg = peer_stats->eosp_dur_avg; + dest->eosp_count = peer_stats->eosp_count; +} + +static int +dhd_twt_get_stats(void *priv, struct dytwt_stats *stats) +{ + struct net_device *dev = (struct net_device *)priv; + wl_twt_stats_cmd_v1_t query; + wl_twt_stats_v2_t stats_v2; + int ret = BCME_OK; + char iovbuf[WLC_IOCTL_SMLEN] = {0, }; + uint8 *pxtlv = NULL; + uint8 *iovresp = NULL; + uint16 buflen = 0, bufstart = 0; + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); + + bzero(&query, sizeof(query)); + query.version = WL_TWT_STATS_CMD_VERSION_1; + query.length = sizeof(query) - OFFSETOF(wl_twt_stats_cmd_v1_t, peer); + + /* Default values, Override Below */ + query.num_bid = 0xFF; + query.num_fid = 0xFF; + query.configID = stats->config_id; + + iovresp = (uint8 *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); + if (iovresp == NULL) { + WL_ERR(("%s: iov resp memory alloc exited\n", __FUNCTION__)); + goto exit; + } + //query.flags |= WL_TWT_STATS_CMD_FLAGS_RESET; + buflen = bufstart = WLC_IOCTL_SMLEN; + pxtlv = (uint8 *)iovbuf; + ret = bcm_pack_xtlv_entry(&pxtlv, &buflen, WL_TWT_CMD_STATS, + sizeof(query), (uint8 *)&query, BCM_XTLV_OPTION_ALIGN32); + if (ret != BCME_OK) { + WL_ERR(("%s : Error return during pack xtlv :%d\n", __FUNCTION__, ret)); + goto exit; + } + + if ((ret = wldev_iovar_getbuf(dev, "twt", iovbuf, bufstart-buflen, + iovresp, WLC_IOCTL_MEDLEN, NULL))) { + WL_ERR(("twt status failed with err=%d \n", ret)); + goto exit; + } + + (void)memcpy_s(&stats_v2, sizeof(stats_v2), iovresp, sizeof(stats_v2)); + if (dtoh16(stats_v2.version) == WL_TWT_STATS_VERSION_2 && + stats_v2.num_stats) { + dhd_twt_stats2_dytwt((wl_twt_stats_v2_t*)iovresp, stats); + } else { + ret = BCME_UNSUPPORTED; + WL_ERR(("Version 1 unsupported. ver %d, \n", dtoh16(stats_v2.version))); + goto exit; + } +exit: + if (iovresp) { + MFREE(cfg->osh, iovresp, WLC_IOCTL_MEDLEN); + } + return ret; +} + +static void dhd_twt_status2_dytwt( + wl_twt_status_v1_t *result, + struct dytwt_status *status) +{ + int i; + wl_twt_sdesc_v0_t *sdesc = NULL; + + for (i = 0 ; i < WL_TWT_MAX_ITWT; i++) { + if (result->itwt_status[i].configID != status->config_id) + continue; + sdesc = &result->itwt_status[i].desc; + status->config_id = result->itwt_status[i].configID; + status->flow_id = sdesc->flow_id; + status->flow_flags = sdesc->flow_flags; + status->setup_cmd = sdesc->setup_cmd; + status->channel = sdesc->channel; + status->nego_type = sdesc->negotiation_type; + status->wake_dur = sdesc->wake_dur; + status->wake_int = sdesc->wake_int; + } +} + +static int +dhd_twt_get_status(void *priv, struct dytwt_status *status) +{ + struct net_device *dev = (struct net_device *)priv; + wl_twt_status_cmd_v1_t query; + wl_twt_status_v1_t result; + int ret = BCME_OK; + char iovbuf[WLC_IOCTL_SMLEN] = {0, }; + uint8 *pxtlv = NULL; + uint8 *iovresp = NULL; + uint16 buflen = 0, bufstart = 0; + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); + + bzero(&query, sizeof(query)); + bzero(&result, sizeof(result)); + query.version = WL_TWT_CMD_STATUS_VERSION_1; + query.length = sizeof(query) - OFFSETOF(wl_twt_status_cmd_v1_t, peer); + + query.configID = status->config_id; + + iovresp = (uint8 *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); + if (iovresp == NULL) { + WL_ERR(("%s: iov resp memory alloc exited\n", __FUNCTION__)); + goto exit; + } + buflen = bufstart = WLC_IOCTL_SMLEN; + pxtlv = (uint8 *)iovbuf; + ret = bcm_pack_xtlv_entry(&pxtlv, &buflen, WL_TWT_CMD_STATUS, + sizeof(query), (uint8 *)&query, BCM_XTLV_OPTION_ALIGN32); + if (ret != BCME_OK) { + WL_ERR(("%s : Error return during pack xtlv :%d\n", __FUNCTION__, ret)); + goto exit; + } + + if ((ret = wldev_iovar_getbuf(dev, "twt", iovbuf, bufstart-buflen, + iovresp, WLC_IOCTL_MEDLEN, NULL))) { + WL_ERR(("twt status failed with err=%d \n", ret)); + goto exit; + } + + (void)memcpy_s(&result, sizeof(result), iovresp, sizeof(result)); + printk("wlan_ptracker: %s(): version: %d, length: %d\n", + __func__, result.version, result.length); + if (dtoh16(result.version) == WL_TWT_CMD_STATUS_VERSION_1) { + dhd_twt_status2_dytwt(&result, status); + } else { + ret = BCME_UNSUPPORTED; + WL_ERR(("Version 1 unsupported. ver %d, \n", dtoh16(result.version))); + goto exit; + } +exit: + if (iovresp) { + MFREE(cfg->osh, iovresp, WLC_IOCTL_MEDLEN); + } + return ret; +} + +static int +dhd_twt_cap(void *priv, struct dytwt_cap *cap) +{ + int ret = BCME_OK; + struct net_device *dev = (struct net_device *)priv; + char iovbuf[WLC_IOCTL_SMLEN] = {0, }; + uint8 *pxtlv = NULL; + uint8 *iovresp = NULL; + wl_twt_cap_cmd_t cmd_cap; + wl_twt_cap_t result; + scb_val_t scbval; + uint16 buflen = 0, bufstart = 0; + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); + + /* Query link speed */ + ret = wldev_get_link_speed(dev, &cap->link_speed); + if (unlikely(ret)) { + WL_ERR(("get_link speed error (%d)\n", ret)); + goto exit; + } + + /* Query RSSI */ + bzero(&scbval, sizeof(scb_val_t)); + ret = wldev_get_rssi(dev, &scbval); + if (unlikely(ret)) { + WL_ERR(("get_rssi error (%d)\n", ret)); + goto exit; + } + cap->rssi = scbval.val; + bzero(&cmd_cap, sizeof(cmd_cap)); + + cmd_cap.version = WL_TWT_CAP_CMD_VERSION_1; + cmd_cap.length = sizeof(cmd_cap) - OFFSETOF(wl_twt_cap_cmd_t, peer); + + iovresp = (uint8 *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); + if (iovresp == NULL) { + pr_err("%s: iov resp memory alloc exited\n", __FUNCTION__); + goto exit; + } + + buflen = bufstart = WLC_IOCTL_SMLEN; + pxtlv = (uint8 *)iovbuf; + + ret = bcm_pack_xtlv_entry(&pxtlv, &buflen, WL_TWT_CMD_CAP, + sizeof(cmd_cap), (uint8 *)&cmd_cap, BCM_XTLV_OPTION_ALIGN32); + if (ret != BCME_OK) { + pr_err("%s : Error return during pack xtlv :%d\n", __FUNCTION__, ret); + goto exit; + } + + if ((ret = wldev_iovar_getbuf(dev, "twt", iovbuf, bufstart-buflen, + iovresp, WLC_IOCTL_MEDLEN, NULL))) { + pr_err("Getting twt status failed with err=%d \n", ret); + goto exit; + } + + (void)memcpy_s(&result, sizeof(result), iovresp, sizeof(result)); + + if (dtoh16(result.version) == WL_TWT_CAP_CMD_VERSION_1) { + pr_err("capability ver %d, \n", dtoh16(result.version)); + cap->device_cap = dtoh16(result.device_cap); + cap->peer_cap = dtoh16(result.peer_cap); + return ret; + } else { + ret = BCME_UNSUPPORTED; + pr_err("Version 1 unsupported. ver %d, \n", dtoh16(result.version)); + goto exit; + } +exit: + if (iovresp) { + MFREE(cfg->osh, iovresp, WLC_IOCTL_MEDLEN); + } + return ret; +} + +extern ssize_t show_pwrstats_path(struct dhd_info *dev, char *buf); + +static u64 twt_pwrstate_hex_get(char *buf) +{ + char *ptr = buf; + char *token = strsep(&ptr, "\x0a"); + + /* remove prefix space */ + token++; + return simple_strtoull(token, NULL, 16); +} + +#define DHD_PWR_STAT_STR_SIZE 512 +static int dhd_twt_pwstate(void *priv, struct dytwt_pwr_state *state) +{ + char buf[DHD_PWR_STAT_STR_SIZE]; + struct net_device *dev = (struct net_device *)priv; + struct dhd_info *dhd = DHD_DEV_INFO(dev); + char *ptr = &buf[0]; + char *token; + int cnt = 0; + int ret; + + ret = show_pwrstats_path(dhd, buf); + if (!ret) + goto out; + + token = strsep(&ptr, ":"); + while (token) { + if (cnt == 3) + state->awake = twt_pwrstate_hex_get(token); + if (cnt == 6) + state->count = twt_pwrstate_hex_get(token); + if (cnt == 7) + state->asleep = twt_pwrstate_hex_get(token); + token = strsep(&ptr, ":"); + cnt++; + } +out: + return 0; +} + +struct dytwt_client_ops twt_ops = { + .setup = dhd_twt_setup, + .teardown = dhd_twt_teardown, + .get_cap = dhd_twt_cap, + .get_pwrstates = dhd_twt_pwstate, + .get_stats = dhd_twt_get_stats, + .get_status = dhd_twt_get_status, +}; + +struct wlan_ptracker_client client = { + .ifname = "wlan0", + .dytwt_ops = &twt_ops, + .cb = NULL, +}; + +static int dhd_plat_ptracker_register(void) +{ + return wlan_ptracker_register_client(&client); +} + +static void dhd_plat_ptracker_unregister(void) +{ + wlan_ptracker_unregister_client(&client); +} + +static u32 custom_notify_table[] = { + WLAN_PTRACKER_NOTIFY_SUSPEN, //CUSTOM_NOTIFY_BUS_SUSPEND, + WLAN_PTRACKER_NOTIFY_STA_CONNECT, //CUSTOM_NOTIFY_STA_CONNECT, + WLAN_PTRACKER_NOTIFY_STA_DISCONNECT, //CUSTOM_NOTIFY_STA_DISCONNECT, + WLAN_PTRACKER_NOTIFY_DYTWT_DISABLE, //CUSTOM_NOTIFY_TWT_SETUP, + WLAN_PTRACKER_NOTIFY_DYTWT_ENABLE, //CUSTOM_NOTIFY_TWT_TEARDOWN, +}; + +int +dhd_custom_notify(u32 id) +{ + u32 _id = custom_notify_table[id]; + + if (!client.cb) + return 0; + return client.cb(&client, _id); +} +#endif /* WLAN_TRACKER */ + int dhd_wlan_init(void) { @@ -909,6 +1335,10 @@ dhd_wlan_init(void) dhd_wlan_init_hardware_info(); #endif /* SUPPORT_MULTIPLE_NVRAM || SUPPORT_MULTIPLE_CLMBLOB */ +#ifdef WLAN_TRACKER + dhd_plat_ptracker_register(); +#endif /* WLAN_TRACKER */ + fail: DHD_ERROR(("%s: FINISH.......\n", __FUNCTION__)); return ret; @@ -924,6 +1354,10 @@ dhd_wlan_deinit(void) gpio_free(wlan_reg_on); } +#ifdef WLAN_TRACKER + dhd_plat_ptracker_unregister(); +#endif /* WLAN_TRACKER */ + #ifdef DHD_COREDUMP platform_device_unregister(&sscd_dev); #endif /* DHD_COREDUMP */ @@ -1011,6 +1445,7 @@ uint16 dhd_plat_align_rxbuf_size(uint16 rxbufpost_sz) #endif } + #ifndef BCMDHD_MODULAR /* Required only for Built-in DHD */ device_initcall(dhd_wlan_init); diff --git a/dhd_linux_exportfs.c b/dhd_linux_exportfs.c index 1be9148..87f651d 100644 --- a/dhd_linux_exportfs.c +++ b/dhd_linux_exportfs.c @@ -580,7 +580,7 @@ static const uint16 pwrstats_req_type[] = { extern uint64 dhdpcie_get_last_suspend_time(dhd_pub_t *dhdp); -static ssize_t +ssize_t show_pwrstats_path(struct dhd_info *dev, char *buf) { int err = 0; diff --git a/dhd_pcie_linux.c b/dhd_pcie_linux.c index 0a8ee7d..887c49f 100644 --- a/dhd_pcie_linux.c +++ b/dhd_pcie_linux.c @@ -3321,6 +3321,9 @@ bool dhd_runtimepm_state(dhd_pub_t *dhd) /* stop all interface network queue. */ dhd_bus_stop_queue(bus); DHD_GENERAL_UNLOCK(dhd, flags); +#ifdef WLAN_TRACKER + dhd_custom_notify(CUSTOM_NOTIFY_BUS_SUSPEND); +#endif /* WLAN_TRACKER */ /* RPM suspend is failed, return FALSE then re-trying */ if (dhdpcie_set_suspend_resume(bus, TRUE)) { DHD_ERROR(("%s: exit with wakelock \n", __FUNCTION__)); @@ -95,5 +95,19 @@ extern uint32 dhd_plat_get_rc_vendor_id(void); extern uint32 dhd_plat_get_rc_device_id(void); extern uint16 dhd_plat_align_rxbuf_size(uint16 rxbufpost_sz); + +#ifdef WLAN_TRACKER +enum { + CUSTOM_NOTIFY_BUS_SUSPEND, + CUSTOM_NOTIFY_STA_CONNECT, + CUSTOM_NOTIFY_STA_DISCONNECT, + CUSTOM_NOTIFY_TWT_SETUP, + CUSTOM_NOTIFY_TWT_TEARDOWN, + CUSTOM_NOTIFY_MAX, +}; + +extern int dhd_custom_notify(u32 id); +#endif /* WLAN_TRACKER */ + #endif /* __linux__ */ #endif /* __DHD_PLAT_H__ */ diff --git a/wl_cfg80211.c b/wl_cfg80211.c index bbfce09..7688602 100644 --- a/wl_cfg80211.c +++ b/wl_cfg80211.c @@ -16642,6 +16642,12 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_ #endif /* DISABLE_WL_FRAMEBURST_SOFTAP */ #endif /* BCMDONGLEHOST */ } +#ifdef WLAN_TRACKER + /* notifer sta state change */ + if (err == BCME_OK) + dhd_custom_notify( + set ? CUSTOM_NOTIFY_STA_CONNECT : CUSTOM_NOTIFY_STA_DISCONNECT); +#endif /* WLAN_TRACKER */ return err; } diff --git a/wl_cfgvendor.c b/wl_cfgvendor.c index fb86f2f..4419ca3 100755 --- a/wl_cfgvendor.c +++ b/wl_cfgvendor.c @@ -79,6 +79,7 @@ #include <wl_cfgp2p.h> #include <wl_cfgscan.h> #include <wl_cfgvif.h> +#include <dhd_plat.h> #ifdef WL_NAN #include <wl_cfgnan.h> #endif /* WL_NAN */ @@ -10609,6 +10610,10 @@ wl_cfgvendor_twt_setup(struct wiphy *wiphy, uint8 *rem = mybuf; uint16 rem_len = sizeof(mybuf); +#ifdef WLAN_TRACKER + dhd_custom_notify(CUSTOM_NOTIFY_TWT_SETUP); +#endif /* WLAN_TRACKER */ + bzero(&val, sizeof(val)); val.version = WL_TWT_SETUP_VER; val.length = sizeof(val.version) + sizeof(val.length); @@ -10760,7 +10765,9 @@ wl_cfgvendor_twt_teardown(struct wiphy *wiphy, "Negotiation type %d alltwt %d\n", val.configID, val.teardesc.negotiation_type, val.teardesc.alltwt)); } - +#ifdef WLAN_TRACKER + dhd_custom_notify(CUSTOM_NOTIFY_TWT_TEARDOWN); +#endif /* WLAN_TRACKER */ exit: return bw; } |