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