1 /*
2 * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 /**
19 * DOC: wlan_hdd_sysfs_txrx_stats.c
20 *
21 * implementation for creating sysfs file txrx_stats
22 */
23
24 #include <wlan_hdd_includes.h>
25 #include <wlan_hdd_main.h>
26 #include "osif_vdev_sync.h"
27 #include <wlan_hdd_sysfs.h>
28 #include <wlan_hdd_sysfs_txrx_stats.h>
29 #include "cds_api.h"
30 #include "cdp_txrx_cmn_struct.h"
31 #include "cdp_txrx_cmn.h"
32
33 static ssize_t
__hdd_sysfs_txrx_stats_store(struct net_device * net_dev,char const * buf,size_t count)34 __hdd_sysfs_txrx_stats_store(struct net_device *net_dev,
35 char const *buf, size_t count)
36 {
37 struct hdd_adapter *adapter = netdev_priv(net_dev);
38 char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
39 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
40 struct cdp_txrx_stats_req req = {0};
41 struct hdd_station_ctx *sta_ctx;
42 struct hdd_context *hdd_ctx;
43 char *sptr, *token;
44 uint32_t val1;
45 uint8_t val2;
46 int ret;
47
48 if (hdd_validate_adapter(adapter))
49 return -EINVAL;
50
51 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
52 ret = wlan_hdd_validate_context(hdd_ctx);
53 if (ret != 0)
54 return ret;
55
56 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
57 if (!wlan_hdd_validate_modules_state(hdd_ctx))
58 return -EINVAL;
59
60 ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
61 buf, count);
62
63 if (ret) {
64 hdd_err_rl("invalid input");
65 return ret;
66 }
67
68 sptr = buf_local;
69 hdd_debug("txrx_stats: count %zu buf_local:(%s) net_devname %s",
70 count, buf_local, net_dev->name);
71
72 /* Get val1 */
73 token = strsep(&sptr, " ");
74 if (!token)
75 return -EINVAL;
76 if (kstrtou32(token, 0, &val1))
77 return -EINVAL;
78
79 /* Get val2 */
80 token = strsep(&sptr, " ");
81 if (!token)
82 return -EINVAL;
83 if (kstrtou8(token, 0, &val2))
84 return -EINVAL;
85
86 req.stats = val1;
87 /* default value of secondary parameter is 0(mac_id) */
88 req.mac_id = val2;
89
90 hdd_debug("WE_SET_TXRX_STATS stats cmd: %d mac_id: %d",
91 req.stats, req.mac_id);
92 if (qdf_unlikely(!soc))
93 return -EINVAL;
94
95 if (val1 == CDP_TXRX_STATS_28) {
96 if (sta_ctx->conn_info.is_authenticated) {
97 hdd_debug("ap mac addr:" QDF_MAC_ADDR_FMT,
98 QDF_MAC_ADDR_REF(&sta_ctx->conn_info.bssid.bytes[0]));
99 req.peer_addr =
100 (char *)&sta_ctx->conn_info.bssid;
101 }
102 }
103 ret = cdp_txrx_stats_request(soc, adapter->deflink->vdev_id, &req);
104
105 if (ret) {
106 hdd_err_rl("failed to set txrx stats: %d", ret);
107 return ret;
108 }
109
110 return count;
111 }
112
113 static ssize_t
hdd_sysfs_txrx_stats_store(struct device * dev,struct device_attribute * attr,char const * buf,size_t count)114 hdd_sysfs_txrx_stats_store(struct device *dev,
115 struct device_attribute *attr,
116 char const *buf, size_t count)
117 {
118 struct net_device *net_dev = container_of(dev, struct net_device, dev);
119 struct osif_vdev_sync *vdev_sync;
120 ssize_t errno_size;
121
122 errno_size = osif_vdev_sync_op_start(net_dev, &vdev_sync);
123 if (errno_size)
124 return errno_size;
125
126 errno_size = __hdd_sysfs_txrx_stats_store(net_dev, buf, count);
127
128 osif_vdev_sync_op_stop(vdev_sync);
129
130 return errno_size;
131 }
132
133 static DEVICE_ATTR(txrx_stats, 0220,
134 NULL, hdd_sysfs_txrx_stats_store);
135
hdd_sysfs_txrx_stats_create(struct hdd_adapter * adapter)136 int hdd_sysfs_txrx_stats_create(struct hdd_adapter *adapter)
137 {
138 int error;
139
140 error = device_create_file(&adapter->dev->dev, &dev_attr_txrx_stats);
141 if (error)
142 hdd_err("could not create txrx_stats sysfs file");
143
144 return error;
145 }
146
hdd_sysfs_txrx_stats_destroy(struct hdd_adapter * adapter)147 void hdd_sysfs_txrx_stats_destroy(struct hdd_adapter *adapter)
148 {
149 device_remove_file(&adapter->dev->dev, &dev_attr_txrx_stats);
150 }
151