1 /*
2 * Copyright (c) 2020 The Linux Foundation. All rights reserved.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 /**
20 * DOC: wlan_hdd_sysfs_mem_stats.c
21 *
22 * Implementation to add sysfs node wlan_mem_stats
23 *
24 */
25
26 #include <wlan_hdd_includes.h>
27 #include "osif_psoc_sync.h"
28 #include <wlan_hdd_sysfs.h>
29 #include <qdf_mem.h>
30 #include <wlan_hdd_sysfs_mem_stats.h>
31
__hdd_wlan_mem_stats_show(char * buf)32 static ssize_t __hdd_wlan_mem_stats_show(char *buf)
33 {
34 return scnprintf(buf, PAGE_SIZE,
35 "DMA = %d HEAP = %d SKB = %d SKB_MAX = %d\n",
36 qdf_dma_mem_stats_read(),
37 qdf_heap_mem_stats_read(),
38 qdf_skb_total_mem_stats_read(),
39 qdf_skb_max_mem_stats_read());
40 }
41
__hdd_wlan_dp_mem_stats_show(char * buf)42 static ssize_t __hdd_wlan_dp_mem_stats_show(char *buf)
43 {
44 int32_t len = 0;
45
46 len += scnprintf(buf + len, PAGE_SIZE,
47 "TX_NBUF_MEM = %d MAX_TX_NBUF_MEM = %d "
48 "RX_NBUF_MEM = %d MAX_RX_NBUF_MEM = %d "
49 "TX_NBUF_CNT = %d MAX_TX_NBUF_CNT = %d "
50 "RX_NBUF_CNT = %d MAX_RX_NBUF_CNT = %d "
51 "PENDING_TX_DESCS = %d MAX_PENDING_TX_DESCS = %d\n",
52 qdf_dp_tx_skb_mem_stats_read(),
53 qdf_dp_tx_skb_max_mem_stats_read(),
54 qdf_dp_rx_skb_mem_stats_read(),
55 qdf_dp_rx_skb_max_mem_stats_read(),
56 qdf_mem_dp_tx_skb_cnt_read(),
57 qdf_mem_dp_tx_skb_max_cnt_read(),
58 qdf_mem_dp_rx_skb_cnt_read(),
59 qdf_mem_dp_rx_skb_max_cnt_read(),
60 qdf_mem_tx_desc_cnt_read(),
61 qdf_mem_tx_desc_max_read());
62 return len;
63 }
64
hdd_wlan_mem_stats_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)65 static ssize_t hdd_wlan_mem_stats_show(struct kobject *kobj,
66 struct kobj_attribute *attr,
67 char *buf)
68 {
69 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
70 struct osif_psoc_sync *psoc_sync;
71 ssize_t length;
72 int errno;
73
74 errno = wlan_hdd_validate_context(hdd_ctx);
75 if (errno)
76 return errno;
77
78 errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync);
79 if (errno)
80 return errno;
81
82 length = __hdd_wlan_mem_stats_show(buf);
83 if (psoc_sync)
84 osif_psoc_sync_op_stop(psoc_sync);
85
86 return length;
87 }
88
hdd_wlan_dp_mem_stats_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)89 static ssize_t hdd_wlan_dp_mem_stats_show(struct kobject *kobj,
90 struct kobj_attribute *attr,
91 char *buf)
92 {
93 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
94 struct osif_psoc_sync *psoc_sync;
95 ssize_t length;
96 int errno;
97
98 errno = wlan_hdd_validate_context(hdd_ctx);
99 if (errno)
100 return errno;
101
102 errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync);
103 if (errno)
104 return errno;
105
106 length = __hdd_wlan_dp_mem_stats_show(buf);
107 if (psoc_sync)
108 osif_psoc_sync_op_stop(psoc_sync);
109
110 return length;
111 }
112
113 static struct kobj_attribute mem_stats_attribute =
114 __ATTR(wlan_mem_stats, 0440, hdd_wlan_mem_stats_show, NULL);
115
116 static struct kobj_attribute mem_dp_stats_attribute =
117 __ATTR(wlan_dp_mem_stats, 0440, hdd_wlan_dp_mem_stats_show, NULL);
118
hdd_sysfs_mem_stats_create(struct kobject * wlan_kobject)119 int hdd_sysfs_mem_stats_create(struct kobject *wlan_kobject)
120 {
121 int error;
122
123 if (!wlan_kobject) {
124 hdd_err("Could not get wlan kobject!");
125 return -EINVAL;
126 }
127 error = sysfs_create_file(wlan_kobject, &mem_stats_attribute.attr);
128 if (error) {
129 hdd_err("Failed to create sysfs file wlan_mem_stats");
130 return -EINVAL;
131 }
132 error = sysfs_create_file(wlan_kobject, &mem_dp_stats_attribute.attr);
133 if (error) {
134 hdd_err("Failed to create sysfs file wlan_dp_mem_stats");
135 sysfs_remove_file(wlan_kobject, &mem_stats_attribute.attr);
136 return -EINVAL;
137 }
138
139 qdf_mem_stats_init();
140
141 return error;
142 }
143
hdd_sysfs_mem_stats_destroy(struct kobject * wlan_kobject)144 void hdd_sysfs_mem_stats_destroy(struct kobject *wlan_kobject)
145 {
146 if (!wlan_kobject) {
147 hdd_err("Could not get wlan kobject!");
148 return;
149 }
150 sysfs_remove_file(wlan_kobject, &mem_dp_stats_attribute.attr);
151 sysfs_remove_file(wlan_kobject, &mem_stats_attribute.attr);
152 }
153
154