xref: /linux/drivers/net/dsa/netc/netc_switch.h (revision 05b5ee610fbb8ca4ce9dc21299442aa827b38008)
1187fbae0SWei Fang /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2187fbae0SWei Fang /*
3187fbae0SWei Fang  * Copyright 2025-2026 NXP
4187fbae0SWei Fang  */
5187fbae0SWei Fang 
6187fbae0SWei Fang #ifndef _NETC_SWITCH_H
7187fbae0SWei Fang #define _NETC_SWITCH_H
8187fbae0SWei Fang 
9187fbae0SWei Fang #include <linux/dsa/tag_netc.h>
10187fbae0SWei Fang #include <linux/fsl/netc_global.h>
11187fbae0SWei Fang #include <linux/fsl/ntmp.h>
12187fbae0SWei Fang #include <linux/of_device.h>
13187fbae0SWei Fang #include <linux/of_net.h>
14187fbae0SWei Fang #include <linux/pci.h>
15187fbae0SWei Fang 
16187fbae0SWei Fang #include "netc_switch_hw.h"
17187fbae0SWei Fang 
18187fbae0SWei Fang #define NETC_REGS_BAR			0
19187fbae0SWei Fang #define NETC_REGS_SIZE			0x80000
20187fbae0SWei Fang #define NETC_MSIX_TBL_BAR		2
21187fbae0SWei Fang #define NETC_REGS_PORT_BASE		0x4000
22187fbae0SWei Fang /* register block size per port  */
23187fbae0SWei Fang #define NETC_REGS_PORT_SIZE		0x4000
24187fbae0SWei Fang #define PORT_IOBASE(p)			(NETC_REGS_PORT_SIZE * (p))
25187fbae0SWei Fang #define NETC_REGS_GLOBAL_BASE		0x70000
26187fbae0SWei Fang 
27187fbae0SWei Fang #define NETC_SWITCH_REV_4_3		0x0403
28187fbae0SWei Fang 
29187fbae0SWei Fang #define NETC_TC_NUM			8
30187fbae0SWei Fang #define NETC_CBDR_NUM			2
31a5ccb7f5SWei Fang #define NETC_IPV_NUM			8
32187fbae0SWei Fang 
33187fbae0SWei Fang #define NETC_MAX_FRAME_LEN		9600
34187fbae0SWei Fang 
3546d64076SWei Fang #define NETC_STANDALONE_PVID		0
36751aa5a5SWei Fang #define NETC_VLAN_UNAWARE_PVID(br_id)	(4096 - (br_id))
3746d64076SWei Fang 
38a5ccb7f5SWei Fang /* Threshold format: MANT (bits 11:4) * 2^EXP (bits 3:0)
39a5ccb7f5SWei Fang  * Unit: Memory words (average of 20 bytes each)
40a5ccb7f5SWei Fang  * NETC_BP_THRESH = 0x8c3, MANT = 0x8c, EXP = 3. Threshold: 1120 words
41a5ccb7f5SWei Fang  * NETC_FC_THRESH_ON = 0x733, MANT = 0x73, EXP = 3. Threshold: 920 words
42a5ccb7f5SWei Fang  * NETC_FC_THRESH_OFF = 0x263, MANT = 0x26, EXP = 3. Threshold: 304 words
43a5ccb7f5SWei Fang  */
44a5ccb7f5SWei Fang #define NETC_BP_THRESH			0x8c3
45a5ccb7f5SWei Fang #define NETC_FC_THRESH_ON		0x733
46a5ccb7f5SWei Fang #define NETC_FC_THRESH_OFF		0x263
47a5ccb7f5SWei Fang 
48a5ccb7f5SWei Fang /* PAUSE quanta: 0xFFFF = 65535 quanta (each quanta = 512 bit times) */
49a5ccb7f5SWei Fang #define NETC_PAUSE_QUANTA		0xFFFF
50a5ccb7f5SWei Fang /* PAUSE refresh threshold: send refresh when timer reaches this value */
51a5ccb7f5SWei Fang #define NETC_PAUSE_THRESH		0x7FFF
52a5ccb7f5SWei Fang 
53*05b5ee61SWei Fang #define NETC_FDBT_AGEING_DELAY		(3 * HZ)
54*05b5ee61SWei Fang #define NETC_FDBT_AGEING_THRESH		100
55*05b5ee61SWei Fang 
56187fbae0SWei Fang struct netc_switch;
57187fbae0SWei Fang 
58187fbae0SWei Fang struct netc_switch_info {
59187fbae0SWei Fang 	u32 num_ports;
60bbe97e34SWei Fang 	void (*phylink_get_caps)(int port, struct phylink_config *config);
61187fbae0SWei Fang };
62187fbae0SWei Fang 
63187fbae0SWei Fang struct netc_port_caps {
64187fbae0SWei Fang 	u32 half_duplex:1; /* indicates whether the port support half-duplex */
65187fbae0SWei Fang 	u32 pmac:1;	  /* indicates whether the port has preemption MAC */
66187fbae0SWei Fang 	u32 pseudo_link:1;
67187fbae0SWei Fang };
68187fbae0SWei Fang 
6946d64076SWei Fang enum netc_host_reason {
7046d64076SWei Fang 	/* Software defined host reasons */
7146d64076SWei Fang 	NETC_HR_HOST_FLOOD = 8,
7246d64076SWei Fang };
7346d64076SWei Fang 
74187fbae0SWei Fang struct netc_port {
75187fbae0SWei Fang 	void __iomem *iobase;
76187fbae0SWei Fang 	struct netc_switch *switch_priv;
77187fbae0SWei Fang 	struct netc_port_caps caps;
78187fbae0SWei Fang 	struct dsa_port *dp;
7946d64076SWei Fang 	struct clk *ref_clk; /* RGMII/RMII reference clock */
80187fbae0SWei Fang 	struct mii_bus *emdio;
8184b4a3b3SWei Fang 	int ett_offset;
8246d64076SWei Fang 
8346d64076SWei Fang 	u16 enable:1;
8446d64076SWei Fang 	u16 uc:1;
8546d64076SWei Fang 	u16 mc:1;
86751aa5a5SWei Fang 	u16 pvid;
8746d64076SWei Fang 	struct ipft_entry_data *host_flood;
88187fbae0SWei Fang };
89187fbae0SWei Fang 
90187fbae0SWei Fang struct netc_switch_regs {
91187fbae0SWei Fang 	void __iomem *base;
92187fbae0SWei Fang 	void __iomem *port;
93187fbae0SWei Fang 	void __iomem *global;
94187fbae0SWei Fang };
95187fbae0SWei Fang 
9646d64076SWei Fang struct netc_fdb_entry {
9746d64076SWei Fang 	u32 entry_id;
9846d64076SWei Fang 	struct fdbt_cfge_data cfge;
9946d64076SWei Fang 	struct fdbt_keye_data keye;
10046d64076SWei Fang 	struct hlist_node node;
10146d64076SWei Fang };
10246d64076SWei Fang 
10384b4a3b3SWei Fang struct netc_vlan_entry {
10484b4a3b3SWei Fang 	u16 vid;
10584b4a3b3SWei Fang 	u32 ect_gid;
10684b4a3b3SWei Fang 	u32 untagged_port_bitmap;
10784b4a3b3SWei Fang 	struct vft_cfge_data cfge;
10884b4a3b3SWei Fang 	struct hlist_node node;
10984b4a3b3SWei Fang };
11084b4a3b3SWei Fang 
111beb0e54fSWei Fang struct netc_port_stat {
112beb0e54fSWei Fang 	int reg;
113beb0e54fSWei Fang 	char name[ETH_GSTRING_LEN] __nonstring;
114beb0e54fSWei Fang };
115beb0e54fSWei Fang 
116187fbae0SWei Fang struct netc_switch {
117187fbae0SWei Fang 	struct pci_dev *pdev;
118187fbae0SWei Fang 	struct device *dev;
119187fbae0SWei Fang 	struct dsa_switch *ds;
120187fbae0SWei Fang 	u16 revision;
121187fbae0SWei Fang 
122187fbae0SWei Fang 	const struct netc_switch_info *info;
123187fbae0SWei Fang 	struct netc_switch_regs regs;
124187fbae0SWei Fang 	struct netc_port **ports;
12584b4a3b3SWei Fang 	u32 port_bitmap; /* bitmap of available ports */
126187fbae0SWei Fang 
127187fbae0SWei Fang 	struct ntmp_user ntmp;
12846d64076SWei Fang 	struct hlist_head fdb_list;
12946d64076SWei Fang 	struct mutex fdbt_lock; /* FDB table lock */
130*05b5ee61SWei Fang 	struct delayed_work fdbt_ageing_work;
131*05b5ee61SWei Fang 	/* (fdbt_ageing_delay * NETC_FDBT_AGEING_THRESH) is ageing time */
132*05b5ee61SWei Fang 	unsigned long fdbt_ageing_delay;
133*05b5ee61SWei Fang 	atomic_t br_cnt;
13484b4a3b3SWei Fang 	struct hlist_head vlan_list;
13584b4a3b3SWei Fang 	struct mutex vft_lock; /* VLAN filter table lock */
13646d64076SWei Fang 
13746d64076SWei Fang 	/* Switch hardware capabilities */
13846d64076SWei Fang 	u32 htmcapr_num_words;
139a5ccb7f5SWei Fang 	u32 num_bp;
140a5ccb7f5SWei Fang 
141a5ccb7f5SWei Fang 	struct bpt_cfge_data *bpt_list;
142187fbae0SWei Fang };
143187fbae0SWei Fang 
144bbe97e34SWei Fang #define NETC_PRIV(ds)			((struct netc_switch *)((ds)->priv))
145bbe97e34SWei Fang #define NETC_PORT(ds, port_id)		(NETC_PRIV(ds)->ports[(port_id)])
146bbe97e34SWei Fang 
147187fbae0SWei Fang /* Write/Read Switch base registers */
148187fbae0SWei Fang #define netc_base_rd(r, o)		netc_read((r)->base + (o))
149187fbae0SWei Fang #define netc_base_wr(r, o, v)		netc_write((r)->base + (o), v)
150187fbae0SWei Fang 
151187fbae0SWei Fang /* Write/Read registers of Switch Port (including pseudo MAC port) */
152187fbae0SWei Fang #define netc_port_rd(p, o)		netc_read((p)->iobase + (o))
15325049d8bSWei Fang #define netc_port_rd64(p, o)		netc_read64((p)->iobase + (o))
154187fbae0SWei Fang #define netc_port_wr(p, o, v)		netc_write((p)->iobase + (o), v)
155187fbae0SWei Fang 
156187fbae0SWei Fang /* Write/Read Switch global registers */
157187fbae0SWei Fang #define netc_glb_rd(r, o)		netc_read((r)->global + (o))
158187fbae0SWei Fang #define netc_glb_wr(r, o, v)		netc_write((r)->global + (o), v)
159187fbae0SWei Fang 
160187fbae0SWei Fang static inline bool is_netc_pseudo_port(struct netc_port *np)
161187fbae0SWei Fang {
162187fbae0SWei Fang 	return np->caps.pseudo_link;
163187fbae0SWei Fang }
164187fbae0SWei Fang 
16546d64076SWei Fang static inline void netc_add_fdb_entry(struct netc_switch *priv,
16646d64076SWei Fang 				      struct netc_fdb_entry *entry)
16746d64076SWei Fang {
16846d64076SWei Fang 	hlist_add_head(&entry->node, &priv->fdb_list);
16946d64076SWei Fang }
17046d64076SWei Fang 
17146d64076SWei Fang static inline void netc_del_fdb_entry(struct netc_fdb_entry *entry)
17246d64076SWei Fang {
17346d64076SWei Fang 	hlist_del(&entry->node);
17446d64076SWei Fang 	kfree(entry);
17546d64076SWei Fang }
17646d64076SWei Fang 
17784b4a3b3SWei Fang static inline void netc_add_vlan_entry(struct netc_switch *priv,
17884b4a3b3SWei Fang 				       struct netc_vlan_entry *entry)
17984b4a3b3SWei Fang {
18084b4a3b3SWei Fang 	hlist_add_head(&entry->node, &priv->vlan_list);
18184b4a3b3SWei Fang }
18284b4a3b3SWei Fang 
18384b4a3b3SWei Fang static inline void netc_del_vlan_entry(struct netc_vlan_entry *entry)
18484b4a3b3SWei Fang {
18584b4a3b3SWei Fang 	hlist_del(&entry->node);
18684b4a3b3SWei Fang 	kfree(entry);
18784b4a3b3SWei Fang }
18884b4a3b3SWei Fang 
189187fbae0SWei Fang int netc_switch_platform_probe(struct netc_switch *priv);
190187fbae0SWei Fang 
19125049d8bSWei Fang /* ethtool APIs */
19225049d8bSWei Fang void netc_port_get_pause_stats(struct dsa_switch *ds, int port,
19325049d8bSWei Fang 			       struct ethtool_pause_stats *pause_stats);
19425049d8bSWei Fang void netc_port_get_rmon_stats(struct dsa_switch *ds, int port,
19525049d8bSWei Fang 			      struct ethtool_rmon_stats *rmon_stats,
19625049d8bSWei Fang 			      const struct ethtool_rmon_hist_range **ranges);
19725049d8bSWei Fang void netc_port_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
19825049d8bSWei Fang 				  struct ethtool_eth_ctrl_stats *ctrl_stats);
19925049d8bSWei Fang void netc_port_get_eth_mac_stats(struct dsa_switch *ds, int port,
20025049d8bSWei Fang 				 struct ethtool_eth_mac_stats *mac_stats);
201beb0e54fSWei Fang int netc_port_get_sset_count(struct dsa_switch *ds, int port, int sset);
202beb0e54fSWei Fang void netc_port_get_strings(struct dsa_switch *ds, int port,
203beb0e54fSWei Fang 			   u32 sset, u8 *data);
204beb0e54fSWei Fang void netc_port_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data);
20525049d8bSWei Fang 
206187fbae0SWei Fang #endif
207