6fd1c66b0ae16959e7936e4e1ce074468ff0e331
[openwrt/staging/stintel.git] /
1 From 472fcea160f27a5d9b7526093d9d8d89ba0b6137 Mon Sep 17 00:00:00 2001
2 From: Christian Marangi <ansuelsmth@gmail.com>
3 Date: Wed, 27 Jul 2022 13:35:16 +0200
4 Subject: [PATCH 07/14] net: dsa: qca8k: move port set status/eee/ethtool stats
5 function to common code
6
7 The same logic to disable/enable port, set eee and get ethtool stats is
8 used by drivers based on qca8k family switch.
9 Move it to common code to make it accessible also by other drivers.
10 While at it also drop unnecessary qca8k_priv cast for void pointers.
11
12 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
13 Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
14 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
15 ---
16 drivers/net/dsa/qca/qca8k-8xxx.c | 105 -----------------------------
17 drivers/net/dsa/qca/qca8k-common.c | 102 ++++++++++++++++++++++++++++
18 drivers/net/dsa/qca/qca8k.h | 11 +++
19 3 files changed, 113 insertions(+), 105 deletions(-)
20
21 --- a/drivers/net/dsa/qca/qca8k-8xxx.c
22 +++ b/drivers/net/dsa/qca/qca8k-8xxx.c
23 @@ -768,21 +768,6 @@ out:
24 return ret;
25 }
26
27 -static void
28 -qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
29 -{
30 - u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
31 -
32 - /* Port 0 and 6 have no internal PHY */
33 - if (port > 0 && port < 6)
34 - mask |= QCA8K_PORT_STATUS_LINK_AUTO;
35 -
36 - if (enable)
37 - regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
38 - else
39 - regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
40 -}
41 -
42 static int
43 qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,
44 struct sk_buff *read_skb, u32 *val)
45 @@ -1974,20 +1959,6 @@ qca8k_phylink_mac_link_up(struct dsa_swi
46 qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
47 }
48
49 -static void
50 -qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data)
51 -{
52 - struct qca8k_priv *priv = ds->priv;
53 - int i;
54 -
55 - if (stringset != ETH_SS_STATS)
56 - return;
57 -
58 - for (i = 0; i < priv->info->mib_count; i++)
59 - strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
60 - ETH_GSTRING_LEN);
61 -}
62 -
63 static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb)
64 {
65 struct qca8k_mib_eth_data *mib_eth_data;
66 @@ -2078,82 +2049,6 @@ exit:
67 }
68
69 static void
70 -qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
71 - uint64_t *data)
72 -{
73 - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
74 - const struct qca8k_mib_desc *mib;
75 - u32 reg, i, val;
76 - u32 hi = 0;
77 - int ret;
78 -
79 - if (priv->mgmt_master && priv->info->ops->autocast_mib &&
80 - priv->info->ops->autocast_mib(ds, port, data) > 0)
81 - return;
82 -
83 - for (i = 0; i < priv->info->mib_count; i++) {
84 - mib = &ar8327_mib[i];
85 - reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
86 -
87 - ret = qca8k_read(priv, reg, &val);
88 - if (ret < 0)
89 - continue;
90 -
91 - if (mib->size == 2) {
92 - ret = qca8k_read(priv, reg + 4, &hi);
93 - if (ret < 0)
94 - continue;
95 - }
96 -
97 - data[i] = val;
98 - if (mib->size == 2)
99 - data[i] |= (u64)hi << 32;
100 - }
101 -}
102 -
103 -static int
104 -qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
105 -{
106 - struct qca8k_priv *priv = ds->priv;
107 -
108 - if (sset != ETH_SS_STATS)
109 - return 0;
110 -
111 - return priv->info->mib_count;
112 -}
113 -
114 -static int
115 -qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee)
116 -{
117 - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
118 - u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
119 - u32 reg;
120 - int ret;
121 -
122 - mutex_lock(&priv->reg_mutex);
123 - ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
124 - if (ret < 0)
125 - goto exit;
126 -
127 - if (eee->eee_enabled)
128 - reg |= lpi_en;
129 - else
130 - reg &= ~lpi_en;
131 - ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
132 -
133 -exit:
134 - mutex_unlock(&priv->reg_mutex);
135 - return ret;
136 -}
137 -
138 -static int
139 -qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
140 -{
141 - /* Nothing to do on the port's MAC */
142 - return 0;
143 -}
144 -
145 -static void
146 qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
147 {
148 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
149 --- a/drivers/net/dsa/qca/qca8k-common.c
150 +++ b/drivers/net/dsa/qca/qca8k-common.c
151 @@ -174,3 +174,105 @@ exit:
152 mutex_unlock(&priv->reg_mutex);
153 return ret;
154 }
155 +
156 +void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
157 +{
158 + u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
159 +
160 + /* Port 0 and 6 have no internal PHY */
161 + if (port > 0 && port < 6)
162 + mask |= QCA8K_PORT_STATUS_LINK_AUTO;
163 +
164 + if (enable)
165 + regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
166 + else
167 + regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
168 +}
169 +
170 +void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset,
171 + uint8_t *data)
172 +{
173 + struct qca8k_priv *priv = ds->priv;
174 + int i;
175 +
176 + if (stringset != ETH_SS_STATS)
177 + return;
178 +
179 + for (i = 0; i < priv->info->mib_count; i++)
180 + strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
181 + ETH_GSTRING_LEN);
182 +}
183 +
184 +void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
185 + uint64_t *data)
186 +{
187 + struct qca8k_priv *priv = ds->priv;
188 + const struct qca8k_mib_desc *mib;
189 + u32 reg, i, val;
190 + u32 hi = 0;
191 + int ret;
192 +
193 + if (priv->mgmt_master && priv->info->ops->autocast_mib &&
194 + priv->info->ops->autocast_mib(ds, port, data) > 0)
195 + return;
196 +
197 + for (i = 0; i < priv->info->mib_count; i++) {
198 + mib = &ar8327_mib[i];
199 + reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
200 +
201 + ret = qca8k_read(priv, reg, &val);
202 + if (ret < 0)
203 + continue;
204 +
205 + if (mib->size == 2) {
206 + ret = qca8k_read(priv, reg + 4, &hi);
207 + if (ret < 0)
208 + continue;
209 + }
210 +
211 + data[i] = val;
212 + if (mib->size == 2)
213 + data[i] |= (u64)hi << 32;
214 + }
215 +}
216 +
217 +int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
218 +{
219 + struct qca8k_priv *priv = ds->priv;
220 +
221 + if (sset != ETH_SS_STATS)
222 + return 0;
223 +
224 + return priv->info->mib_count;
225 +}
226 +
227 +int qca8k_set_mac_eee(struct dsa_switch *ds, int port,
228 + struct ethtool_eee *eee)
229 +{
230 + u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
231 + struct qca8k_priv *priv = ds->priv;
232 + u32 reg;
233 + int ret;
234 +
235 + mutex_lock(&priv->reg_mutex);
236 + ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
237 + if (ret < 0)
238 + goto exit;
239 +
240 + if (eee->eee_enabled)
241 + reg |= lpi_en;
242 + else
243 + reg &= ~lpi_en;
244 + ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
245 +
246 +exit:
247 + mutex_unlock(&priv->reg_mutex);
248 + return ret;
249 +}
250 +
251 +int qca8k_get_mac_eee(struct dsa_switch *ds, int port,
252 + struct ethtool_eee *e)
253 +{
254 + /* Nothing to do on the port's MAC */
255 + return 0;
256 +}
257 --- a/drivers/net/dsa/qca/qca8k.h
258 +++ b/drivers/net/dsa/qca/qca8k.h
259 @@ -423,6 +423,7 @@ struct qca8k_fdb {
260 extern const struct qca8k_mib_desc ar8327_mib[];
261 extern const struct regmap_access_table qca8k_readable_table;
262 int qca8k_mib_init(struct qca8k_priv *priv);
263 +void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable);
264
265 /* Common read/write/rmw function */
266 int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val);
267 @@ -435,4 +436,14 @@ int qca8k_bulk_write(struct qca8k_priv *
268 /* Common ops function */
269 int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask);
270
271 +/* Common ethtool stats function */
272 +void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data);
273 +void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
274 + uint64_t *data);
275 +int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset);
276 +
277 +/* Common eee function */
278 +int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee);
279 +int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
280 +
281 #endif /* __QCA8K_H */