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
7 Add MAC initialization and phylink functions for PPE MAC ports.
9 Change-Id: I39dcba671732392bcfa2e734473fd083989bfbec
10 Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
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
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
32 + select PCS_QCOM_IPQ_UNIPHY
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
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
53 #include "ppe_config.h"
54 #include "ppe_debugfs.h"
55 +#include "ppe_port.h"
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)
61 return dev_err_probe(dev, ret, "PPE HW config failed\n");
63 + ret = ppe_port_mac_init(ppe_dev);
65 + return dev_err_probe(dev, ret,
66 + "PPE Port MAC initialization failed\n");
68 ppe_debugfs_setup(ppe_dev);
69 platform_set_drvdata(pdev, ppe_dev);
71 @@ -219,6 +225,9 @@ static void qcom_ppe_remove(struct platform_device *pdev)
73 ppe_dev = platform_get_drvdata(pdev);
74 ppe_debugfs_teardown(ppe_dev);
75 + ppe_port_mac_deinit(ppe_dev);
77 + platform_set_drvdata(pdev, NULL);
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.
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);
101 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_port.c b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
103 index 000000000000..dcc13889089e
105 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
107 +// SPDX-License-Identifier: GPL-2.0-only
109 + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
112 +/* PPE Port MAC initialization and PPE port MAC functions. */
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>
123 +#include "ppe_port.h"
124 +#include "ppe_regs.h"
126 +/* PPE MAC max frame size which including 4bytes FCS */
127 +#define PPE_PORT_MAC_MAX_FRAME_SIZE 0x3000
129 +/* PPE BM port start for PPE MAC ports */
130 +#define PPE_BM_PORT_MAC_START 7
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",
139 +/* PPE port and MAC reset */
140 +static int ppe_port_mac_reset(struct ppe_port *ppe_port)
142 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
145 + ret = reset_control_assert(ppe_port->rstcs[PPE_PORT_CLK_RST_MAC]);
149 + ret = reset_control_assert(ppe_port->rstcs[PPE_PORT_CLK_RST_RX]);
153 + ret = reset_control_assert(ppe_port->rstcs[PPE_PORT_CLK_RST_TX]);
157 + /* 150ms delay is required by hardware to reset PPE port and MAC */
160 + ret = reset_control_deassert(ppe_port->rstcs[PPE_PORT_CLK_RST_MAC]);
164 + ret = reset_control_deassert(ppe_port->rstcs[PPE_PORT_CLK_RST_RX]);
168 + ret = reset_control_deassert(ppe_port->rstcs[PPE_PORT_CLK_RST_TX]);
175 + dev_err(ppe_dev->dev, "%s: port %d reset fail %d\n",
176 + __func__, ppe_port->port_id, ret);
180 +/* PPE port MAC configuration for phylink */
181 +static void ppe_port_mac_config(struct phylink_config *config,
183 + const struct phylink_link_state *state)
185 + struct ppe_port *ppe_port = container_of(config, struct ppe_port,
187 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
188 + int port = ppe_port->port_id;
189 + enum ppe_mac_type mac_type;
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;
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;
207 + dev_err(ppe_dev->dev, "%s: Unsupport interface %s\n",
208 + __func__, phy_modes(state->interface));
212 + /* Reset Port MAC for GMAC */
213 + if (mac_type == PPE_MAC_TYPE_GMAC) {
214 + ret = ppe_port_mac_reset(ppe_port);
216 + goto err_mac_config;
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,
226 + goto err_mac_config;
228 + ppe_port->mac_type = mac_type;
233 + dev_err(ppe_dev->dev, "%s: port %d MAC config fail %d\n",
234 + __func__, port, ret);
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)
241 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
242 + int ret, port = ppe_port->port_id;
245 + /* Set GMAC speed */
248 + val = GMAC_SPEED_1000;
251 + val = GMAC_SPEED_100;
254 + val = GMAC_SPEED_10;
257 + dev_err(ppe_dev->dev, "%s: Invalid GMAC speed %s\n",
258 + __func__, phy_speed_to_str(speed));
262 + reg = PPE_PORT_GMAC_ADDR(port);
263 + ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_SPEED_ADDR,
264 + GMAC_SPEED_M, val);
268 + /* Set duplex, flow control and enable GMAC */
270 + if (duplex == DUPLEX_FULL)
271 + val |= GMAC_DUPLEX_FULL;
273 + val |= GMAC_TXFCEN;
275 + val |= GMAC_RXFCEN;
277 + ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_ENABLE_ADDR,
278 + GMAC_ENABLE_ALL, val);
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)
289 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
290 + int ret, port = ppe_port->port_id;
293 + /* Set XGMAC TX speed and enable TX */
296 + if (interface == PHY_INTERFACE_MODE_USXGMII)
297 + val = XGMAC_SPEED_10000_USXGMII;
299 + val = XGMAC_SPEED_10000;
302 + val = XGMAC_SPEED_5000;
305 + if (interface == PHY_INTERFACE_MODE_USXGMII ||
306 + interface == PHY_INTERFACE_MODE_10G_QXGMII)
307 + val = XGMAC_SPEED_2500_USXGMII;
309 + val = XGMAC_SPEED_2500;
312 + val = XGMAC_SPEED_1000;
315 + val = XGMAC_SPEED_100;
318 + val = XGMAC_SPEED_10;
321 + dev_err(ppe_dev->dev, "%s: Invalid XGMAC speed %s\n",
322 + __func__, phy_speed_to_str(speed));
326 + reg = PPE_PORT_XGMAC_ADDR(port);
328 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_TX_CONFIG_ADDR,
329 + XGMAC_SPEED_M | XGMAC_TXEN, val);
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);
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);
348 + /* Enable XGMAC RX*/
349 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_RX_CONFIG_ADDR,
350 + XGMAC_RXEN, XGMAC_RXEN);
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,
359 + phy_interface_t interface,
360 + int speed, int duplex,
361 + bool tx_pause, bool rx_pause)
363 + struct ppe_port *ppe_port = container_of(config, struct ppe_port,
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;
370 + if (mac_type == PPE_MAC_TYPE_GMAC)
371 + ret = ppe_port_gmac_link_up(ppe_port,
372 + speed, duplex, tx_pause, rx_pause);
374 + ret = ppe_port_xgmac_link_up(ppe_port, interface,
375 + speed, duplex, tx_pause, rx_pause);
377 + goto err_port_mac_link_up;
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);
386 + goto err_port_mac_link_up;
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);
394 + goto err_port_mac_link_up;
398 +err_port_mac_link_up:
399 + dev_err(ppe_dev->dev, "%s: port %d link up fail %d\n",
400 + __func__, port, ret);
403 +/* PPE port MAC link down configuration for phylink */
404 +static void ppe_port_mac_link_down(struct phylink_config *config,
406 + phy_interface_t interface)
408 + struct ppe_port *ppe_port = container_of(config, struct ppe_port,
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;
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);
420 + goto err_port_mac_link_down;
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);
427 + goto err_port_mac_link_down;
429 + reg = PPE_PORT_XGMAC_ADDR(port);
430 + ret = regmap_update_bits(ppe_dev->regmap,
431 + reg + XGMAC_RX_CONFIG_ADDR,
434 + goto err_port_mac_link_down;
436 + ret = regmap_update_bits(ppe_dev->regmap,
437 + reg + XGMAC_TX_CONFIG_ADDR,
440 + goto err_port_mac_link_down;
445 +err_port_mac_link_down:
446 + dev_err(ppe_dev->dev, "%s: port %d link down fail %d\n",
447 + __func__, port, ret);
450 +/* PPE port MAC PCS selection for phylink */
452 +struct phylink_pcs *ppe_port_mac_select_pcs(struct phylink_config *config,
453 + phy_interface_t interface)
455 + struct ppe_port *ppe_port = container_of(config, struct ppe_port,
457 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
458 + int ret, port = ppe_port->port_id;
461 + /* PPE port5 can connects with PCS0 or PCS1. In PSGMII
462 + * mode, it selects PCS0; otherwise, it selects PCS1.
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);
471 + dev_err(ppe_dev->dev, "%s: port5 select PCS fail %d\n",
477 + return ppe_port->pcs;
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,
488 + * ppe_port_phylink_setup() - Set phylink instance for the given PPE port
489 + * @ppe_port: PPE port
490 + * @netdev: Netdevice
492 + * Description: Wrapper function to help setup phylink for the PPE port
493 + * specified by @ppe_port and associated with the net device @netdev.
495 + * Return: 0 upon success or a negative error upon failure.
497 +int ppe_port_phylink_setup(struct ppe_port *ppe_port, struct net_device *netdev)
499 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
500 + struct device_node *pcs_node;
504 + pcs_node = of_parse_phandle(ppe_port->np, "pcs-handle", 0);
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);
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);
539 + /* Create phylink */
540 + ppe_port->phylink = phylink_create(&ppe_port->phylink_config,
541 + of_fwnode_handle(ppe_port->np),
542 + ppe_port->interface,
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);
551 + /* Connect phylink */
552 + ret = phylink_of_phy_connect(ppe_port->phylink, ppe_port->np, 0);
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;
562 + phylink_destroy(ppe_port->phylink);
563 + ppe_port->phylink = NULL;
565 + ipq_unipcs_destroy(ppe_port->pcs);
566 + ppe_port->pcs = NULL;
571 + * ppe_port_phylink_destroy() - Destroy phylink instance for the given PPE port
572 + * @ppe_port: PPE port
574 + * Description: Wrapper function to help destroy phylink for the PPE port
575 + * specified by @ppe_port.
577 +void ppe_port_phylink_destroy(struct ppe_port *ppe_port)
579 + /* Destroy phylink */
580 + if (ppe_port->phylink) {
582 + phylink_disconnect_phy(ppe_port->phylink);
584 + phylink_destroy(ppe_port->phylink);
585 + ppe_port->phylink = NULL;
589 + if (ppe_port->pcs) {
590 + ipq_unipcs_destroy(ppe_port->pcs);
591 + ppe_port->pcs = NULL;
595 +/* PPE port clock initialization */
596 +static int ppe_port_clock_init(struct ppe_port *ppe_port)
598 + struct device_node *port_node = ppe_port->np;
599 + struct reset_control *rstc;
603 + for (i = 0; i < PPE_PORT_CLK_RST_MAX; i++) {
604 + /* Get PPE port resets which will be used to reset PPE
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);
614 + clk = of_clk_get_by_name(port_node, ppe_port_clk_rst_name[i]);
616 + ret = PTR_ERR(clk);
620 + ret = clk_prepare_enable(clk);
624 + ppe_port->clks[i] = clk;
625 + ppe_port->rstcs[i] = rstc;
633 + reset_control_put(rstc);
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]);
644 +/* PPE port clock deinitialization */
645 +static void ppe_port_clock_deinit(struct ppe_port *ppe_port)
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]);
656 +/* PPE port MAC hardware init configuration */
657 +static int ppe_port_mac_hw_init(struct ppe_port *ppe_port)
659 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
660 + int ret, port = ppe_port->port_id;
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);
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);
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);
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);
690 + /* Enable and reset GMAC MIB counters and set as read clear
691 + * mode, the GMAC MIB counters will be cleared after reading.
693 + ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_MIB_CTRL_ADDR,
694 + GMAC_MIB_CTRL_MASK, GMAC_MIB_CTRL_MASK);
698 + ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_MIB_CTRL_ADDR,
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);
710 + val = FIELD_PREP(XGMAC_GPSL_M, PPE_PORT_MAC_MAX_FRAME_SIZE);
711 + val |= XGMAC_GPSLEN;
714 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_RX_CONFIG_ADDR,
715 + XGMAC_RX_CONFIG_MASK, val);
719 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_WD_TIMEOUT_ADDR,
720 + XGMAC_WD_TIMEOUT_MASK, XGMAC_WD_TIMEOUT_VAL);
724 + ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_PKT_FILTER_ADDR,
725 + XGMAC_PKT_FILTER_MASK, XGMAC_PKT_FILTER_VAL);
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);
737 + * ppe_port_mac_init() - Initialization of PPE ports for the PPE device
738 + * @ppe_dev: PPE device
740 + * Description: Initialize the PPE MAC ports on the PPE device specified
743 + * Return: 0 upon success or a negative error upon failure.
745 +int ppe_port_mac_init(struct ppe_device *ppe_dev)
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;
752 + ports_node = of_get_child_by_name(ppe_dev->dev->of_node,
755 + dev_err(ppe_dev->dev, "Failed to get ports node\n");
759 + num = of_get_available_child_count(ports_node);
761 + ppe_ports = devm_kzalloc(ppe_dev->dev,
762 + struct_size(ppe_ports, port, num),
766 + goto err_ports_node;
769 + ppe_dev->ports = ppe_ports;
770 + ppe_ports->num = num;
772 + for_each_available_child_of_node(ports_node, port_node) {
773 + ret = of_property_read_u32(port_node, "reg", &port);
775 + dev_err(ppe_dev->dev, "Failed to get port id\n");
776 + goto err_port_node;
779 + ret = of_get_phy_mode(port_node, &phy_mode);
781 + dev_err(ppe_dev->dev, "Failed to get phy mode\n");
782 + goto err_port_node;
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;
790 + ret = ppe_port_clock_init(&ppe_ports->port[i]);
792 + dev_err(ppe_dev->dev, "Failed to initialize port clocks\n");
796 + ret = ppe_port_mac_hw_init(&ppe_ports->port[i]);
798 + dev_err(ppe_dev->dev, "Failed to initialize MAC hardware\n");
799 + goto err_port_node;
805 + of_node_put(ports_node);
809 + for (j = 0; j < i; j++)
810 + ppe_port_clock_deinit(&ppe_ports->port[j]);
812 + of_node_put(port_node);
814 + of_node_put(ports_node);
819 + * ppe_port_mac_deinit() - Deinitialization of PPE ports for the PPE device
820 + * @ppe_dev: PPE device
822 + * Description: Deinitialize the PPE MAC ports on the PPE device specified
825 +void ppe_port_mac_deinit(struct ppe_device *ppe_dev)
827 + struct ppe_port *ppe_port;
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);
835 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_port.h b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
837 index 000000000000..194f65815011
839 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
841 +/* SPDX-License-Identifier: GPL-2.0-only
843 + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
846 +#ifndef __PPE_PORT_H__
847 +#define __PPE_PORT_H__
849 +#include <linux/phylink.h>
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
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,
866 + * enum ppe_mac_type - PPE MAC type
867 + * @PPE_MAC_TYPE_GMAC: GMAC type
868 + * @PPE_MAC_TYPE_XGMAC: XGMAC type
872 + PPE_MAC_TYPE_XGMAC,
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
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;
897 + struct clk *clks[PPE_PORT_CLK_RST_MAX];
898 + struct reset_control *rstcs[PPE_PORT_CLK_RST_MAX];
902 + * struct ppe_ports - Array of PPE ports
903 + * @num: Number of PPE ports
904 + * @port: Each PPE port private data
908 + struct ppe_port port[] __counted_by(num);
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);
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
922 #ifndef __PPE_REGS_H__
923 #define __PPE_REGS_H__
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))
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)
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)
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)
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)
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
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)
973 +#define GMAC_CTRL_MASK \
974 + (GMAC_TX_THD_M | GMAC_MAXFRAME_SIZE_M | GMAC_CRS_SEL)
976 +/* GMAC debug control register */
977 +#define GMAC_DBG_CTRL_ADDR 0x1c
978 +#define GMAC_HIGH_IPG_M GENMASK(15, 8)
980 +/* GMAC jumbo size register */
981 +#define GMAC_JUMBO_SIZE_ADDR 0x30
982 +#define GMAC_JUMBO_SIZE_M GENMASK(13, 0)
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)
990 +#define GMAC_MIB_CTRL_MASK \
991 + (GMAC_MIB_RD_CLR | GMAC_MIB_RST | GMAC_MIB_EN)
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)
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)
1016 +#define XGMAC_RX_CONFIG_MASK \
1017 + (XGMAC_GPSL_M | XGMAC_WD | XGMAC_GPSLEN | XGMAC_CST | \
1018 + XGMAC_ACS | XGMAC_RXEN)
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)
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))
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)
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))
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)
1046 +/* XGMAC RX flow control register */
1047 +#define XGMAC_RX_FLOW_CTRL_ADDR 0x90
1048 +#define XGMAC_RXFCEN BIT(0)
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)