13cfa11baSSteen Hegelund /* SPDX-License-Identifier: GPL-2.0+ */
23cfa11baSSteen Hegelund /* Microchip Sparx5 Switch driver
33cfa11baSSteen Hegelund  *
43cfa11baSSteen Hegelund  * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
53cfa11baSSteen Hegelund  */
63cfa11baSSteen Hegelund 
73cfa11baSSteen Hegelund #ifndef __SPARX5_MAIN_H__
83cfa11baSSteen Hegelund #define __SPARX5_MAIN_H__
93cfa11baSSteen Hegelund 
103cfa11baSSteen Hegelund #include <linux/types.h>
113cfa11baSSteen Hegelund #include <linux/phy/phy.h>
123cfa11baSSteen Hegelund #include <linux/netdevice.h>
133cfa11baSSteen Hegelund #include <linux/phy.h>
143cfa11baSSteen Hegelund #include <linux/if_vlan.h>
153cfa11baSSteen Hegelund #include <linux/bitmap.h>
163cfa11baSSteen Hegelund #include <linux/phylink.h>
170933bd04SHoratiu Vultur #include <linux/net_tstamp.h>
180933bd04SHoratiu Vultur #include <linux/ptp_clock_kernel.h>
19f3cad261SSteen Hegelund #include <linux/hrtimer.h>
203cfa11baSSteen Hegelund 
2190d40252SCasper Andersson #include "sparx5_main_regs.h"
2290d40252SCasper Andersson 
233cfa11baSSteen Hegelund /* Target chip type */
243cfa11baSSteen Hegelund enum spx5_target_chiptype {
253cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7546    = 0x7546,  /* SparX-5-64  Enterprise */
263cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7549    = 0x7549,  /* SparX-5-90  Enterprise */
273cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7552    = 0x7552,  /* SparX-5-128 Enterprise */
283cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7556    = 0x7556,  /* SparX-5-160 Enterprise */
293cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7558    = 0x7558,  /* SparX-5-200 Enterprise */
303cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7546TSN = 0x47546, /* SparX-5-64i Industrial */
313cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7549TSN = 0x47549, /* SparX-5-90i Industrial */
323cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7552TSN = 0x47552, /* SparX-5-128i Industrial */
333cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7556TSN = 0x47556, /* SparX-5-160i Industrial */
343cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7558TSN = 0x47558, /* SparX-5-200i Industrial */
353cfa11baSSteen Hegelund };
363cfa11baSSteen Hegelund 
373cfa11baSSteen Hegelund enum sparx5_port_max_tags {
383cfa11baSSteen Hegelund 	SPX5_PORT_MAX_TAGS_NONE,  /* No extra tags allowed */
393cfa11baSSteen Hegelund 	SPX5_PORT_MAX_TAGS_ONE,   /* Single tag allowed */
403cfa11baSSteen Hegelund 	SPX5_PORT_MAX_TAGS_TWO    /* Single and double tag allowed */
413cfa11baSSteen Hegelund };
423cfa11baSSteen Hegelund 
433cfa11baSSteen Hegelund enum sparx5_vlan_port_type {
443cfa11baSSteen Hegelund 	SPX5_VLAN_PORT_TYPE_UNAWARE, /* VLAN unaware port */
453cfa11baSSteen Hegelund 	SPX5_VLAN_PORT_TYPE_C,       /* C-port */
463cfa11baSSteen Hegelund 	SPX5_VLAN_PORT_TYPE_S,       /* S-port */
473cfa11baSSteen Hegelund 	SPX5_VLAN_PORT_TYPE_S_CUSTOM /* S-port using custom type */
483cfa11baSSteen Hegelund };
493cfa11baSSteen Hegelund 
503cfa11baSSteen Hegelund #define SPX5_PORTS             65
513cfa11baSSteen Hegelund #define SPX5_PORT_CPU          (SPX5_PORTS)  /* Next port is CPU port */
523cfa11baSSteen Hegelund #define SPX5_PORT_CPU_0        (SPX5_PORT_CPU + 0) /* CPU Port 65 */
533cfa11baSSteen Hegelund #define SPX5_PORT_CPU_1        (SPX5_PORT_CPU + 1) /* CPU Port 66 */
543cfa11baSSteen Hegelund #define SPX5_PORT_VD0          (SPX5_PORT_CPU + 2) /* VD0/Port 67 used for IPMC */
553cfa11baSSteen Hegelund #define SPX5_PORT_VD1          (SPX5_PORT_CPU + 3) /* VD1/Port 68 used for AFI/OAM */
563cfa11baSSteen Hegelund #define SPX5_PORT_VD2          (SPX5_PORT_CPU + 4) /* VD2/Port 69 used for IPinIP*/
573cfa11baSSteen Hegelund #define SPX5_PORTS_ALL         (SPX5_PORT_CPU + 5) /* Total number of ports */
583cfa11baSSteen Hegelund 
593cfa11baSSteen Hegelund #define PGID_BASE              SPX5_PORTS /* Starts after port PGIDs */
603cfa11baSSteen Hegelund #define PGID_UC_FLOOD          (PGID_BASE + 0)
613cfa11baSSteen Hegelund #define PGID_MC_FLOOD          (PGID_BASE + 1)
623cfa11baSSteen Hegelund #define PGID_IPV4_MC_DATA      (PGID_BASE + 2)
633cfa11baSSteen Hegelund #define PGID_IPV4_MC_CTRL      (PGID_BASE + 3)
643cfa11baSSteen Hegelund #define PGID_IPV6_MC_DATA      (PGID_BASE + 4)
653cfa11baSSteen Hegelund #define PGID_IPV6_MC_CTRL      (PGID_BASE + 5)
663cfa11baSSteen Hegelund #define PGID_BCAST	       (PGID_BASE + 6)
673cfa11baSSteen Hegelund #define PGID_CPU	       (PGID_BASE + 7)
68*ad238fc6SCasper Andersson #define PGID_MCAST_START       (PGID_BASE + 8)
693cfa11baSSteen Hegelund 
70af9b45d0SCasper Andersson #define PGID_TABLE_SIZE	       3290
71af9b45d0SCasper Andersson 
723cfa11baSSteen Hegelund #define IFH_LEN                9 /* 36 bytes */
733cfa11baSSteen Hegelund #define NULL_VID               0
743cfa11baSSteen Hegelund #define SPX5_MACT_PULL_DELAY   (2 * HZ)
753cfa11baSSteen Hegelund #define SPX5_STATS_CHECK_DELAY (1 * HZ)
763cfa11baSSteen Hegelund #define SPX5_PRIOS             8     /* Number of priority queues */
773cfa11baSSteen Hegelund #define SPX5_BUFFER_CELL_SZ    184   /* Cell size  */
783cfa11baSSteen Hegelund #define SPX5_BUFFER_MEMORY     4194280 /* 22795 words * 184 bytes */
793cfa11baSSteen Hegelund 
80f3cad261SSteen Hegelund #define XTR_QUEUE     0
81f3cad261SSteen Hegelund #define INJ_QUEUE     0
82f3cad261SSteen Hegelund 
8310615907SSteen Hegelund #define FDMA_DCB_MAX			64
8410615907SSteen Hegelund #define FDMA_RX_DCB_MAX_DBS		15
8510615907SSteen Hegelund #define FDMA_TX_DCB_MAX_DBS		1
8610615907SSteen Hegelund 
870933bd04SHoratiu Vultur #define SPARX5_PHC_COUNT		3
880933bd04SHoratiu Vultur #define SPARX5_PHC_PORT			0
890933bd04SHoratiu Vultur 
90589a07b8SHoratiu Vultur #define IFH_REW_OP_NOOP			0x0
91589a07b8SHoratiu Vultur #define IFH_REW_OP_ONE_STEP_PTP		0x3
92589a07b8SHoratiu Vultur #define IFH_REW_OP_TWO_STEP_PTP		0x4
93589a07b8SHoratiu Vultur 
9470dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_NONE		0x0
9570dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_PTP		0x5
9670dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_IPV4_UDP_PTP	0x6
9770dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_IPV6_UDP_PTP	0x7
9870dfe25cSHoratiu Vultur 
993cfa11baSSteen Hegelund struct sparx5;
1003cfa11baSSteen Hegelund 
10110615907SSteen Hegelund struct sparx5_db_hw {
10210615907SSteen Hegelund 	u64 dataptr;
10310615907SSteen Hegelund 	u64 status;
10410615907SSteen Hegelund };
10510615907SSteen Hegelund 
10610615907SSteen Hegelund struct sparx5_rx_dcb_hw {
10710615907SSteen Hegelund 	u64 nextptr;
10810615907SSteen Hegelund 	u64 info;
10910615907SSteen Hegelund 	struct sparx5_db_hw db[FDMA_RX_DCB_MAX_DBS];
11010615907SSteen Hegelund };
11110615907SSteen Hegelund 
11210615907SSteen Hegelund struct sparx5_tx_dcb_hw {
11310615907SSteen Hegelund 	u64 nextptr;
11410615907SSteen Hegelund 	u64 info;
11510615907SSteen Hegelund 	struct sparx5_db_hw db[FDMA_TX_DCB_MAX_DBS];
11610615907SSteen Hegelund };
11710615907SSteen Hegelund 
11810615907SSteen Hegelund /* Frame DMA receive state:
11910615907SSteen Hegelund  * For each DB, there is a SKB, and the skb data pointer is mapped in
12010615907SSteen Hegelund  * the DB. Once a frame is received the skb is given to the upper layers
12110615907SSteen Hegelund  * and a new skb is added to the dcb.
12210615907SSteen Hegelund  * When the db_index reached FDMA_RX_DCB_MAX_DBS the DB is reused.
12310615907SSteen Hegelund  */
12410615907SSteen Hegelund struct sparx5_rx {
12510615907SSteen Hegelund 	struct sparx5_rx_dcb_hw *dcb_entries;
12610615907SSteen Hegelund 	struct sparx5_rx_dcb_hw *last_entry;
12710615907SSteen Hegelund 	struct sk_buff *skb[FDMA_DCB_MAX][FDMA_RX_DCB_MAX_DBS];
12810615907SSteen Hegelund 	int db_index;
12910615907SSteen Hegelund 	int dcb_index;
13010615907SSteen Hegelund 	dma_addr_t dma;
13110615907SSteen Hegelund 	struct napi_struct napi;
13210615907SSteen Hegelund 	u32 channel_id;
13310615907SSteen Hegelund 	struct net_device *ndev;
13410615907SSteen Hegelund 	u64 packets;
13510615907SSteen Hegelund };
13610615907SSteen Hegelund 
13710615907SSteen Hegelund /* Frame DMA transmit state:
13810615907SSteen Hegelund  * DCBs are chained using the DCBs nextptr field.
13910615907SSteen Hegelund  */
14010615907SSteen Hegelund struct sparx5_tx {
14110615907SSteen Hegelund 	struct sparx5_tx_dcb_hw *curr_entry;
14210615907SSteen Hegelund 	struct sparx5_tx_dcb_hw *first_entry;
14310615907SSteen Hegelund 	struct list_head db_list;
14410615907SSteen Hegelund 	dma_addr_t dma;
14510615907SSteen Hegelund 	u32 channel_id;
14610615907SSteen Hegelund 	u64 packets;
14710615907SSteen Hegelund 	u64 dropped;
14810615907SSteen Hegelund };
14910615907SSteen Hegelund 
1503cfa11baSSteen Hegelund struct sparx5_port_config {
1513cfa11baSSteen Hegelund 	phy_interface_t portmode;
1523cfa11baSSteen Hegelund 	u32 bandwidth;
1533cfa11baSSteen Hegelund 	int speed;
1543cfa11baSSteen Hegelund 	int duplex;
1553cfa11baSSteen Hegelund 	enum phy_media media;
1563cfa11baSSteen Hegelund 	bool inband;
1573cfa11baSSteen Hegelund 	bool power_down;
1583cfa11baSSteen Hegelund 	bool autoneg;
1593cfa11baSSteen Hegelund 	bool serdes_reset;
1603cfa11baSSteen Hegelund 	u32 pause;
1613cfa11baSSteen Hegelund 	u32 pause_adv;
1623cfa11baSSteen Hegelund 	phy_interface_t phy_mode;
1633cfa11baSSteen Hegelund 	u32 sd_sgpio;
1643cfa11baSSteen Hegelund };
1653cfa11baSSteen Hegelund 
1663cfa11baSSteen Hegelund struct sparx5_port {
1673cfa11baSSteen Hegelund 	struct net_device *ndev;
1683cfa11baSSteen Hegelund 	struct sparx5 *sparx5;
1693cfa11baSSteen Hegelund 	struct device_node *of_node;
1703cfa11baSSteen Hegelund 	struct phy *serdes;
1713cfa11baSSteen Hegelund 	struct sparx5_port_config conf;
172f3cad261SSteen Hegelund 	struct phylink_config phylink_config;
173f3cad261SSteen Hegelund 	struct phylink *phylink;
174f3cad261SSteen Hegelund 	struct phylink_pcs phylink_pcs;
1753cfa11baSSteen Hegelund 	u16 portno;
1763cfa11baSSteen Hegelund 	/* Ingress default VLAN (pvid) */
1773cfa11baSSteen Hegelund 	u16 pvid;
1783cfa11baSSteen Hegelund 	/* Egress default VLAN (vid) */
1793cfa11baSSteen Hegelund 	u16 vid;
1803cfa11baSSteen Hegelund 	bool signd_internal;
1813cfa11baSSteen Hegelund 	bool signd_active_high;
1823cfa11baSSteen Hegelund 	bool signd_enable;
1833cfa11baSSteen Hegelund 	bool flow_control;
1843cfa11baSSteen Hegelund 	enum sparx5_port_max_tags max_vlan_tags;
1853cfa11baSSteen Hegelund 	enum sparx5_vlan_port_type vlan_type;
1863cfa11baSSteen Hegelund 	u32 custom_etype;
1873cfa11baSSteen Hegelund 	bool vlan_aware;
188f3cad261SSteen Hegelund 	struct hrtimer inj_timer;
189589a07b8SHoratiu Vultur 	/* ptp */
190589a07b8SHoratiu Vultur 	u8 ptp_cmd;
19170dfe25cSHoratiu Vultur 	u16 ts_id;
19270dfe25cSHoratiu Vultur 	struct sk_buff_head tx_skbs;
1933cfa11baSSteen Hegelund };
1943cfa11baSSteen Hegelund 
1953cfa11baSSteen Hegelund enum sparx5_core_clockfreq {
1963cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_DEFAULT,  /* Defaults to the highest supported frequency */
1973cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_250MHZ,   /* 250MHZ core clock frequency */
1983cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_500MHZ,   /* 500MHZ core clock frequency */
1993cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_625MHZ,   /* 625MHZ core clock frequency */
2003cfa11baSSteen Hegelund };
2013cfa11baSSteen Hegelund 
2020933bd04SHoratiu Vultur struct sparx5_phc {
2030933bd04SHoratiu Vultur 	struct ptp_clock *clock;
2040933bd04SHoratiu Vultur 	struct ptp_clock_info info;
2050933bd04SHoratiu Vultur 	struct hwtstamp_config hwtstamp_config;
2060933bd04SHoratiu Vultur 	struct sparx5 *sparx5;
2070933bd04SHoratiu Vultur 	u8 index;
2080933bd04SHoratiu Vultur };
2090933bd04SHoratiu Vultur 
21070dfe25cSHoratiu Vultur struct sparx5_skb_cb {
21170dfe25cSHoratiu Vultur 	u8 rew_op;
21270dfe25cSHoratiu Vultur 	u8 pdu_type;
21370dfe25cSHoratiu Vultur 	u8 pdu_w16_offset;
21470dfe25cSHoratiu Vultur 	u16 ts_id;
21570dfe25cSHoratiu Vultur 	unsigned long jiffies;
21670dfe25cSHoratiu Vultur };
21770dfe25cSHoratiu Vultur 
21870dfe25cSHoratiu Vultur #define SPARX5_PTP_TIMEOUT		msecs_to_jiffies(10)
21970dfe25cSHoratiu Vultur #define SPARX5_SKB_CB(skb) \
22070dfe25cSHoratiu Vultur 	((struct sparx5_skb_cb *)((skb)->cb))
22170dfe25cSHoratiu Vultur 
2223cfa11baSSteen Hegelund struct sparx5 {
2233cfa11baSSteen Hegelund 	struct platform_device *pdev;
2243cfa11baSSteen Hegelund 	struct device *dev;
2253cfa11baSSteen Hegelund 	u32 chip_id;
2263cfa11baSSteen Hegelund 	enum spx5_target_chiptype target_ct;
2273cfa11baSSteen Hegelund 	void __iomem *regs[NUM_TARGETS];
2283cfa11baSSteen Hegelund 	int port_count;
2293cfa11baSSteen Hegelund 	struct mutex lock; /* MAC reg lock */
2303cfa11baSSteen Hegelund 	/* port structures are in net device */
2313cfa11baSSteen Hegelund 	struct sparx5_port *ports[SPX5_PORTS];
2323cfa11baSSteen Hegelund 	enum sparx5_core_clockfreq coreclock;
233af4b1102SSteen Hegelund 	/* Statistics */
234af4b1102SSteen Hegelund 	u32 num_stats;
235af4b1102SSteen Hegelund 	u32 num_ethtool_stats;
236af4b1102SSteen Hegelund 	const char * const *stats_layout;
237af4b1102SSteen Hegelund 	u64 *stats;
238af4b1102SSteen Hegelund 	/* Workqueue for reading stats */
239af4b1102SSteen Hegelund 	struct mutex queue_stats_lock;
240af4b1102SSteen Hegelund 	struct delayed_work stats_work;
241af4b1102SSteen Hegelund 	struct workqueue_struct *stats_queue;
242d6fce514SSteen Hegelund 	/* Notifiers */
243d6fce514SSteen Hegelund 	struct notifier_block netdevice_nb;
244d6fce514SSteen Hegelund 	struct notifier_block switchdev_nb;
245d6fce514SSteen Hegelund 	struct notifier_block switchdev_blocking_nb;
246b37a1baeSSteen Hegelund 	/* Switch state */
2473cfa11baSSteen Hegelund 	u8 base_mac[ETH_ALEN];
248d6fce514SSteen Hegelund 	/* Associated bridge device (when bridged) */
249d6fce514SSteen Hegelund 	struct net_device *hw_bridge_dev;
25078eab33bSSteen Hegelund 	/* Bridged interfaces */
251d6fce514SSteen Hegelund 	DECLARE_BITMAP(bridge_mask, SPX5_PORTS);
25278eab33bSSteen Hegelund 	DECLARE_BITMAP(bridge_fwd_mask, SPX5_PORTS);
25378eab33bSSteen Hegelund 	DECLARE_BITMAP(bridge_lrn_mask, SPX5_PORTS);
25478eab33bSSteen Hegelund 	DECLARE_BITMAP(vlan_mask[VLAN_N_VID], SPX5_PORTS);
255b37a1baeSSteen Hegelund 	/* SW MAC table */
256b37a1baeSSteen Hegelund 	struct list_head mact_entries;
257b37a1baeSSteen Hegelund 	/* mac table list (mact_entries) mutex */
258b37a1baeSSteen Hegelund 	struct mutex mact_lock;
259b37a1baeSSteen Hegelund 	struct delayed_work mact_work;
260b37a1baeSSteen Hegelund 	struct workqueue_struct *mact_queue;
2613cfa11baSSteen Hegelund 	/* Board specifics */
2623cfa11baSSteen Hegelund 	bool sd_sgpio_remapping;
263f3cad261SSteen Hegelund 	/* Register based inj/xtr */
264f3cad261SSteen Hegelund 	int xtr_irq;
26510615907SSteen Hegelund 	/* Frame DMA */
26610615907SSteen Hegelund 	int fdma_irq;
26710615907SSteen Hegelund 	struct sparx5_rx rx;
26810615907SSteen Hegelund 	struct sparx5_tx tx;
2690933bd04SHoratiu Vultur 	/* PTP */
2700933bd04SHoratiu Vultur 	bool ptp;
2710933bd04SHoratiu Vultur 	struct sparx5_phc phc[SPARX5_PHC_COUNT];
2720933bd04SHoratiu Vultur 	spinlock_t ptp_clock_lock; /* lock for phc */
27370dfe25cSHoratiu Vultur 	spinlock_t ptp_ts_id_lock; /* lock for ts_id */
274589a07b8SHoratiu Vultur 	struct mutex ptp_lock; /* lock for ptp interface state */
27570dfe25cSHoratiu Vultur 	u16 ptp_skbs;
276d31d3791SHoratiu Vultur 	int ptp_irq;
277af9b45d0SCasper Andersson 	/* PGID allocation map */
278af9b45d0SCasper Andersson 	u8 pgid_map[PGID_TABLE_SIZE];
2793cfa11baSSteen Hegelund };
2803cfa11baSSteen Hegelund 
281d6fce514SSteen Hegelund /* sparx5_switchdev.c */
282d6fce514SSteen Hegelund int sparx5_register_notifier_blocks(struct sparx5 *sparx5);
283d6fce514SSteen Hegelund void sparx5_unregister_notifier_blocks(struct sparx5 *sparx5);
284d6fce514SSteen Hegelund 
285f3cad261SSteen Hegelund /* sparx5_packet.c */
28610615907SSteen Hegelund struct frame_info {
28710615907SSteen Hegelund 	int src_port;
28870dfe25cSHoratiu Vultur 	u32 timestamp;
28910615907SSteen Hegelund };
29010615907SSteen Hegelund 
29110615907SSteen Hegelund void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp);
29210615907SSteen Hegelund void sparx5_ifh_parse(u32 *ifh, struct frame_info *info);
293f3cad261SSteen Hegelund irqreturn_t sparx5_xtr_handler(int irq, void *_priv);
294f3cad261SSteen Hegelund int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev);
295f3cad261SSteen Hegelund int sparx5_manual_injection_mode(struct sparx5 *sparx5);
296f3cad261SSteen Hegelund void sparx5_port_inj_timer_setup(struct sparx5_port *port);
297f3cad261SSteen Hegelund 
29810615907SSteen Hegelund /* sparx5_fdma.c */
29910615907SSteen Hegelund int sparx5_fdma_start(struct sparx5 *sparx5);
30010615907SSteen Hegelund int sparx5_fdma_stop(struct sparx5 *sparx5);
30110615907SSteen Hegelund int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb);
30210615907SSteen Hegelund irqreturn_t sparx5_fdma_handler(int irq, void *args);
30310615907SSteen Hegelund 
304b37a1baeSSteen Hegelund /* sparx5_mactable.c */
305b37a1baeSSteen Hegelund void sparx5_mact_pull_work(struct work_struct *work);
306b37a1baeSSteen Hegelund int sparx5_mact_learn(struct sparx5 *sparx5, int port,
307b37a1baeSSteen Hegelund 		      const unsigned char mac[ETH_ALEN], u16 vid);
308b37a1baeSSteen Hegelund bool sparx5_mact_getnext(struct sparx5 *sparx5,
309b37a1baeSSteen Hegelund 			 unsigned char mac[ETH_ALEN], u16 *vid, u32 *pcfg2);
3103bacfccdSCasper Andersson bool sparx5_mact_find(struct sparx5 *sparx5,
3113bacfccdSCasper Andersson 		      const unsigned char mac[ETH_ALEN], u16 vid, u32 *pcfg2);
312b37a1baeSSteen Hegelund int sparx5_mact_forget(struct sparx5 *sparx5,
313b37a1baeSSteen Hegelund 		       const unsigned char mac[ETH_ALEN], u16 vid);
314b37a1baeSSteen Hegelund int sparx5_add_mact_entry(struct sparx5 *sparx5,
3159f01cfbfSCasper Andersson 			  struct net_device *dev,
3169f01cfbfSCasper Andersson 			  u16 portno,
317b37a1baeSSteen Hegelund 			  const unsigned char *addr, u16 vid);
318b37a1baeSSteen Hegelund int sparx5_del_mact_entry(struct sparx5 *sparx5,
319b37a1baeSSteen Hegelund 			  const unsigned char *addr,
320b37a1baeSSteen Hegelund 			  u16 vid);
321b37a1baeSSteen Hegelund int sparx5_mc_sync(struct net_device *dev, const unsigned char *addr);
322b37a1baeSSteen Hegelund int sparx5_mc_unsync(struct net_device *dev, const unsigned char *addr);
323b37a1baeSSteen Hegelund void sparx5_set_ageing(struct sparx5 *sparx5, int msecs);
324b37a1baeSSteen Hegelund void sparx5_mact_init(struct sparx5 *sparx5);
325b37a1baeSSteen Hegelund 
32678eab33bSSteen Hegelund /* sparx5_vlan.c */
32778eab33bSSteen Hegelund void sparx5_pgid_update_mask(struct sparx5_port *port, int pgid, bool enable);
328*ad238fc6SCasper Andersson void sparx5_pgid_read_mask(struct sparx5 *sparx5, int pgid, u32 portmask[3]);
32978eab33bSSteen Hegelund void sparx5_update_fwd(struct sparx5 *sparx5);
33078eab33bSSteen Hegelund void sparx5_vlan_init(struct sparx5 *sparx5);
33178eab33bSSteen Hegelund void sparx5_vlan_port_setup(struct sparx5 *sparx5, int portno);
33278eab33bSSteen Hegelund int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid,
33378eab33bSSteen Hegelund 			bool untagged);
33478eab33bSSteen Hegelund int sparx5_vlan_vid_del(struct sparx5_port *port, u16 vid);
33578eab33bSSteen Hegelund void sparx5_vlan_port_apply(struct sparx5 *sparx5, struct sparx5_port *port);
33678eab33bSSteen Hegelund 
3370a9d48adSSteen Hegelund /* sparx5_calendar.c */
3380a9d48adSSteen Hegelund int sparx5_config_auto_calendar(struct sparx5 *sparx5);
3390a9d48adSSteen Hegelund int sparx5_config_dsm_calendar(struct sparx5 *sparx5);
3400a9d48adSSteen Hegelund 
341af4b1102SSteen Hegelund /* sparx5_ethtool.c */
342af4b1102SSteen Hegelund void sparx5_get_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats);
343af4b1102SSteen Hegelund int sparx_stats_init(struct sparx5 *sparx5);
344af4b1102SSteen Hegelund 
345f3cad261SSteen Hegelund /* sparx5_netdev.c */
34670dfe25cSHoratiu Vultur void sparx5_set_port_ifh_timestamp(void *ifh_hdr, u64 timestamp);
34770dfe25cSHoratiu Vultur void sparx5_set_port_ifh_rew_op(void *ifh_hdr, u32 rew_op);
34870dfe25cSHoratiu Vultur void sparx5_set_port_ifh_pdu_type(void *ifh_hdr, u32 pdu_type);
34970dfe25cSHoratiu Vultur void sparx5_set_port_ifh_pdu_w16_offset(void *ifh_hdr, u32 pdu_w16_offset);
3508f68f53aSHoratiu Vultur void sparx5_set_port_ifh(void *ifh_hdr, u16 portno);
351f3cad261SSteen Hegelund bool sparx5_netdevice_check(const struct net_device *dev);
352f3cad261SSteen Hegelund struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno);
353f3cad261SSteen Hegelund int sparx5_register_netdevs(struct sparx5 *sparx5);
354f3cad261SSteen Hegelund void sparx5_destroy_netdevs(struct sparx5 *sparx5);
355f3cad261SSteen Hegelund void sparx5_unregister_netdevs(struct sparx5 *sparx5);
356f3cad261SSteen Hegelund 
3570933bd04SHoratiu Vultur /* sparx5_ptp.c */
3580933bd04SHoratiu Vultur int sparx5_ptp_init(struct sparx5 *sparx5);
3590933bd04SHoratiu Vultur void sparx5_ptp_deinit(struct sparx5 *sparx5);
360589a07b8SHoratiu Vultur int sparx5_ptp_hwtstamp_set(struct sparx5_port *port, struct ifreq *ifr);
361589a07b8SHoratiu Vultur int sparx5_ptp_hwtstamp_get(struct sparx5_port *port, struct ifreq *ifr);
36270dfe25cSHoratiu Vultur void sparx5_ptp_rxtstamp(struct sparx5 *sparx5, struct sk_buff *skb,
36370dfe25cSHoratiu Vultur 			 u64 timestamp);
36470dfe25cSHoratiu Vultur int sparx5_ptp_txtstamp_request(struct sparx5_port *port,
36570dfe25cSHoratiu Vultur 				struct sk_buff *skb);
36670dfe25cSHoratiu Vultur void sparx5_ptp_txtstamp_release(struct sparx5_port *port,
36770dfe25cSHoratiu Vultur 				 struct sk_buff *skb);
368d31d3791SHoratiu Vultur irqreturn_t sparx5_ptp_irq_handler(int irq, void *args);
3690933bd04SHoratiu Vultur 
370af9b45d0SCasper Andersson /* sparx5_pgid.c */
371af9b45d0SCasper Andersson enum sparx5_pgid_type {
372af9b45d0SCasper Andersson 	SPX5_PGID_FREE,
373af9b45d0SCasper Andersson 	SPX5_PGID_RESERVED,
374af9b45d0SCasper Andersson 	SPX5_PGID_MULTICAST,
375af9b45d0SCasper Andersson };
376af9b45d0SCasper Andersson 
377af9b45d0SCasper Andersson void sparx5_pgid_init(struct sparx5 *spx5);
378af9b45d0SCasper Andersson int sparx5_pgid_alloc_glag(struct sparx5 *spx5, u16 *idx);
379af9b45d0SCasper Andersson int sparx5_pgid_alloc_mcast(struct sparx5 *spx5, u16 *idx);
380af9b45d0SCasper Andersson int sparx5_pgid_free(struct sparx5 *spx5, u16 idx);
381af9b45d0SCasper Andersson 
3823cfa11baSSteen Hegelund /* Clock period in picoseconds */
3833cfa11baSSteen Hegelund static inline u32 sparx5_clk_period(enum sparx5_core_clockfreq cclock)
3843cfa11baSSteen Hegelund {
3853cfa11baSSteen Hegelund 	switch (cclock) {
3863cfa11baSSteen Hegelund 	case SPX5_CORE_CLOCK_250MHZ:
3873cfa11baSSteen Hegelund 		return 4000;
3883cfa11baSSteen Hegelund 	case SPX5_CORE_CLOCK_500MHZ:
3893cfa11baSSteen Hegelund 		return 2000;
3903cfa11baSSteen Hegelund 	case SPX5_CORE_CLOCK_625MHZ:
3913cfa11baSSteen Hegelund 	default:
3923cfa11baSSteen Hegelund 		return 1600;
3933cfa11baSSteen Hegelund 	}
3943cfa11baSSteen Hegelund }
3953cfa11baSSteen Hegelund 
396f3cad261SSteen Hegelund static inline bool sparx5_is_baser(phy_interface_t interface)
397f3cad261SSteen Hegelund {
398f3cad261SSteen Hegelund 	return interface == PHY_INTERFACE_MODE_5GBASER ||
399f3cad261SSteen Hegelund 		   interface == PHY_INTERFACE_MODE_10GBASER ||
400f3cad261SSteen Hegelund 		   interface == PHY_INTERFACE_MODE_25GBASER;
401f3cad261SSteen Hegelund }
402f3cad261SSteen Hegelund 
403f3cad261SSteen Hegelund extern const struct phylink_mac_ops sparx5_phylink_mac_ops;
404f3cad261SSteen Hegelund extern const struct phylink_pcs_ops sparx5_phylink_pcs_ops;
405af4b1102SSteen Hegelund extern const struct ethtool_ops sparx5_ethtool_ops;
406f3cad261SSteen Hegelund 
4073cfa11baSSteen Hegelund /* Calculate raw offset */
4083cfa11baSSteen Hegelund static inline __pure int spx5_offset(int id, int tinst, int tcnt,
4093cfa11baSSteen Hegelund 				     int gbase, int ginst,
4103cfa11baSSteen Hegelund 				     int gcnt, int gwidth,
4113cfa11baSSteen Hegelund 				     int raddr, int rinst,
4123cfa11baSSteen Hegelund 				     int rcnt, int rwidth)
4133cfa11baSSteen Hegelund {
4143cfa11baSSteen Hegelund 	WARN_ON((tinst) >= tcnt);
4153cfa11baSSteen Hegelund 	WARN_ON((ginst) >= gcnt);
4163cfa11baSSteen Hegelund 	WARN_ON((rinst) >= rcnt);
4173cfa11baSSteen Hegelund 	return gbase + ((ginst) * gwidth) +
4183cfa11baSSteen Hegelund 		raddr + ((rinst) * rwidth);
4193cfa11baSSteen Hegelund }
4203cfa11baSSteen Hegelund 
4213cfa11baSSteen Hegelund /* Read, Write and modify registers content.
4223cfa11baSSteen Hegelund  * The register definition macros start at the id
4233cfa11baSSteen Hegelund  */
4243cfa11baSSteen Hegelund static inline void __iomem *spx5_addr(void __iomem *base[],
4253cfa11baSSteen Hegelund 				      int id, int tinst, int tcnt,
4263cfa11baSSteen Hegelund 				      int gbase, int ginst,
4273cfa11baSSteen Hegelund 				      int gcnt, int gwidth,
4283cfa11baSSteen Hegelund 				      int raddr, int rinst,
4293cfa11baSSteen Hegelund 				      int rcnt, int rwidth)
4303cfa11baSSteen Hegelund {
4313cfa11baSSteen Hegelund 	WARN_ON((tinst) >= tcnt);
4323cfa11baSSteen Hegelund 	WARN_ON((ginst) >= gcnt);
4333cfa11baSSteen Hegelund 	WARN_ON((rinst) >= rcnt);
4343cfa11baSSteen Hegelund 	return base[id + (tinst)] +
4353cfa11baSSteen Hegelund 		gbase + ((ginst) * gwidth) +
4363cfa11baSSteen Hegelund 		raddr + ((rinst) * rwidth);
4373cfa11baSSteen Hegelund }
4383cfa11baSSteen Hegelund 
4393cfa11baSSteen Hegelund static inline void __iomem *spx5_inst_addr(void __iomem *base,
4403cfa11baSSteen Hegelund 					   int gbase, int ginst,
4413cfa11baSSteen Hegelund 					   int gcnt, int gwidth,
4423cfa11baSSteen Hegelund 					   int raddr, int rinst,
4433cfa11baSSteen Hegelund 					   int rcnt, int rwidth)
4443cfa11baSSteen Hegelund {
4453cfa11baSSteen Hegelund 	WARN_ON((ginst) >= gcnt);
4463cfa11baSSteen Hegelund 	WARN_ON((rinst) >= rcnt);
4473cfa11baSSteen Hegelund 	return base +
4483cfa11baSSteen Hegelund 		gbase + ((ginst) * gwidth) +
4493cfa11baSSteen Hegelund 		raddr + ((rinst) * rwidth);
4503cfa11baSSteen Hegelund }
4513cfa11baSSteen Hegelund 
4523cfa11baSSteen Hegelund static inline u32 spx5_rd(struct sparx5 *sparx5, int id, int tinst, int tcnt,
4533cfa11baSSteen Hegelund 			  int gbase, int ginst, int gcnt, int gwidth,
4543cfa11baSSteen Hegelund 			  int raddr, int rinst, int rcnt, int rwidth)
4553cfa11baSSteen Hegelund {
4563cfa11baSSteen Hegelund 	return readl(spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst,
4573cfa11baSSteen Hegelund 			       gcnt, gwidth, raddr, rinst, rcnt, rwidth));
4583cfa11baSSteen Hegelund }
4593cfa11baSSteen Hegelund 
4603cfa11baSSteen Hegelund static inline u32 spx5_inst_rd(void __iomem *iomem, int id, int tinst, int tcnt,
4613cfa11baSSteen Hegelund 			       int gbase, int ginst, int gcnt, int gwidth,
4623cfa11baSSteen Hegelund 			       int raddr, int rinst, int rcnt, int rwidth)
4633cfa11baSSteen Hegelund {
4643cfa11baSSteen Hegelund 	return readl(spx5_inst_addr(iomem, gbase, ginst,
4653cfa11baSSteen Hegelund 				     gcnt, gwidth, raddr, rinst, rcnt, rwidth));
4663cfa11baSSteen Hegelund }
4673cfa11baSSteen Hegelund 
4683cfa11baSSteen Hegelund static inline void spx5_wr(u32 val, struct sparx5 *sparx5,
4693cfa11baSSteen Hegelund 			   int id, int tinst, int tcnt,
4703cfa11baSSteen Hegelund 			   int gbase, int ginst, int gcnt, int gwidth,
4713cfa11baSSteen Hegelund 			   int raddr, int rinst, int rcnt, int rwidth)
4723cfa11baSSteen Hegelund {
4733cfa11baSSteen Hegelund 	writel(val, spx5_addr(sparx5->regs, id, tinst, tcnt,
4743cfa11baSSteen Hegelund 			      gbase, ginst, gcnt, gwidth,
4753cfa11baSSteen Hegelund 			      raddr, rinst, rcnt, rwidth));
4763cfa11baSSteen Hegelund }
4773cfa11baSSteen Hegelund 
4783cfa11baSSteen Hegelund static inline void spx5_inst_wr(u32 val, void __iomem *iomem,
4793cfa11baSSteen Hegelund 				int id, int tinst, int tcnt,
4803cfa11baSSteen Hegelund 				int gbase, int ginst, int gcnt, int gwidth,
4813cfa11baSSteen Hegelund 				int raddr, int rinst, int rcnt, int rwidth)
4823cfa11baSSteen Hegelund {
4833cfa11baSSteen Hegelund 	writel(val, spx5_inst_addr(iomem,
4843cfa11baSSteen Hegelund 				   gbase, ginst, gcnt, gwidth,
4853cfa11baSSteen Hegelund 				   raddr, rinst, rcnt, rwidth));
4863cfa11baSSteen Hegelund }
4873cfa11baSSteen Hegelund 
4883cfa11baSSteen Hegelund static inline void spx5_rmw(u32 val, u32 mask, struct sparx5 *sparx5,
4893cfa11baSSteen Hegelund 			    int id, int tinst, int tcnt,
4903cfa11baSSteen Hegelund 			    int gbase, int ginst, int gcnt, int gwidth,
4913cfa11baSSteen Hegelund 			    int raddr, int rinst, int rcnt, int rwidth)
4923cfa11baSSteen Hegelund {
4933cfa11baSSteen Hegelund 	u32 nval;
4943cfa11baSSteen Hegelund 
4953cfa11baSSteen Hegelund 	nval = readl(spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst,
4963cfa11baSSteen Hegelund 			       gcnt, gwidth, raddr, rinst, rcnt, rwidth));
4973cfa11baSSteen Hegelund 	nval = (nval & ~mask) | (val & mask);
4983cfa11baSSteen Hegelund 	writel(nval, spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst,
4993cfa11baSSteen Hegelund 			       gcnt, gwidth, raddr, rinst, rcnt, rwidth));
5003cfa11baSSteen Hegelund }
5013cfa11baSSteen Hegelund 
5023cfa11baSSteen Hegelund static inline void spx5_inst_rmw(u32 val, u32 mask, void __iomem *iomem,
5033cfa11baSSteen Hegelund 				 int id, int tinst, int tcnt,
5043cfa11baSSteen Hegelund 				 int gbase, int ginst, int gcnt, int gwidth,
5053cfa11baSSteen Hegelund 				 int raddr, int rinst, int rcnt, int rwidth)
5063cfa11baSSteen Hegelund {
5073cfa11baSSteen Hegelund 	u32 nval;
5083cfa11baSSteen Hegelund 
5093cfa11baSSteen Hegelund 	nval = readl(spx5_inst_addr(iomem, gbase, ginst, gcnt, gwidth, raddr,
5103cfa11baSSteen Hegelund 				    rinst, rcnt, rwidth));
5113cfa11baSSteen Hegelund 	nval = (nval & ~mask) | (val & mask);
5123cfa11baSSteen Hegelund 	writel(nval, spx5_inst_addr(iomem, gbase, ginst, gcnt, gwidth, raddr,
5133cfa11baSSteen Hegelund 				    rinst, rcnt, rwidth));
5143cfa11baSSteen Hegelund }
5153cfa11baSSteen Hegelund 
5163cfa11baSSteen Hegelund static inline void __iomem *spx5_inst_get(struct sparx5 *sparx5, int id, int tinst)
5173cfa11baSSteen Hegelund {
5183cfa11baSSteen Hegelund 	return sparx5->regs[id + tinst];
5193cfa11baSSteen Hegelund }
5203cfa11baSSteen Hegelund 
5213cfa11baSSteen Hegelund static inline void __iomem *spx5_reg_get(struct sparx5 *sparx5,
5223cfa11baSSteen Hegelund 					 int id, int tinst, int tcnt,
5233cfa11baSSteen Hegelund 					 int gbase, int ginst, int gcnt, int gwidth,
5243cfa11baSSteen Hegelund 					 int raddr, int rinst, int rcnt, int rwidth)
5253cfa11baSSteen Hegelund {
5263cfa11baSSteen Hegelund 	return spx5_addr(sparx5->regs, id, tinst, tcnt,
5273cfa11baSSteen Hegelund 			 gbase, ginst, gcnt, gwidth,
5283cfa11baSSteen Hegelund 			 raddr, rinst, rcnt, rwidth);
5293cfa11baSSteen Hegelund }
5303cfa11baSSteen Hegelund 
5313cfa11baSSteen Hegelund #endif	/* __SPARX5_MAIN_H__ */
532