d89ae3af54b7339bc4ea8d12d8062862b1f9477c
[openwrt/staging/stintel.git] /
1 From 028ed86f08a4fdf25213af5f5afd63b30fb7b029 Mon Sep 17 00:00:00 2001
2 From: Lei Wei <quic_leiwei@quicinc.com>
3 Date: Thu, 29 Feb 2024 16:59:53 +0800
4 Subject: [PATCH 32/50] net: ethernet: qualcomm: Add phylink support for PPE
5 MAC ports
6
7 Add MAC initialization and phylink functions for PPE MAC ports.
8
9 Change-Id: I39dcba671732392bcfa2e734473fd083989bfbec
10 Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
11 ---
12 drivers/net/ethernet/qualcomm/Kconfig | 3 +
13 drivers/net/ethernet/qualcomm/ppe/Makefile | 2 +-
14 drivers/net/ethernet/qualcomm/ppe/ppe.c | 9 +
15 drivers/net/ethernet/qualcomm/ppe/ppe.h | 2 +
16 drivers/net/ethernet/qualcomm/ppe/ppe_port.c | 728 +++++++++++++++++++
17 drivers/net/ethernet/qualcomm/ppe/ppe_port.h | 76 ++
18 drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 123 ++++
19 7 files changed, 942 insertions(+), 1 deletion(-)
20 create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_port.c
21 create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_port.h
22
23 diff --git a/drivers/net/ethernet/qualcomm/Kconfig b/drivers/net/ethernet/qualcomm/Kconfig
24 index 8cc24da48777..a96f6acd4561 100644
25 --- a/drivers/net/ethernet/qualcomm/Kconfig
26 +++ b/drivers/net/ethernet/qualcomm/Kconfig
27 @@ -66,6 +66,9 @@ config QCOM_PPE
28 depends on HAS_IOMEM && OF
29 depends on COMMON_CLK
30 select REGMAP_MMIO
31 + select PHYLINK
32 + select PCS_QCOM_IPQ_UNIPHY
33 + select SFP
34 help
35 This driver supports the Qualcomm Technologies, Inc. packet
36 process engine (PPE) available with IPQ SoC. The PPE houses
37 diff --git a/drivers/net/ethernet/qualcomm/ppe/Makefile b/drivers/net/ethernet/qualcomm/ppe/Makefile
38 index 227af2168224..76cdc423a8cc 100644
39 --- a/drivers/net/ethernet/qualcomm/ppe/Makefile
40 +++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
41 @@ -4,4 +4,4 @@
42 #
43
44 obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
45 -qcom-ppe-objs := ppe.o ppe_config.o ppe_api.o ppe_debugfs.o
46 +qcom-ppe-objs := ppe.o ppe_config.o ppe_api.o ppe_debugfs.o ppe_port.o
47 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c
48 index 8cf6c1161c4b..bcf21c838e05 100644
49 --- a/drivers/net/ethernet/qualcomm/ppe/ppe.c
50 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
51 @@ -17,6 +17,7 @@
52 #include "ppe.h"
53 #include "ppe_config.h"
54 #include "ppe_debugfs.h"
55 +#include "ppe_port.h"
56
57 #define PPE_PORT_MAX 8
58 #define PPE_CLK_RATE 353000000
59 @@ -207,6 +208,11 @@ static int qcom_ppe_probe(struct platform_device *pdev)
60 if (ret)
61 return dev_err_probe(dev, ret, "PPE HW config failed\n");
62
63 + ret = ppe_port_mac_init(ppe_dev);
64 + if (ret)
65 + return dev_err_probe(dev, ret,
66 + "PPE Port MAC initialization failed\n");
67 +
68 ppe_debugfs_setup(ppe_dev);
69 platform_set_drvdata(pdev, ppe_dev);
70
71 @@ -219,6 +225,9 @@ static void qcom_ppe_remove(struct platform_device *pdev)
72
73 ppe_dev = platform_get_drvdata(pdev);
74 ppe_debugfs_teardown(ppe_dev);
75 + ppe_port_mac_deinit(ppe_dev);
76 +
77 + platform_set_drvdata(pdev, NULL);
78 }
79
80 static const struct of_device_id qcom_ppe_of_match[] = {
81 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.h b/drivers/net/ethernet/qualcomm/ppe/ppe.h
82 index a2a5d1901547..020d5df2c5e3 100644
83 --- a/drivers/net/ethernet/qualcomm/ppe/ppe.h
84 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe.h
85 @@ -20,6 +20,7 @@ struct dentry;
86 * @clk_rate: PPE clock rate.
87 * @num_ports: Number of PPE ports.
88 * @debugfs_root: PPE debug root entry.
89 + * @ports: PPE MAC ports.
90 * @num_icc_paths: Number of interconnect paths.
91 * @icc_paths: Interconnect path array.
92 *
93 @@ -33,6 +34,7 @@ struct ppe_device {
94 unsigned long clk_rate;
95 unsigned int num_ports;
96 struct dentry *debugfs_root;
97 + struct ppe_ports *ports;
98 unsigned int num_icc_paths;
99 struct icc_bulk_data icc_paths[] __counted_by(num_icc_paths);
100 };
101 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_port.c b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
102 new file mode 100644
103 index 000000000000..dcc13889089e
104 --- /dev/null
105 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
106 @@ -0,0 +1,728 @@
107 +// SPDX-License-Identifier: GPL-2.0-only
108 +/*
109 + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
110 + */
111 +
112 +/* PPE Port MAC initialization and PPE port MAC functions. */
113 +
114 +#include <linux/clk.h>
115 +#include <linux/of_net.h>
116 +#include <linux/pcs/pcs-qcom-ipq-uniphy.h>
117 +#include <linux/phylink.h>
118 +#include <linux/reset.h>
119 +#include <linux/regmap.h>
120 +#include <linux/rtnetlink.h>
121 +
122 +#include "ppe.h"
123 +#include "ppe_port.h"
124 +#include "ppe_regs.h"
125 +
126 +/* PPE MAC max frame size which including 4bytes FCS */
127 +#define PPE_PORT_MAC_MAX_FRAME_SIZE 0x3000
128 +
129 +/* PPE BM port start for PPE MAC ports */
130 +#define PPE_BM_PORT_MAC_START 7
131 +
132 +/* PPE port clock and reset name */
133 +static const char * const ppe_port_clk_rst_name[] = {
134 + [PPE_PORT_CLK_RST_MAC] = "port_mac",
135 + [PPE_PORT_CLK_RST_RX] = "port_rx",
136 + [PPE_PORT_CLK_RST_TX] = "port_tx",
137 +};
138 +
139 +/* PPE port and MAC reset */
140 +static int ppe_port_mac_reset(struct ppe_port *ppe_port)
141 +{
142 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
143 + int ret;
144 +
145 + ret = reset_control_assert(ppe_port->rstcs[PPE_PORT_CLK_RST_MAC]);
146 + if (ret)
147 + goto error;
148 +
149 + ret = reset_control_assert(ppe_port->rstcs[PPE_PORT_CLK_RST_RX]);
150 + if (ret)
151 + goto error;
152 +
153 + ret = reset_control_assert(ppe_port->rstcs[PPE_PORT_CLK_RST_TX]);
154 + if (ret)
155 + goto error;
156 +
157 + /* 150ms delay is required by hardware to reset PPE port and MAC */
158 + msleep(150);
159 +
160 + ret = reset_control_deassert(ppe_port->rstcs[PPE_PORT_CLK_RST_MAC]);
161 + if (ret)
162 + goto error;
163 +
164 + ret = reset_control_deassert(ppe_port->rstcs[PPE_PORT_CLK_RST_RX]);
165 + if (ret)
166 + goto error;
167 +
168 + ret = reset_control_deassert(ppe_port->rstcs[PPE_PORT_CLK_RST_TX]);
169 + if (ret)
170 + goto error;
171 +
172 + return ret;
173 +
174 +error:
175 + dev_err(ppe_dev->dev, "%s: port %d reset fail %d\n",
176 + __func__, ppe_port->port_id, ret);
177 + return ret;
178 +}
179 +
180 +/* PPE port MAC configuration for phylink */
181 +static void ppe_port_mac_config(struct phylink_config *config,
182 + unsigned int mode,
183 + const struct phylink_link_state *state)
184 +{
185 + struct ppe_port *ppe_port = container_of(config, struct ppe_port,
186 + phylink_config);
187 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
188 + int port = ppe_port->port_id;
189 + enum ppe_mac_type mac_type;
190 + u32 val, mask;
191 + int ret;
192 +
193 + switch (state->interface) {
194 + case PHY_INTERFACE_MODE_2500BASEX:
195 + case PHY_INTERFACE_MODE_USXGMII:
196 + case PHY_INTERFACE_MODE_10GBASER:
197 + case PHY_INTERFACE_MODE_10G_QXGMII:
198 + mac_type = PPE_MAC_TYPE_XGMAC;
199 + break;
200 + case PHY_INTERFACE_MODE_QSGMII:
201 + case PHY_INTERFACE_MODE_PSGMII:
202 + case PHY_INTERFACE_MODE_SGMII:
203 + case PHY_INTERFACE_MODE_1000BASEX:
204 + mac_type = PPE_MAC_TYPE_GMAC;
205 + break;
206 + default:
207 + dev_err(ppe_dev->dev, "%s: Unsupport interface %s\n",
208 + __func__, phy_modes(state->interface));
209 + return;
210 + }
211 +
212 + /* Reset Port MAC for GMAC */
213 + if (mac_type == PPE_MAC_TYPE_GMAC) {
214 + ret = ppe_port_mac_reset(ppe_port);
215 + if (ret)
216 + goto err_mac_config;
217 + }
218 +
219 + /* Port mux to select GMAC or XGMAC */
220 + mask = PPE_PORT_SEL_XGMAC(port);
221 + val = mac_type == PPE_MAC_TYPE_GMAC ? 0 : mask;
222 + ret = regmap_update_bits(ppe_dev->regmap,
223 + PPE_PORT_MUX_CTRL_ADDR,
224 + mask, val);
225 + if (ret)
226 + goto err_mac_config;
227 +
228 + ppe_port->mac_type = mac_type;
229 +
230 + return;
231 +
232 +err_mac_config:
233 + dev_err(ppe_dev->dev, "%s: port %d MAC config fail %d\n",
234 + __func__, port, ret);
235 +}
236 +
237 +/* PPE port GMAC link up configuration */
238 +static int ppe_port_gmac_link_up(struct ppe_port *ppe_port, int speed,
239 + int duplex, bool tx_pause, bool rx_pause)
240 +{
241 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
242 + int ret, port = ppe_port->port_id;
243 + u32 reg, val;
244 +
245 + /* Set GMAC speed */
246 + switch (speed) {
247 + case SPEED_1000:
248 + val = GMAC_SPEED_1000;
249 + break;
250 + case SPEED_100:
251 + val = GMAC_SPEED_100;
252 + break;
253 + case SPEED_10:
254 + val = GMAC_SPEED_10;
255 + break;
256 + default:
257 + dev_err(ppe_dev->dev, "%s: Invalid GMAC speed %s\n",
258 + __func__, phy_speed_to_str(speed));
259 + return -EINVAL;
260 + }
261 +
262 + reg = PPE_PORT_GMAC_ADDR(port);
263 + ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_SPEED_ADDR,
264 + GMAC_SPEED_M, val);
265 + if (ret)
266 + return ret;
267 +
268 + /* Set duplex, flow control and enable GMAC */
269 + val = GMAC_TRXEN;
270 + if (duplex == DUPLEX_FULL)
271 + val |= GMAC_DUPLEX_FULL;
272 + if (tx_pause)
273 + val |= GMAC_TXFCEN;
274 + if (rx_pause)
275 + val |= GMAC_RXFCEN;
276 +
277 + ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_ENABLE_ADDR,
278 + GMAC_ENABLE_ALL, val);
279 +
280 + return ret;
281 +}
282 +
283 +/* PPE port XGMAC link up configuration */
284 +static int ppe_port_xgmac_link_up(struct ppe_port *ppe_port,
285 + phy_interface_t interface,
286 + int speed, int duplex,
287 + bool tx_pause, bool rx_pause)
288 +{
289 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
290 + int ret, port = ppe_port->port_id;
291 + u32 reg, val;
292 +
293 + /* Set XGMAC TX speed and enable TX */
294 + switch (speed) {
295 + case SPEED_10000:
296 + if (interface == PHY_INTERFACE_MODE_USXGMII)
297 + val = XGMAC_SPEED_10000_USXGMII;
298 + else
299 + val = XGMAC_SPEED_10000;
300 + break;
301 + case SPEED_5000:
302 + val = XGMAC_SPEED_5000;
303 + break;
304 + case SPEED_2500:
305 + if (interface == PHY_INTERFACE_MODE_USXGMII ||
306 + interface == PHY_INTERFACE_MODE_10G_QXGMII)
307 + val = XGMAC_SPEED_2500_USXGMII;
308 + else
309 + val = XGMAC_SPEED_2500;
310 + break;
311 + case SPEED_1000:
312 + val = XGMAC_SPEED_1000;
313 + break;
314 + case SPEED_100:
315 + val = XGMAC_SPEED_100;
316 + break;
317 + case SPEED_10:
318 + val = XGMAC_SPEED_10;
319 + break;
320 + default:
321 + dev_err(ppe_dev->dev, "%s: Invalid XGMAC speed %s\n",
322 + __func__, phy_speed_to_str(speed));
323 + return -EINVAL;
324 + }
325 +
326 + reg = PPE_PORT_XGMAC_ADDR(port);
327 + val |= XGMAC_TXEN;
328 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_TX_CONFIG_ADDR,
329 + XGMAC_SPEED_M | XGMAC_TXEN, val);
330 + if (ret)
331 + return ret;
332 +
333 + /* Set XGMAC TX flow control */
334 + val = FIELD_PREP(XGMAC_PAUSE_TIME_M, FIELD_MAX(XGMAC_PAUSE_TIME_M));
335 + val |= tx_pause ? XGMAC_TXFCEN : 0;
336 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_TX_FLOW_CTRL_ADDR,
337 + XGMAC_PAUSE_TIME_M | XGMAC_TXFCEN, val);
338 + if (ret)
339 + return ret;
340 +
341 + /* Set XGMAC RX flow control */
342 + val = rx_pause ? XGMAC_RXFCEN : 0;
343 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_RX_FLOW_CTRL_ADDR,
344 + XGMAC_RXFCEN, val);
345 + if (ret)
346 + return ret;
347 +
348 + /* Enable XGMAC RX*/
349 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_RX_CONFIG_ADDR,
350 + XGMAC_RXEN, XGMAC_RXEN);
351 +
352 + return ret;
353 +}
354 +
355 +/* PPE port MAC link up configuration for phylink */
356 +static void ppe_port_mac_link_up(struct phylink_config *config,
357 + struct phy_device *phy,
358 + unsigned int mode,
359 + phy_interface_t interface,
360 + int speed, int duplex,
361 + bool tx_pause, bool rx_pause)
362 +{
363 + struct ppe_port *ppe_port = container_of(config, struct ppe_port,
364 + phylink_config);
365 + enum ppe_mac_type mac_type = ppe_port->mac_type;
366 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
367 + int ret, port = ppe_port->port_id;
368 + u32 reg, val;
369 +
370 + if (mac_type == PPE_MAC_TYPE_GMAC)
371 + ret = ppe_port_gmac_link_up(ppe_port,
372 + speed, duplex, tx_pause, rx_pause);
373 + else
374 + ret = ppe_port_xgmac_link_up(ppe_port, interface,
375 + speed, duplex, tx_pause, rx_pause);
376 + if (ret)
377 + goto err_port_mac_link_up;
378 +
379 + /* Set PPE port BM flow control */
380 + reg = PPE_BM_PORT_FC_MODE_ADDR +
381 + PPE_BM_PORT_FC_MODE_INC * (port + PPE_BM_PORT_MAC_START);
382 + val = tx_pause ? PPE_BM_PORT_FC_MODE_EN : 0;
383 + ret = regmap_update_bits(ppe_dev->regmap, reg,
384 + PPE_BM_PORT_FC_MODE_EN, val);
385 + if (ret)
386 + goto err_port_mac_link_up;
387 +
388 + /* Enable PPE port TX */
389 + reg = PPE_PORT_BRIDGE_CTRL_ADDR + PPE_PORT_BRIDGE_CTRL_INC * port;
390 + ret = regmap_update_bits(ppe_dev->regmap, reg,
391 + PPE_PORT_BRIDGE_TXMAC_EN,
392 + PPE_PORT_BRIDGE_TXMAC_EN);
393 + if (ret)
394 + goto err_port_mac_link_up;
395 +
396 + return;
397 +
398 +err_port_mac_link_up:
399 + dev_err(ppe_dev->dev, "%s: port %d link up fail %d\n",
400 + __func__, port, ret);
401 +}
402 +
403 +/* PPE port MAC link down configuration for phylink */
404 +static void ppe_port_mac_link_down(struct phylink_config *config,
405 + unsigned int mode,
406 + phy_interface_t interface)
407 +{
408 + struct ppe_port *ppe_port = container_of(config, struct ppe_port,
409 + phylink_config);
410 + enum ppe_mac_type mac_type = ppe_port->mac_type;
411 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
412 + int ret, port = ppe_port->port_id;
413 + u32 reg;
414 +
415 + /* Disable PPE port TX */
416 + reg = PPE_PORT_BRIDGE_CTRL_ADDR + PPE_PORT_BRIDGE_CTRL_INC * port;
417 + ret = regmap_update_bits(ppe_dev->regmap, reg,
418 + PPE_PORT_BRIDGE_TXMAC_EN, 0);
419 + if (ret)
420 + goto err_port_mac_link_down;
421 +
422 + /* Disable PPE MAC */
423 + if (mac_type == PPE_MAC_TYPE_GMAC) {
424 + reg = PPE_PORT_GMAC_ADDR(port) + GMAC_ENABLE_ADDR;
425 + ret = regmap_update_bits(ppe_dev->regmap, reg, GMAC_TRXEN, 0);
426 + if (ret)
427 + goto err_port_mac_link_down;
428 + } else {
429 + reg = PPE_PORT_XGMAC_ADDR(port);
430 + ret = regmap_update_bits(ppe_dev->regmap,
431 + reg + XGMAC_RX_CONFIG_ADDR,
432 + XGMAC_RXEN, 0);
433 + if (ret)
434 + goto err_port_mac_link_down;
435 +
436 + ret = regmap_update_bits(ppe_dev->regmap,
437 + reg + XGMAC_TX_CONFIG_ADDR,
438 + XGMAC_TXEN, 0);
439 + if (ret)
440 + goto err_port_mac_link_down;
441 + }
442 +
443 + return;
444 +
445 +err_port_mac_link_down:
446 + dev_err(ppe_dev->dev, "%s: port %d link down fail %d\n",
447 + __func__, port, ret);
448 +}
449 +
450 +/* PPE port MAC PCS selection for phylink */
451 +static
452 +struct phylink_pcs *ppe_port_mac_select_pcs(struct phylink_config *config,
453 + phy_interface_t interface)
454 +{
455 + struct ppe_port *ppe_port = container_of(config, struct ppe_port,
456 + phylink_config);
457 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
458 + int ret, port = ppe_port->port_id;
459 + u32 val;
460 +
461 + /* PPE port5 can connects with PCS0 or PCS1. In PSGMII
462 + * mode, it selects PCS0; otherwise, it selects PCS1.
463 + */
464 + if (port == 5) {
465 + val = interface == PHY_INTERFACE_MODE_PSGMII ?
466 + 0 : PPE_PORT5_SEL_PCS1;
467 + ret = regmap_update_bits(ppe_dev->regmap,
468 + PPE_PORT_MUX_CTRL_ADDR,
469 + PPE_PORT5_SEL_PCS1, val);
470 + if (ret) {
471 + dev_err(ppe_dev->dev, "%s: port5 select PCS fail %d\n",
472 + __func__, ret);
473 + return NULL;
474 + }
475 + }
476 +
477 + return ppe_port->pcs;
478 +}
479 +
480 +static const struct phylink_mac_ops ppe_phylink_ops = {
481 + .mac_config = ppe_port_mac_config,
482 + .mac_link_up = ppe_port_mac_link_up,
483 + .mac_link_down = ppe_port_mac_link_down,
484 + .mac_select_pcs = ppe_port_mac_select_pcs,
485 +};
486 +
487 +/**
488 + * ppe_port_phylink_setup() - Set phylink instance for the given PPE port
489 + * @ppe_port: PPE port
490 + * @netdev: Netdevice
491 + *
492 + * Description: Wrapper function to help setup phylink for the PPE port
493 + * specified by @ppe_port and associated with the net device @netdev.
494 + *
495 + * Return: 0 upon success or a negative error upon failure.
496 + */
497 +int ppe_port_phylink_setup(struct ppe_port *ppe_port, struct net_device *netdev)
498 +{
499 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
500 + struct device_node *pcs_node;
501 + int ret;
502 +
503 + /* Create PCS */
504 + pcs_node = of_parse_phandle(ppe_port->np, "pcs-handle", 0);
505 + if (!pcs_node)
506 + return -ENODEV;
507 +
508 + ppe_port->pcs = ipq_unipcs_create(pcs_node);
509 + of_node_put(pcs_node);
510 + if (IS_ERR(ppe_port->pcs)) {
511 + dev_err(ppe_dev->dev, "%s: port %d failed to create PCS\n",
512 + __func__, ppe_port->port_id);
513 + return PTR_ERR(ppe_port->pcs);
514 + }
515 +
516 + /* Port phylink capability */
517 + ppe_port->phylink_config.dev = &netdev->dev;
518 + ppe_port->phylink_config.type = PHYLINK_NETDEV;
519 + ppe_port->phylink_config.mac_capabilities = MAC_ASYM_PAUSE |
520 + MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000 |
521 + MAC_2500FD | MAC_5000FD | MAC_10000FD;
522 + __set_bit(PHY_INTERFACE_MODE_QSGMII,
523 + ppe_port->phylink_config.supported_interfaces);
524 + __set_bit(PHY_INTERFACE_MODE_PSGMII,
525 + ppe_port->phylink_config.supported_interfaces);
526 + __set_bit(PHY_INTERFACE_MODE_SGMII,
527 + ppe_port->phylink_config.supported_interfaces);
528 + __set_bit(PHY_INTERFACE_MODE_1000BASEX,
529 + ppe_port->phylink_config.supported_interfaces);
530 + __set_bit(PHY_INTERFACE_MODE_2500BASEX,
531 + ppe_port->phylink_config.supported_interfaces);
532 + __set_bit(PHY_INTERFACE_MODE_USXGMII,
533 + ppe_port->phylink_config.supported_interfaces);
534 + __set_bit(PHY_INTERFACE_MODE_10GBASER,
535 + ppe_port->phylink_config.supported_interfaces);
536 + __set_bit(PHY_INTERFACE_MODE_10G_QXGMII,
537 + ppe_port->phylink_config.supported_interfaces);
538 +
539 + /* Create phylink */
540 + ppe_port->phylink = phylink_create(&ppe_port->phylink_config,
541 + of_fwnode_handle(ppe_port->np),
542 + ppe_port->interface,
543 + &ppe_phylink_ops);
544 + if (IS_ERR(ppe_port->phylink)) {
545 + dev_err(ppe_dev->dev, "%s: port %d failed to create phylink\n",
546 + __func__, ppe_port->port_id);
547 + ret = PTR_ERR(ppe_port->phylink);
548 + goto err_free_pcs;
549 + }
550 +
551 + /* Connect phylink */
552 + ret = phylink_of_phy_connect(ppe_port->phylink, ppe_port->np, 0);
553 + if (ret) {
554 + dev_err(ppe_dev->dev, "%s: port %d failed to connect phylink\n",
555 + __func__, ppe_port->port_id);
556 + goto err_free_phylink;
557 + }
558 +
559 + return 0;
560 +
561 +err_free_phylink:
562 + phylink_destroy(ppe_port->phylink);
563 + ppe_port->phylink = NULL;
564 +err_free_pcs:
565 + ipq_unipcs_destroy(ppe_port->pcs);
566 + ppe_port->pcs = NULL;
567 + return ret;
568 +}
569 +
570 +/**
571 + * ppe_port_phylink_destroy() - Destroy phylink instance for the given PPE port
572 + * @ppe_port: PPE port
573 + *
574 + * Description: Wrapper function to help destroy phylink for the PPE port
575 + * specified by @ppe_port.
576 + */
577 +void ppe_port_phylink_destroy(struct ppe_port *ppe_port)
578 +{
579 + /* Destroy phylink */
580 + if (ppe_port->phylink) {
581 + rtnl_lock();
582 + phylink_disconnect_phy(ppe_port->phylink);
583 + rtnl_unlock();
584 + phylink_destroy(ppe_port->phylink);
585 + ppe_port->phylink = NULL;
586 + }
587 +
588 + /* Destroy PCS */
589 + if (ppe_port->pcs) {
590 + ipq_unipcs_destroy(ppe_port->pcs);
591 + ppe_port->pcs = NULL;
592 + }
593 +}
594 +
595 +/* PPE port clock initialization */
596 +static int ppe_port_clock_init(struct ppe_port *ppe_port)
597 +{
598 + struct device_node *port_node = ppe_port->np;
599 + struct reset_control *rstc;
600 + struct clk *clk;
601 + int i, j, ret;
602 +
603 + for (i = 0; i < PPE_PORT_CLK_RST_MAX; i++) {
604 + /* Get PPE port resets which will be used to reset PPE
605 + * port and MAC.
606 + */
607 + rstc = of_reset_control_get_exclusive(port_node,
608 + ppe_port_clk_rst_name[i]);
609 + if (IS_ERR(rstc)) {
610 + ret = PTR_ERR(rstc);
611 + goto err_rst;
612 + }
613 +
614 + clk = of_clk_get_by_name(port_node, ppe_port_clk_rst_name[i]);
615 + if (IS_ERR(clk)) {
616 + ret = PTR_ERR(clk);
617 + goto err_clk_get;
618 + }
619 +
620 + ret = clk_prepare_enable(clk);
621 + if (ret)
622 + goto err_clk_en;
623 +
624 + ppe_port->clks[i] = clk;
625 + ppe_port->rstcs[i] = rstc;
626 + }
627 +
628 + return 0;
629 +
630 +err_clk_en:
631 + clk_put(clk);
632 +err_clk_get:
633 + reset_control_put(rstc);
634 +err_rst:
635 + for (j = 0; j < i; j++) {
636 + clk_disable_unprepare(ppe_port->clks[j]);
637 + clk_put(ppe_port->clks[j]);
638 + reset_control_put(ppe_port->rstcs[j]);
639 + }
640 +
641 + return ret;
642 +}
643 +
644 +/* PPE port clock deinitialization */
645 +static void ppe_port_clock_deinit(struct ppe_port *ppe_port)
646 +{
647 + int i;
648 +
649 + for (i = 0; i < PPE_PORT_CLK_RST_MAX; i++) {
650 + clk_disable_unprepare(ppe_port->clks[i]);
651 + clk_put(ppe_port->clks[i]);
652 + reset_control_put(ppe_port->rstcs[i]);
653 + }
654 +}
655 +
656 +/* PPE port MAC hardware init configuration */
657 +static int ppe_port_mac_hw_init(struct ppe_port *ppe_port)
658 +{
659 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
660 + int ret, port = ppe_port->port_id;
661 + u32 reg, val;
662 +
663 + /* GMAC RX and TX are initialized as disabled */
664 + reg = PPE_PORT_GMAC_ADDR(port);
665 + ret = regmap_update_bits(ppe_dev->regmap,
666 + reg + GMAC_ENABLE_ADDR, GMAC_TRXEN, 0);
667 + if (ret)
668 + return ret;
669 +
670 + /* GMAC max frame size configuration */
671 + val = FIELD_PREP(GMAC_JUMBO_SIZE_M, PPE_PORT_MAC_MAX_FRAME_SIZE);
672 + ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_JUMBO_SIZE_ADDR,
673 + GMAC_JUMBO_SIZE_M, val);
674 + if (ret)
675 + return ret;
676 +
677 + val = FIELD_PREP(GMAC_MAXFRAME_SIZE_M, PPE_PORT_MAC_MAX_FRAME_SIZE);
678 + val |= FIELD_PREP(GMAC_TX_THD_M, 0x1);
679 + ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_CTRL_ADDR,
680 + GMAC_CTRL_MASK, val);
681 + if (ret)
682 + return ret;
683 +
684 + val = FIELD_PREP(GMAC_HIGH_IPG_M, 0xc);
685 + ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_DBG_CTRL_ADDR,
686 + GMAC_HIGH_IPG_M, val);
687 + if (ret)
688 + return ret;
689 +
690 + /* Enable and reset GMAC MIB counters and set as read clear
691 + * mode, the GMAC MIB counters will be cleared after reading.
692 + */
693 + ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_MIB_CTRL_ADDR,
694 + GMAC_MIB_CTRL_MASK, GMAC_MIB_CTRL_MASK);
695 + if (ret)
696 + return ret;
697 +
698 + ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_MIB_CTRL_ADDR,
699 + GMAC_MIB_RST, 0);
700 + if (ret)
701 + return ret;
702 +
703 + /* XGMAC RX and TX disabled and max frame size configuration */
704 + reg = PPE_PORT_XGMAC_ADDR(port);
705 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_TX_CONFIG_ADDR,
706 + XGMAC_TXEN | XGMAC_JD, XGMAC_JD);
707 + if (ret)
708 + return ret;
709 +
710 + val = FIELD_PREP(XGMAC_GPSL_M, PPE_PORT_MAC_MAX_FRAME_SIZE);
711 + val |= XGMAC_GPSLEN;
712 + val |= XGMAC_CST;
713 + val |= XGMAC_ACS;
714 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_RX_CONFIG_ADDR,
715 + XGMAC_RX_CONFIG_MASK, val);
716 + if (ret)
717 + return ret;
718 +
719 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_WD_TIMEOUT_ADDR,
720 + XGMAC_WD_TIMEOUT_MASK, XGMAC_WD_TIMEOUT_VAL);
721 + if (ret)
722 + return ret;
723 +
724 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_PKT_FILTER_ADDR,
725 + XGMAC_PKT_FILTER_MASK, XGMAC_PKT_FILTER_VAL);
726 + if (ret)
727 + return ret;
728 +
729 + /* Enable and reset XGMAC MIB counters */
730 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_MMC_CTRL_ADDR,
731 + XGMAC_MCF | XGMAC_CNTRST, XGMAC_CNTRST);
732 +
733 + return ret;
734 +}
735 +
736 +/**
737 + * ppe_port_mac_init() - Initialization of PPE ports for the PPE device
738 + * @ppe_dev: PPE device
739 + *
740 + * Description: Initialize the PPE MAC ports on the PPE device specified
741 + * by @ppe_dev.
742 + *
743 + * Return: 0 upon success or a negative error upon failure.
744 + */
745 +int ppe_port_mac_init(struct ppe_device *ppe_dev)
746 +{
747 + struct device_node *ports_node, *port_node;
748 + int port, num, ret, j, i = 0;
749 + struct ppe_ports *ppe_ports;
750 + phy_interface_t phy_mode;
751 +
752 + ports_node = of_get_child_by_name(ppe_dev->dev->of_node,
753 + "ethernet-ports");
754 + if (!ports_node) {
755 + dev_err(ppe_dev->dev, "Failed to get ports node\n");
756 + return -ENODEV;
757 + }
758 +
759 + num = of_get_available_child_count(ports_node);
760 +
761 + ppe_ports = devm_kzalloc(ppe_dev->dev,
762 + struct_size(ppe_ports, port, num),
763 + GFP_KERNEL);
764 + if (!ppe_ports) {
765 + ret = -ENOMEM;
766 + goto err_ports_node;
767 + }
768 +
769 + ppe_dev->ports = ppe_ports;
770 + ppe_ports->num = num;
771 +
772 + for_each_available_child_of_node(ports_node, port_node) {
773 + ret = of_property_read_u32(port_node, "reg", &port);
774 + if (ret) {
775 + dev_err(ppe_dev->dev, "Failed to get port id\n");
776 + goto err_port_node;
777 + }
778 +
779 + ret = of_get_phy_mode(port_node, &phy_mode);
780 + if (ret) {
781 + dev_err(ppe_dev->dev, "Failed to get phy mode\n");
782 + goto err_port_node;
783 + }
784 +
785 + ppe_ports->port[i].ppe_dev = ppe_dev;
786 + ppe_ports->port[i].port_id = port;
787 + ppe_ports->port[i].np = port_node;
788 + ppe_ports->port[i].interface = phy_mode;
789 +
790 + ret = ppe_port_clock_init(&ppe_ports->port[i]);
791 + if (ret) {
792 + dev_err(ppe_dev->dev, "Failed to initialize port clocks\n");
793 + goto err_port_clk;
794 + }
795 +
796 + ret = ppe_port_mac_hw_init(&ppe_ports->port[i]);
797 + if (ret) {
798 + dev_err(ppe_dev->dev, "Failed to initialize MAC hardware\n");
799 + goto err_port_node;
800 + }
801 +
802 + i++;
803 + }
804 +
805 + of_node_put(ports_node);
806 + return 0;
807 +
808 +err_port_clk:
809 + for (j = 0; j < i; j++)
810 + ppe_port_clock_deinit(&ppe_ports->port[j]);
811 +err_port_node:
812 + of_node_put(port_node);
813 +err_ports_node:
814 + of_node_put(ports_node);
815 + return ret;
816 +}
817 +
818 +/**
819 + * ppe_port_mac_deinit() - Deinitialization of PPE ports for the PPE device
820 + * @ppe_dev: PPE device
821 + *
822 + * Description: Deinitialize the PPE MAC ports on the PPE device specified
823 + * by @ppe_dev.
824 + */
825 +void ppe_port_mac_deinit(struct ppe_device *ppe_dev)
826 +{
827 + struct ppe_port *ppe_port;
828 + int i;
829 +
830 + for (i = 0; i < ppe_dev->ports->num; i++) {
831 + ppe_port = &ppe_dev->ports->port[i];
832 + ppe_port_clock_deinit(ppe_port);
833 + }
834 +}
835 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_port.h b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
836 new file mode 100644
837 index 000000000000..194f65815011
838 --- /dev/null
839 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
840 @@ -0,0 +1,76 @@
841 +/* SPDX-License-Identifier: GPL-2.0-only
842 + *
843 + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
844 + */
845 +
846 +#ifndef __PPE_PORT_H__
847 +#define __PPE_PORT_H__
848 +
849 +#include <linux/phylink.h>
850 +
851 +/**
852 + * enum ppe_port_clk_rst_type - PPE port clock and reset ID type
853 + * @PPE_PORT_CLK_RST_MAC: The clock and reset ID for port MAC
854 + * @PPE_PORT_CLK_RST_RX: The clock and reset ID for port receive path
855 + * @PPE_PORT_CLK_RST_TX: The clock and reset for port transmit path
856 + * @PPE_PORT_CLK_RST_MAX: The maximum of port clock and reset
857 + */
858 +enum ppe_port_clk_rst_type {
859 + PPE_PORT_CLK_RST_MAC,
860 + PPE_PORT_CLK_RST_RX,
861 + PPE_PORT_CLK_RST_TX,
862 + PPE_PORT_CLK_RST_MAX,
863 +};
864 +
865 +/**
866 + * enum ppe_mac_type - PPE MAC type
867 + * @PPE_MAC_TYPE_GMAC: GMAC type
868 + * @PPE_MAC_TYPE_XGMAC: XGMAC type
869 + */
870 +enum ppe_mac_type {
871 + PPE_MAC_TYPE_GMAC,
872 + PPE_MAC_TYPE_XGMAC,
873 +};
874 +
875 +/**
876 + * struct ppe_port - Private data for each PPE port
877 + * @phylink: Linux phylink instance
878 + * @phylink_config: Linux phylink configurations
879 + * @pcs: Linux phylink PCS instance
880 + * @np: Port device tree node
881 + * @ppe_dev: Back pointer to PPE device private data
882 + * @interface: Port interface mode
883 + * @mac_type: Port MAC type, GMAC or XGMAC
884 + * @port_id: Port ID
885 + * @clks: Port clocks
886 + * @rstcs: Port resets
887 + */
888 +struct ppe_port {
889 + struct phylink *phylink;
890 + struct phylink_config phylink_config;
891 + struct phylink_pcs *pcs;
892 + struct device_node *np;
893 + struct ppe_device *ppe_dev;
894 + phy_interface_t interface;
895 + enum ppe_mac_type mac_type;
896 + int port_id;
897 + struct clk *clks[PPE_PORT_CLK_RST_MAX];
898 + struct reset_control *rstcs[PPE_PORT_CLK_RST_MAX];
899 +};
900 +
901 +/**
902 + * struct ppe_ports - Array of PPE ports
903 + * @num: Number of PPE ports
904 + * @port: Each PPE port private data
905 + */
906 +struct ppe_ports {
907 + unsigned int num;
908 + struct ppe_port port[] __counted_by(num);
909 +};
910 +
911 +int ppe_port_mac_init(struct ppe_device *ppe_dev);
912 +void ppe_port_mac_deinit(struct ppe_device *ppe_dev);
913 +int ppe_port_phylink_setup(struct ppe_port *ppe_port,
914 + struct net_device *netdev);
915 +void ppe_port_phylink_destroy(struct ppe_port *ppe_port);
916 +#endif
917 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
918 index e84633d0f572..34b659ac0c37 100644
919 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
920 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
921 @@ -7,6 +7,17 @@
922 #ifndef __PPE_REGS_H__
923 #define __PPE_REGS_H__
924
925 +/* PPE port mux select control register */
926 +#define PPE_PORT_MUX_CTRL_ADDR 0x10
927 +#define PPE_PORT6_SEL_XGMAC BIT(13)
928 +#define PPE_PORT5_SEL_XGMAC BIT(12)
929 +#define PPE_PORT4_SEL_XGMAC BIT(11)
930 +#define PPE_PORT3_SEL_XGMAC BIT(10)
931 +#define PPE_PORT2_SEL_XGMAC BIT(9)
932 +#define PPE_PORT1_SEL_XGMAC BIT(8)
933 +#define PPE_PORT5_SEL_PCS1 BIT(4)
934 +#define PPE_PORT_SEL_XGMAC(x) (BIT(8) << ((x) - 1))
935 +
936 /* There are 15 BM ports and 4 BM groups supported by PPE,
937 * BM port (0-7) is matched to EDMA port 0, BM port (8-13) is matched
938 * to PPE physical port 1-6, BM port 14 is matched to EIP.
939 @@ -545,4 +556,116 @@
940 #define PPE_ENQ_OPR_TBL_INC 0x10
941 #define PPE_ENQ_OPR_TBL_ENQ_DISABLE BIT(0)
942
943 +/* PPE GMAC and XGMAC register base address */
944 +#define PPE_PORT_GMAC_ADDR(x) (0x001000 + ((x) - 1) * 0x200)
945 +#define PPE_PORT_XGMAC_ADDR(x) (0x500000 + ((x) - 1) * 0x4000)
946 +
947 +/* GMAC enable register */
948 +#define GMAC_ENABLE_ADDR 0x0
949 +#define GMAC_TXFCEN BIT(6)
950 +#define GMAC_RXFCEN BIT(5)
951 +#define GMAC_DUPLEX_FULL BIT(4)
952 +#define GMAC_TXEN BIT(1)
953 +#define GMAC_RXEN BIT(0)
954 +
955 +#define GMAC_TRXEN \
956 + (GMAC_TXEN | GMAC_RXEN)
957 +#define GMAC_ENABLE_ALL \
958 + (GMAC_TXFCEN | GMAC_RXFCEN | GMAC_DUPLEX_FULL | GMAC_TXEN | GMAC_RXEN)
959 +
960 +/* GMAC speed register */
961 +#define GMAC_SPEED_ADDR 0x4
962 +#define GMAC_SPEED_M GENMASK(1, 0)
963 +#define GMAC_SPEED_10 0
964 +#define GMAC_SPEED_100 1
965 +#define GMAC_SPEED_1000 2
966 +
967 +/* GMAC control register */
968 +#define GMAC_CTRL_ADDR 0x18
969 +#define GMAC_TX_THD_M GENMASK(27, 24)
970 +#define GMAC_MAXFRAME_SIZE_M GENMASK(21, 8)
971 +#define GMAC_CRS_SEL BIT(6)
972 +
973 +#define GMAC_CTRL_MASK \
974 + (GMAC_TX_THD_M | GMAC_MAXFRAME_SIZE_M | GMAC_CRS_SEL)
975 +
976 +/* GMAC debug control register */
977 +#define GMAC_DBG_CTRL_ADDR 0x1c
978 +#define GMAC_HIGH_IPG_M GENMASK(15, 8)
979 +
980 +/* GMAC jumbo size register */
981 +#define GMAC_JUMBO_SIZE_ADDR 0x30
982 +#define GMAC_JUMBO_SIZE_M GENMASK(13, 0)
983 +
984 +/* GMAC MIB control register */
985 +#define GMAC_MIB_CTRL_ADDR 0x34
986 +#define GMAC_MIB_RD_CLR BIT(2)
987 +#define GMAC_MIB_RST BIT(1)
988 +#define GMAC_MIB_EN BIT(0)
989 +
990 +#define GMAC_MIB_CTRL_MASK \
991 + (GMAC_MIB_RD_CLR | GMAC_MIB_RST | GMAC_MIB_EN)
992 +
993 +/* XGMAC TX configuration register */
994 +#define XGMAC_TX_CONFIG_ADDR 0x0
995 +#define XGMAC_SPEED_M GENMASK(31, 29)
996 +#define XGMAC_SPEED_10000_USXGMII FIELD_PREP(XGMAC_SPEED_M, 4)
997 +#define XGMAC_SPEED_10000 FIELD_PREP(XGMAC_SPEED_M, 0)
998 +#define XGMAC_SPEED_5000 FIELD_PREP(XGMAC_SPEED_M, 5)
999 +#define XGMAC_SPEED_2500_USXGMII FIELD_PREP(XGMAC_SPEED_M, 6)
1000 +#define XGMAC_SPEED_2500 FIELD_PREP(XGMAC_SPEED_M, 2)
1001 +#define XGMAC_SPEED_1000 FIELD_PREP(XGMAC_SPEED_M, 3)
1002 +#define XGMAC_SPEED_100 XGMAC_SPEED_1000
1003 +#define XGMAC_SPEED_10 XGMAC_SPEED_1000
1004 +#define XGMAC_JD BIT(16)
1005 +#define XGMAC_TXEN BIT(0)
1006 +
1007 +/* XGMAC RX configuration register */
1008 +#define XGMAC_RX_CONFIG_ADDR 0x4
1009 +#define XGMAC_GPSL_M GENMASK(29, 16)
1010 +#define XGMAC_WD BIT(7)
1011 +#define XGMAC_GPSLEN BIT(6)
1012 +#define XGMAC_CST BIT(2)
1013 +#define XGMAC_ACS BIT(1)
1014 +#define XGMAC_RXEN BIT(0)
1015 +
1016 +#define XGMAC_RX_CONFIG_MASK \
1017 + (XGMAC_GPSL_M | XGMAC_WD | XGMAC_GPSLEN | XGMAC_CST | \
1018 + XGMAC_ACS | XGMAC_RXEN)
1019 +
1020 +/* XGMAC packet filter register */
1021 +#define XGMAC_PKT_FILTER_ADDR 0x8
1022 +#define XGMAC_RA BIT(31)
1023 +#define XGMAC_PCF_M GENMASK(7, 6)
1024 +#define XGMAC_PR BIT(0)
1025 +
1026 +#define XGMAC_PKT_FILTER_MASK \
1027 + (XGMAC_RA | XGMAC_PCF_M | XGMAC_PR)
1028 +#define XGMAC_PKT_FILTER_VAL \
1029 + (XGMAC_RA | XGMAC_PR | FIELD_PREP(XGMAC_PCF_M, 0x2))
1030 +
1031 +/* XGMAC watchdog timeout register */
1032 +#define XGMAC_WD_TIMEOUT_ADDR 0xc
1033 +#define XGMAC_PWE BIT(8)
1034 +#define XGMAC_WTO_M GENMASK(3, 0)
1035 +
1036 +#define XGMAC_WD_TIMEOUT_MASK \
1037 + (XGMAC_PWE | XGMAC_WTO_M)
1038 +#define XGMAC_WD_TIMEOUT_VAL \
1039 + (XGMAC_PWE | FIELD_PREP(XGMAC_WTO_M, 0xb))
1040 +
1041 +/* XGMAC TX flow control register */
1042 +#define XGMAC_TX_FLOW_CTRL_ADDR 0x70
1043 +#define XGMAC_PAUSE_TIME_M GENMASK(31, 16)
1044 +#define XGMAC_TXFCEN BIT(1)
1045 +
1046 +/* XGMAC RX flow control register */
1047 +#define XGMAC_RX_FLOW_CTRL_ADDR 0x90
1048 +#define XGMAC_RXFCEN BIT(0)
1049 +
1050 +/* XGMAC management counters control register */
1051 +#define XGMAC_MMC_CTRL_ADDR 0x800
1052 +#define XGMAC_MCF BIT(3)
1053 +#define XGMAC_CNTRST BIT(0)
1054 +
1055 #endif
1056 --
1057 2.45.2
1058