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
|
From ef0cc7d01f3eeca37c6bf864903af1c0cf0a792d Mon Sep 17 00:00:00 2001
From: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Date: Fri, 5 May 2017 18:11:08 +0300
Subject: [PATCH] dpaa2-eth: Add Tx shaping support
Add support in sysfs for controlling DPNI Tx shaping
parameters: rate limit (in Mbps) and max burst size (in bytes).
The settings are per port.
TODO: See how to integrate Tx shaping support using
standard Linux tools (ethtool)
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 80 ++++++++++++++++++++++++
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 4 ++
2 files changed, 84 insertions(+)
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -3771,6 +3771,83 @@ const struct dcbnl_rtnl_ops dpaa2_eth_dc
};
#endif
+/* SysFS support */
+static ssize_t dpaa2_eth_show_tx_shaping(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(to_net_dev(dev));
+ /* No MC API for getting the shaping config. We're stateful. */
+ struct dpni_tx_shaping_cfg *scfg = &priv->shaping_cfg;
+
+ return sprintf(buf, "%u %hu\n", scfg->rate_limit, scfg->max_burst_size);
+}
+
+static ssize_t dpaa2_eth_write_tx_shaping(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ int err, items;
+ struct dpaa2_eth_priv *priv = netdev_priv(to_net_dev(dev));
+ struct dpni_tx_shaping_cfg scfg;
+
+ items = sscanf(buf, "%u %hu", &scfg.rate_limit, &scfg.max_burst_size);
+ if (items != 2) {
+ pr_err("Expected format: \"rate_limit(Mbps) max_burst_size(bytes)\"\n");
+ return -EINVAL;
+ }
+ /* Size restriction as per MC API documentation */
+ if (scfg.max_burst_size > DPAA2_ETH_MAX_BURST_SIZE) {
+ pr_err("max_burst_size must be <= %d\n",
+ DPAA2_ETH_MAX_BURST_SIZE);
+ return -EINVAL;
+ }
+
+ err = dpni_set_tx_shaping(priv->mc_io, 0, priv->mc_token, &scfg);
+ if (err) {
+ dev_err(dev, "dpni_set_tx_shaping() failed\n");
+ return -EPERM;
+ }
+ /* If successful, save the current configuration for future inquiries */
+ priv->shaping_cfg = scfg;
+
+ return count;
+}
+
+static struct device_attribute dpaa2_eth_attrs[] = {
+ __ATTR(tx_shaping,
+ 0600,
+ dpaa2_eth_show_tx_shaping,
+ dpaa2_eth_write_tx_shaping),
+};
+
+static void dpaa2_eth_sysfs_init(struct device *dev)
+{
+ int i, err;
+
+ for (i = 0; i < ARRAY_SIZE(dpaa2_eth_attrs); i++) {
+ err = device_create_file(dev, &dpaa2_eth_attrs[i]);
+ if (err) {
+ dev_err(dev, "ERROR creating sysfs file\n");
+ goto undo;
+ }
+ }
+ return;
+
+undo:
+ while (i > 0)
+ device_remove_file(dev, &dpaa2_eth_attrs[--i]);
+}
+
+static void dpaa2_eth_sysfs_remove(struct device *dev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dpaa2_eth_attrs); i++)
+ device_remove_file(dev, &dpaa2_eth_attrs[i]);
+}
+
static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
{
struct device *dev;
@@ -3890,6 +3967,7 @@ static int dpaa2_eth_probe(struct fsl_mc
#ifdef CONFIG_DEBUG_FS
dpaa2_dbg_add(priv);
#endif
+ dpaa2_eth_sysfs_init(&net_dev->dev);
dev_info(dev, "Probed interface %s\n", net_dev->name);
return 0;
@@ -3937,6 +4015,8 @@ static int dpaa2_eth_remove(struct fsl_m
#ifdef CONFIG_DEBUG_FS
dpaa2_dbg_remove(priv);
#endif
+ dpaa2_eth_sysfs_remove(&net_dev->dev);
+
unregister_netdev(net_dev);
if (priv->do_link_poll)
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -42,6 +42,9 @@
*/
#define DPAA2_ETH_FQ_TAILDROP_THRESH (1024 * 1024)
+/* Maximum burst size value for Tx shaping */
+#define DPAA2_ETH_MAX_BURST_SIZE 0xF7FF
+
/* Maximum number of Tx confirmation frames to be processed
* in a single NAPI call
*/
@@ -444,6 +447,7 @@ struct dpaa2_eth_priv {
#ifdef CONFIG_DEBUG_FS
struct dpaa2_debugfs dbg;
#endif
+ struct dpni_tx_shaping_cfg shaping_cfg;
};
#define DPAA2_RXH_SUPPORTED (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO \
|