xref: /linux/drivers/net/dsa/netc/netc_switch.h (revision 25049d8b6e6b87f7ffcf53ce5ea1b51528b8677f)
1 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2 /*
3  * Copyright 2025-2026 NXP
4  */
5 
6 #ifndef _NETC_SWITCH_H
7 #define _NETC_SWITCH_H
8 
9 #include <linux/dsa/tag_netc.h>
10 #include <linux/fsl/netc_global.h>
11 #include <linux/fsl/ntmp.h>
12 #include <linux/of_device.h>
13 #include <linux/of_net.h>
14 #include <linux/pci.h>
15 
16 #include "netc_switch_hw.h"
17 
18 #define NETC_REGS_BAR			0
19 #define NETC_REGS_SIZE			0x80000
20 #define NETC_MSIX_TBL_BAR		2
21 #define NETC_REGS_PORT_BASE		0x4000
22 /* register block size per port  */
23 #define NETC_REGS_PORT_SIZE		0x4000
24 #define PORT_IOBASE(p)			(NETC_REGS_PORT_SIZE * (p))
25 #define NETC_REGS_GLOBAL_BASE		0x70000
26 
27 #define NETC_SWITCH_REV_4_3		0x0403
28 
29 #define NETC_TC_NUM			8
30 #define NETC_CBDR_NUM			2
31 #define NETC_IPV_NUM			8
32 
33 #define NETC_MAX_FRAME_LEN		9600
34 
35 #define NETC_STANDALONE_PVID		0
36 
37 /* Threshold format: MANT (bits 11:4) * 2^EXP (bits 3:0)
38  * Unit: Memory words (average of 20 bytes each)
39  * NETC_BP_THRESH = 0x8c3, MANT = 0x8c, EXP = 3. Threshold: 1120 words
40  * NETC_FC_THRESH_ON = 0x733, MANT = 0x73, EXP = 3. Threshold: 920 words
41  * NETC_FC_THRESH_OFF = 0x263, MANT = 0x26, EXP = 3. Threshold: 304 words
42  */
43 #define NETC_BP_THRESH			0x8c3
44 #define NETC_FC_THRESH_ON		0x733
45 #define NETC_FC_THRESH_OFF		0x263
46 
47 /* PAUSE quanta: 0xFFFF = 65535 quanta (each quanta = 512 bit times) */
48 #define NETC_PAUSE_QUANTA		0xFFFF
49 /* PAUSE refresh threshold: send refresh when timer reaches this value */
50 #define NETC_PAUSE_THRESH		0x7FFF
51 
52 struct netc_switch;
53 
54 struct netc_switch_info {
55 	u32 num_ports;
56 	void (*phylink_get_caps)(int port, struct phylink_config *config);
57 };
58 
59 struct netc_port_caps {
60 	u32 half_duplex:1; /* indicates whether the port support half-duplex */
61 	u32 pmac:1;	  /* indicates whether the port has preemption MAC */
62 	u32 pseudo_link:1;
63 };
64 
65 enum netc_host_reason {
66 	/* Software defined host reasons */
67 	NETC_HR_HOST_FLOOD = 8,
68 };
69 
70 struct netc_port {
71 	void __iomem *iobase;
72 	struct netc_switch *switch_priv;
73 	struct netc_port_caps caps;
74 	struct dsa_port *dp;
75 	struct clk *ref_clk; /* RGMII/RMII reference clock */
76 	struct mii_bus *emdio;
77 
78 	u16 enable:1;
79 	u16 uc:1;
80 	u16 mc:1;
81 	struct ipft_entry_data *host_flood;
82 };
83 
84 struct netc_switch_regs {
85 	void __iomem *base;
86 	void __iomem *port;
87 	void __iomem *global;
88 };
89 
90 struct netc_fdb_entry {
91 	u32 entry_id;
92 	struct fdbt_cfge_data cfge;
93 	struct fdbt_keye_data keye;
94 	struct hlist_node node;
95 };
96 
97 struct netc_switch {
98 	struct pci_dev *pdev;
99 	struct device *dev;
100 	struct dsa_switch *ds;
101 	u16 revision;
102 
103 	const struct netc_switch_info *info;
104 	struct netc_switch_regs regs;
105 	struct netc_port **ports;
106 
107 	struct ntmp_user ntmp;
108 	struct hlist_head fdb_list;
109 	struct mutex fdbt_lock; /* FDB table lock */
110 
111 	/* Switch hardware capabilities */
112 	u32 htmcapr_num_words;
113 	u32 num_bp;
114 
115 	struct bpt_cfge_data *bpt_list;
116 };
117 
118 #define NETC_PRIV(ds)			((struct netc_switch *)((ds)->priv))
119 #define NETC_PORT(ds, port_id)		(NETC_PRIV(ds)->ports[(port_id)])
120 
121 /* Write/Read Switch base registers */
122 #define netc_base_rd(r, o)		netc_read((r)->base + (o))
123 #define netc_base_wr(r, o, v)		netc_write((r)->base + (o), v)
124 
125 /* Write/Read registers of Switch Port (including pseudo MAC port) */
126 #define netc_port_rd(p, o)		netc_read((p)->iobase + (o))
127 #define netc_port_rd64(p, o)		netc_read64((p)->iobase + (o))
128 #define netc_port_wr(p, o, v)		netc_write((p)->iobase + (o), v)
129 
130 /* Write/Read Switch global registers */
131 #define netc_glb_rd(r, o)		netc_read((r)->global + (o))
132 #define netc_glb_wr(r, o, v)		netc_write((r)->global + (o), v)
133 
134 static inline bool is_netc_pseudo_port(struct netc_port *np)
135 {
136 	return np->caps.pseudo_link;
137 }
138 
139 static inline void netc_add_fdb_entry(struct netc_switch *priv,
140 				      struct netc_fdb_entry *entry)
141 {
142 	hlist_add_head(&entry->node, &priv->fdb_list);
143 }
144 
145 static inline void netc_del_fdb_entry(struct netc_fdb_entry *entry)
146 {
147 	hlist_del(&entry->node);
148 	kfree(entry);
149 }
150 
151 int netc_switch_platform_probe(struct netc_switch *priv);
152 
153 /* ethtool APIs */
154 void netc_port_get_pause_stats(struct dsa_switch *ds, int port,
155 			       struct ethtool_pause_stats *pause_stats);
156 void netc_port_get_rmon_stats(struct dsa_switch *ds, int port,
157 			      struct ethtool_rmon_stats *rmon_stats,
158 			      const struct ethtool_rmon_hist_range **ranges);
159 void netc_port_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
160 				  struct ethtool_eth_ctrl_stats *ctrl_stats);
161 void netc_port_get_eth_mac_stats(struct dsa_switch *ds, int port,
162 				 struct ethtool_eth_mac_stats *mac_stats);
163 
164 #endif
165