-
Notifications
You must be signed in to change notification settings - Fork 202
Expand file tree
/
Copy pathena_sysfs.c
More file actions
206 lines (169 loc) · 5.72 KB
/
Copy pathena_sysfs.c
File metadata and controls
206 lines (169 loc) · 5.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) Amazon.com, Inc. or its affiliates.
* All rights reserved.
*/
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/stat.h>
#include <linux/sysfs.h>
#include "ena_com.h"
#include "ena_netdev.h"
#ifdef ENA_PHC_SUPPORT
#include "ena_phc.h"
#endif /* ENA_PHC_SUPPORT */
#include "ena_sysfs.h"
static ssize_t ena_store_rx_copybreak(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct ena_adapter *adapter = dev_get_drvdata(dev);
unsigned long rx_copybreak;
int rc;
rc = kstrtoul(buf, 10, &rx_copybreak);
if (rc < 0)
goto exit;
rtnl_lock();
rc = ena_set_rx_copybreak(adapter, rx_copybreak);
if (rc)
goto unlock;
rtnl_unlock();
return len;
unlock:
rtnl_unlock();
exit:
return rc;
}
#define ENA_RX_COPYBREAK_STR_MAX_LEN 7
static ssize_t ena_show_rx_copybreak(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct ena_adapter *adapter = dev_get_drvdata(dev);
return snprintf(buf, ENA_RX_COPYBREAK_STR_MAX_LEN, "%d\n",
adapter->rx_copybreak);
}
static DEVICE_ATTR(rx_copybreak, S_IRUGO | S_IWUSR, ena_show_rx_copybreak,
ena_store_rx_copybreak);
#ifdef ENA_PHC_SUPPORT
/* Max PHC error bound string size takes into account max u32 value, null and new line characters */
#define ENA_PHC_ERROR_BOUND_STR_MAX_LEN 12
static ssize_t ena_show_phc_error_bound(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct ena_adapter *adapter = dev_get_drvdata(dev);
u32 error_bound_nsec = 0;
int rc;
rc = ena_phc_get_error_bound(adapter, &error_bound_nsec);
if (rc != 0)
return rc;
return snprintf(buf, ENA_PHC_ERROR_BOUND_STR_MAX_LEN, "%u\n", error_bound_nsec);
}
static DEVICE_ATTR(phc_error_bound, S_IRUGO, ena_show_phc_error_bound, NULL);
#endif /* ENA_PHC_SUPPORT */
static ssize_t ena_large_llq_set(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t len)
{
struct ena_adapter *adapter = dev_get_drvdata(dev);
enum ena_llq_header_size_policy_t new_llq_policy;
unsigned long large_llq_enabled;
int rc;
rc = kstrtoul(buf, 10, &large_llq_enabled);
if (rc < 0)
return rc;
if (large_llq_enabled != 0 && large_llq_enabled != 1)
return -EINVAL;
rtnl_lock();
new_llq_policy = large_llq_enabled ? ENA_LLQ_HEADER_SIZE_POLICY_LARGE :
ENA_LLQ_HEADER_SIZE_POLICY_NORMAL;
if (adapter->llq_policy == new_llq_policy)
goto unlock;
adapter->llq_policy = new_llq_policy;
rc = ena_destroy_device(adapter, false);
rc |= ena_restore_device(adapter);
if (rc)
netif_err(adapter, ifdown, adapter->netdev,
"Reset attempt failed. Can not reset the device\n");
unlock:
rtnl_unlock();
return rc ? rc : len;
}
#define ENA_LARGE_LLQ_STR_MAX_LEN 3
static ssize_t ena_large_llq_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct ena_adapter *adapter = dev_get_drvdata(dev);
bool large_llq_enabled;
large_llq_enabled = adapter->llq_policy == ENA_LLQ_HEADER_SIZE_POLICY_LARGE;
return snprintf(buf, ENA_LARGE_LLQ_STR_MAX_LEN, "%d\n",
large_llq_enabled);
}
static DEVICE_ATTR(large_llq_header, S_IRUGO | S_IWUSR, ena_large_llq_show,
ena_large_llq_set);
/* Enough to cover each print string and the value */
#define ENA_HW_PACKET_TIMESTAMPING_MAX_LEN 32
static ssize_t ena_hw_packet_timestamping_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct ena_adapter *adapter = dev_get_drvdata(dev);
struct hw_timestamp_state *hwpt_state = &adapter->hw_ts_state;
int rc = 0, write_rc;
/* HW configuration */
write_rc = snprintf(buf,
ENA_HW_PACKET_TIMESTAMPING_MAX_LEN,
"HW TX support: %u\n",
hwpt_state->hw_tx_supported);
buf += write_rc;
rc += write_rc;
write_rc = snprintf(buf,
ENA_HW_PACKET_TIMESTAMPING_MAX_LEN,
"HW RX support: %u\n",
hwpt_state->hw_rx_supported);
buf += write_rc;
rc += write_rc;
/* User configuration */
write_rc = snprintf(buf,
ENA_HW_PACKET_TIMESTAMPING_MAX_LEN,
"TX configuration: %u\n",
hwpt_state->ts_cfg.tx_type == HWTSTAMP_TX_ON);
buf += write_rc;
rc += write_rc;
write_rc = snprintf(buf,
ENA_HW_PACKET_TIMESTAMPING_MAX_LEN,
"RX configuration: %u\n",
hwpt_state->ts_cfg.rx_filter == HWTSTAMP_FILTER_ALL);
buf += write_rc;
rc += write_rc;
return rc;
}
static DEVICE_ATTR(hw_packet_timestamping_state, S_IRUGO,
ena_hw_packet_timestamping_show, NULL);
/******************************************************************************
*****************************************************************************/
int ena_sysfs_init(struct device *dev)
{
if (device_create_file(dev, &dev_attr_rx_copybreak))
dev_err(dev, "Failed to create rx_copybreak sysfs entry");
#ifdef ENA_PHC_SUPPORT
if (ena_phc_is_active(dev_get_drvdata(dev)))
if (device_create_file(dev, &dev_attr_phc_error_bound))
dev_err(dev, "Failed to create phc_error_bound sysfs entry");
#endif /* ENA_PHC_SUPPORT */
if (device_create_file(dev, &dev_attr_large_llq_header))
dev_err(dev, "Failed to create large_llq_header sysfs entry");
if (device_create_file(dev, &dev_attr_hw_packet_timestamping_state))
dev_err(dev, "Failed to create hw_packet_timestamping_state sysfs entry");
return 0;
}
/******************************************************************************
*****************************************************************************/
void ena_sysfs_terminate(struct device *dev)
{
device_remove_file(dev, &dev_attr_rx_copybreak);
#ifdef ENA_PHC_SUPPORT
device_remove_file(dev, &dev_attr_phc_error_bound);
#endif /* ENA_PHC_SUPPORT */
device_remove_file(dev, &dev_attr_large_llq_header);
device_remove_file(dev, &dev_attr_hw_packet_timestamping_state);
}