xref: /linux/drivers/net/ethernet/microchip/sparx5/sparx5_main.h (revision 9f01cfbf2922432668c2fd4dfc0413342aaff48b)
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)
683cfa11baSSteen Hegelund 
693cfa11baSSteen Hegelund #define IFH_LEN                9 /* 36 bytes */
703cfa11baSSteen Hegelund #define NULL_VID               0
713cfa11baSSteen Hegelund #define SPX5_MACT_PULL_DELAY   (2 * HZ)
723cfa11baSSteen Hegelund #define SPX5_STATS_CHECK_DELAY (1 * HZ)
733cfa11baSSteen Hegelund #define SPX5_PRIOS             8     /* Number of priority queues */
743cfa11baSSteen Hegelund #define SPX5_BUFFER_CELL_SZ    184   /* Cell size  */
753cfa11baSSteen Hegelund #define SPX5_BUFFER_MEMORY     4194280 /* 22795 words * 184 bytes */
763cfa11baSSteen Hegelund 
77f3cad261SSteen Hegelund #define XTR_QUEUE     0
78f3cad261SSteen Hegelund #define INJ_QUEUE     0
79f3cad261SSteen Hegelund 
8010615907SSteen Hegelund #define FDMA_DCB_MAX			64
8110615907SSteen Hegelund #define FDMA_RX_DCB_MAX_DBS		15
8210615907SSteen Hegelund #define FDMA_TX_DCB_MAX_DBS		1
8310615907SSteen Hegelund 
840933bd04SHoratiu Vultur #define SPARX5_PHC_COUNT		3
850933bd04SHoratiu Vultur #define SPARX5_PHC_PORT			0
860933bd04SHoratiu Vultur 
87589a07b8SHoratiu Vultur #define IFH_REW_OP_NOOP			0x0
88589a07b8SHoratiu Vultur #define IFH_REW_OP_ONE_STEP_PTP		0x3
89589a07b8SHoratiu Vultur #define IFH_REW_OP_TWO_STEP_PTP		0x4
90589a07b8SHoratiu Vultur 
9170dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_NONE		0x0
9270dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_PTP		0x5
9370dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_IPV4_UDP_PTP	0x6
9470dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_IPV6_UDP_PTP	0x7
9570dfe25cSHoratiu Vultur 
963cfa11baSSteen Hegelund struct sparx5;
973cfa11baSSteen Hegelund 
9810615907SSteen Hegelund struct sparx5_db_hw {
9910615907SSteen Hegelund 	u64 dataptr;
10010615907SSteen Hegelund 	u64 status;
10110615907SSteen Hegelund };
10210615907SSteen Hegelund 
10310615907SSteen Hegelund struct sparx5_rx_dcb_hw {
10410615907SSteen Hegelund 	u64 nextptr;
10510615907SSteen Hegelund 	u64 info;
10610615907SSteen Hegelund 	struct sparx5_db_hw db[FDMA_RX_DCB_MAX_DBS];
10710615907SSteen Hegelund };
10810615907SSteen Hegelund 
10910615907SSteen Hegelund struct sparx5_tx_dcb_hw {
11010615907SSteen Hegelund 	u64 nextptr;
11110615907SSteen Hegelund 	u64 info;
11210615907SSteen Hegelund 	struct sparx5_db_hw db[FDMA_TX_DCB_MAX_DBS];
11310615907SSteen Hegelund };
11410615907SSteen Hegelund 
11510615907SSteen Hegelund /* Frame DMA receive state:
11610615907SSteen Hegelund  * For each DB, there is a SKB, and the skb data pointer is mapped in
11710615907SSteen Hegelund  * the DB. Once a frame is received the skb is given to the upper layers
11810615907SSteen Hegelund  * and a new skb is added to the dcb.
11910615907SSteen Hegelund  * When the db_index reached FDMA_RX_DCB_MAX_DBS the DB is reused.
12010615907SSteen Hegelund  */
12110615907SSteen Hegelund struct sparx5_rx {
12210615907SSteen Hegelund 	struct sparx5_rx_dcb_hw *dcb_entries;
12310615907SSteen Hegelund 	struct sparx5_rx_dcb_hw *last_entry;
12410615907SSteen Hegelund 	struct sk_buff *skb[FDMA_DCB_MAX][FDMA_RX_DCB_MAX_DBS];
12510615907SSteen Hegelund 	int db_index;
12610615907SSteen Hegelund 	int dcb_index;
12710615907SSteen Hegelund 	dma_addr_t dma;
12810615907SSteen Hegelund 	struct napi_struct napi;
12910615907SSteen Hegelund 	u32 channel_id;
13010615907SSteen Hegelund 	struct net_device *ndev;
13110615907SSteen Hegelund 	u64 packets;
13210615907SSteen Hegelund };
13310615907SSteen Hegelund 
13410615907SSteen Hegelund /* Frame DMA transmit state:
13510615907SSteen Hegelund  * DCBs are chained using the DCBs nextptr field.
13610615907SSteen Hegelund  */
13710615907SSteen Hegelund struct sparx5_tx {
13810615907SSteen Hegelund 	struct sparx5_tx_dcb_hw *curr_entry;
13910615907SSteen Hegelund 	struct sparx5_tx_dcb_hw *first_entry;
14010615907SSteen Hegelund 	struct list_head db_list;
14110615907SSteen Hegelund 	dma_addr_t dma;
14210615907SSteen Hegelund 	u32 channel_id;
14310615907SSteen Hegelund 	u64 packets;
14410615907SSteen Hegelund 	u64 dropped;
14510615907SSteen Hegelund };
14610615907SSteen Hegelund 
1473cfa11baSSteen Hegelund struct sparx5_port_config {
1483cfa11baSSteen Hegelund 	phy_interface_t portmode;
1493cfa11baSSteen Hegelund 	u32 bandwidth;
1503cfa11baSSteen Hegelund 	int speed;
1513cfa11baSSteen Hegelund 	int duplex;
1523cfa11baSSteen Hegelund 	enum phy_media media;
1533cfa11baSSteen Hegelund 	bool inband;
1543cfa11baSSteen Hegelund 	bool power_down;
1553cfa11baSSteen Hegelund 	bool autoneg;
1563cfa11baSSteen Hegelund 	bool serdes_reset;
1573cfa11baSSteen Hegelund 	u32 pause;
1583cfa11baSSteen Hegelund 	u32 pause_adv;
1593cfa11baSSteen Hegelund 	phy_interface_t phy_mode;
1603cfa11baSSteen Hegelund 	u32 sd_sgpio;
1613cfa11baSSteen Hegelund };
1623cfa11baSSteen Hegelund 
1633cfa11baSSteen Hegelund struct sparx5_port {
1643cfa11baSSteen Hegelund 	struct net_device *ndev;
1653cfa11baSSteen Hegelund 	struct sparx5 *sparx5;
1663cfa11baSSteen Hegelund 	struct device_node *of_node;
1673cfa11baSSteen Hegelund 	struct phy *serdes;
1683cfa11baSSteen Hegelund 	struct sparx5_port_config conf;
169f3cad261SSteen Hegelund 	struct phylink_config phylink_config;
170f3cad261SSteen Hegelund 	struct phylink *phylink;
171f3cad261SSteen Hegelund 	struct phylink_pcs phylink_pcs;
1723cfa11baSSteen Hegelund 	u16 portno;
1733cfa11baSSteen Hegelund 	/* Ingress default VLAN (pvid) */
1743cfa11baSSteen Hegelund 	u16 pvid;
1753cfa11baSSteen Hegelund 	/* Egress default VLAN (vid) */
1763cfa11baSSteen Hegelund 	u16 vid;
1773cfa11baSSteen Hegelund 	bool signd_internal;
1783cfa11baSSteen Hegelund 	bool signd_active_high;
1793cfa11baSSteen Hegelund 	bool signd_enable;
1803cfa11baSSteen Hegelund 	bool flow_control;
1813cfa11baSSteen Hegelund 	enum sparx5_port_max_tags max_vlan_tags;
1823cfa11baSSteen Hegelund 	enum sparx5_vlan_port_type vlan_type;
1833cfa11baSSteen Hegelund 	u32 custom_etype;
1843cfa11baSSteen Hegelund 	bool vlan_aware;
185f3cad261SSteen Hegelund 	struct hrtimer inj_timer;
186589a07b8SHoratiu Vultur 	/* ptp */
187589a07b8SHoratiu Vultur 	u8 ptp_cmd;
18870dfe25cSHoratiu Vultur 	u16 ts_id;
18970dfe25cSHoratiu Vultur 	struct sk_buff_head tx_skbs;
1903cfa11baSSteen Hegelund };
1913cfa11baSSteen Hegelund 
1923cfa11baSSteen Hegelund enum sparx5_core_clockfreq {
1933cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_DEFAULT,  /* Defaults to the highest supported frequency */
1943cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_250MHZ,   /* 250MHZ core clock frequency */
1953cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_500MHZ,   /* 500MHZ core clock frequency */
1963cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_625MHZ,   /* 625MHZ core clock frequency */
1973cfa11baSSteen Hegelund };
1983cfa11baSSteen Hegelund 
1990933bd04SHoratiu Vultur struct sparx5_phc {
2000933bd04SHoratiu Vultur 	struct ptp_clock *clock;
2010933bd04SHoratiu Vultur 	struct ptp_clock_info info;
2020933bd04SHoratiu Vultur 	struct hwtstamp_config hwtstamp_config;
2030933bd04SHoratiu Vultur 	struct sparx5 *sparx5;
2040933bd04SHoratiu Vultur 	u8 index;
2050933bd04SHoratiu Vultur };
2060933bd04SHoratiu Vultur 
20770dfe25cSHoratiu Vultur struct sparx5_skb_cb {
20870dfe25cSHoratiu Vultur 	u8 rew_op;
20970dfe25cSHoratiu Vultur 	u8 pdu_type;
21070dfe25cSHoratiu Vultur 	u8 pdu_w16_offset;
21170dfe25cSHoratiu Vultur 	u16 ts_id;
21270dfe25cSHoratiu Vultur 	unsigned long jiffies;
21370dfe25cSHoratiu Vultur };
21470dfe25cSHoratiu Vultur 
21570dfe25cSHoratiu Vultur #define SPARX5_PTP_TIMEOUT		msecs_to_jiffies(10)
21670dfe25cSHoratiu Vultur #define SPARX5_SKB_CB(skb) \
21770dfe25cSHoratiu Vultur 	((struct sparx5_skb_cb *)((skb)->cb))
21870dfe25cSHoratiu Vultur 
2193cfa11baSSteen Hegelund struct sparx5 {
2203cfa11baSSteen Hegelund 	struct platform_device *pdev;
2213cfa11baSSteen Hegelund 	struct device *dev;
2223cfa11baSSteen Hegelund 	u32 chip_id;
2233cfa11baSSteen Hegelund 	enum spx5_target_chiptype target_ct;
2243cfa11baSSteen Hegelund 	void __iomem *regs[NUM_TARGETS];
2253cfa11baSSteen Hegelund 	int port_count;
2263cfa11baSSteen Hegelund 	struct mutex lock; /* MAC reg lock */
2273cfa11baSSteen Hegelund 	/* port structures are in net device */
2283cfa11baSSteen Hegelund 	struct sparx5_port *ports[SPX5_PORTS];
2293cfa11baSSteen Hegelund 	enum sparx5_core_clockfreq coreclock;
230af4b1102SSteen Hegelund 	/* Statistics */
231af4b1102SSteen Hegelund 	u32 num_stats;
232af4b1102SSteen Hegelund 	u32 num_ethtool_stats;
233af4b1102SSteen Hegelund 	const char * const *stats_layout;
234af4b1102SSteen Hegelund 	u64 *stats;
235af4b1102SSteen Hegelund 	/* Workqueue for reading stats */
236af4b1102SSteen Hegelund 	struct mutex queue_stats_lock;
237af4b1102SSteen Hegelund 	struct delayed_work stats_work;
238af4b1102SSteen Hegelund 	struct workqueue_struct *stats_queue;
239d6fce514SSteen Hegelund 	/* Notifiers */
240d6fce514SSteen Hegelund 	struct notifier_block netdevice_nb;
241d6fce514SSteen Hegelund 	struct notifier_block switchdev_nb;
242d6fce514SSteen Hegelund 	struct notifier_block switchdev_blocking_nb;
243b37a1baeSSteen Hegelund 	/* Switch state */
2443cfa11baSSteen Hegelund 	u8 base_mac[ETH_ALEN];
245d6fce514SSteen Hegelund 	/* Associated bridge device (when bridged) */
246d6fce514SSteen Hegelund 	struct net_device *hw_bridge_dev;
24778eab33bSSteen Hegelund 	/* Bridged interfaces */
248d6fce514SSteen Hegelund 	DECLARE_BITMAP(bridge_mask, SPX5_PORTS);
24978eab33bSSteen Hegelund 	DECLARE_BITMAP(bridge_fwd_mask, SPX5_PORTS);
25078eab33bSSteen Hegelund 	DECLARE_BITMAP(bridge_lrn_mask, SPX5_PORTS);
25178eab33bSSteen Hegelund 	DECLARE_BITMAP(vlan_mask[VLAN_N_VID], SPX5_PORTS);
252b37a1baeSSteen Hegelund 	/* SW MAC table */
253b37a1baeSSteen Hegelund 	struct list_head mact_entries;
254b37a1baeSSteen Hegelund 	/* mac table list (mact_entries) mutex */
255b37a1baeSSteen Hegelund 	struct mutex mact_lock;
256b37a1baeSSteen Hegelund 	struct delayed_work mact_work;
257b37a1baeSSteen Hegelund 	struct workqueue_struct *mact_queue;
2583cfa11baSSteen Hegelund 	/* Board specifics */
2593cfa11baSSteen Hegelund 	bool sd_sgpio_remapping;
260f3cad261SSteen Hegelund 	/* Register based inj/xtr */
261f3cad261SSteen Hegelund 	int xtr_irq;
26210615907SSteen Hegelund 	/* Frame DMA */
26310615907SSteen Hegelund 	int fdma_irq;
26410615907SSteen Hegelund 	struct sparx5_rx rx;
26510615907SSteen Hegelund 	struct sparx5_tx tx;
2660933bd04SHoratiu Vultur 	/* PTP */
2670933bd04SHoratiu Vultur 	bool ptp;
2680933bd04SHoratiu Vultur 	struct sparx5_phc phc[SPARX5_PHC_COUNT];
2690933bd04SHoratiu Vultur 	spinlock_t ptp_clock_lock; /* lock for phc */
27070dfe25cSHoratiu Vultur 	spinlock_t ptp_ts_id_lock; /* lock for ts_id */
271589a07b8SHoratiu Vultur 	struct mutex ptp_lock; /* lock for ptp interface state */
27270dfe25cSHoratiu Vultur 	u16 ptp_skbs;
273d31d3791SHoratiu Vultur 	int ptp_irq;
2743cfa11baSSteen Hegelund };
2753cfa11baSSteen Hegelund 
276d6fce514SSteen Hegelund /* sparx5_switchdev.c */
277d6fce514SSteen Hegelund int sparx5_register_notifier_blocks(struct sparx5 *sparx5);
278d6fce514SSteen Hegelund void sparx5_unregister_notifier_blocks(struct sparx5 *sparx5);
279d6fce514SSteen Hegelund 
280f3cad261SSteen Hegelund /* sparx5_packet.c */
28110615907SSteen Hegelund struct frame_info {
28210615907SSteen Hegelund 	int src_port;
28370dfe25cSHoratiu Vultur 	u32 timestamp;
28410615907SSteen Hegelund };
28510615907SSteen Hegelund 
28610615907SSteen Hegelund void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp);
28710615907SSteen Hegelund void sparx5_ifh_parse(u32 *ifh, struct frame_info *info);
288f3cad261SSteen Hegelund irqreturn_t sparx5_xtr_handler(int irq, void *_priv);
289f3cad261SSteen Hegelund int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev);
290f3cad261SSteen Hegelund int sparx5_manual_injection_mode(struct sparx5 *sparx5);
291f3cad261SSteen Hegelund void sparx5_port_inj_timer_setup(struct sparx5_port *port);
292f3cad261SSteen Hegelund 
29310615907SSteen Hegelund /* sparx5_fdma.c */
29410615907SSteen Hegelund int sparx5_fdma_start(struct sparx5 *sparx5);
29510615907SSteen Hegelund int sparx5_fdma_stop(struct sparx5 *sparx5);
29610615907SSteen Hegelund int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb);
29710615907SSteen Hegelund irqreturn_t sparx5_fdma_handler(int irq, void *args);
29810615907SSteen Hegelund 
299b37a1baeSSteen Hegelund /* sparx5_mactable.c */
300b37a1baeSSteen Hegelund void sparx5_mact_pull_work(struct work_struct *work);
301b37a1baeSSteen Hegelund int sparx5_mact_learn(struct sparx5 *sparx5, int port,
302b37a1baeSSteen Hegelund 		      const unsigned char mac[ETH_ALEN], u16 vid);
303b37a1baeSSteen Hegelund bool sparx5_mact_getnext(struct sparx5 *sparx5,
304b37a1baeSSteen Hegelund 			 unsigned char mac[ETH_ALEN], u16 *vid, u32 *pcfg2);
305b37a1baeSSteen Hegelund int sparx5_mact_forget(struct sparx5 *sparx5,
306b37a1baeSSteen Hegelund 		       const unsigned char mac[ETH_ALEN], u16 vid);
307b37a1baeSSteen Hegelund int sparx5_add_mact_entry(struct sparx5 *sparx5,
308*9f01cfbfSCasper Andersson 			  struct net_device *dev,
309*9f01cfbfSCasper Andersson 			  u16 portno,
310b37a1baeSSteen Hegelund 			  const unsigned char *addr, u16 vid);
311b37a1baeSSteen Hegelund int sparx5_del_mact_entry(struct sparx5 *sparx5,
312b37a1baeSSteen Hegelund 			  const unsigned char *addr,
313b37a1baeSSteen Hegelund 			  u16 vid);
314b37a1baeSSteen Hegelund int sparx5_mc_sync(struct net_device *dev, const unsigned char *addr);
315b37a1baeSSteen Hegelund int sparx5_mc_unsync(struct net_device *dev, const unsigned char *addr);
316b37a1baeSSteen Hegelund void sparx5_set_ageing(struct sparx5 *sparx5, int msecs);
317b37a1baeSSteen Hegelund void sparx5_mact_init(struct sparx5 *sparx5);
318b37a1baeSSteen Hegelund 
31978eab33bSSteen Hegelund /* sparx5_vlan.c */
32078eab33bSSteen Hegelund void sparx5_pgid_update_mask(struct sparx5_port *port, int pgid, bool enable);
32178eab33bSSteen Hegelund void sparx5_update_fwd(struct sparx5 *sparx5);
32278eab33bSSteen Hegelund void sparx5_vlan_init(struct sparx5 *sparx5);
32378eab33bSSteen Hegelund void sparx5_vlan_port_setup(struct sparx5 *sparx5, int portno);
32478eab33bSSteen Hegelund int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid,
32578eab33bSSteen Hegelund 			bool untagged);
32678eab33bSSteen Hegelund int sparx5_vlan_vid_del(struct sparx5_port *port, u16 vid);
32778eab33bSSteen Hegelund void sparx5_vlan_port_apply(struct sparx5 *sparx5, struct sparx5_port *port);
32878eab33bSSteen Hegelund 
3290a9d48adSSteen Hegelund /* sparx5_calendar.c */
3300a9d48adSSteen Hegelund int sparx5_config_auto_calendar(struct sparx5 *sparx5);
3310a9d48adSSteen Hegelund int sparx5_config_dsm_calendar(struct sparx5 *sparx5);
3320a9d48adSSteen Hegelund 
333af4b1102SSteen Hegelund /* sparx5_ethtool.c */
334af4b1102SSteen Hegelund void sparx5_get_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats);
335af4b1102SSteen Hegelund int sparx_stats_init(struct sparx5 *sparx5);
336af4b1102SSteen Hegelund 
337f3cad261SSteen Hegelund /* sparx5_netdev.c */
33870dfe25cSHoratiu Vultur void sparx5_set_port_ifh_timestamp(void *ifh_hdr, u64 timestamp);
33970dfe25cSHoratiu Vultur void sparx5_set_port_ifh_rew_op(void *ifh_hdr, u32 rew_op);
34070dfe25cSHoratiu Vultur void sparx5_set_port_ifh_pdu_type(void *ifh_hdr, u32 pdu_type);
34170dfe25cSHoratiu Vultur void sparx5_set_port_ifh_pdu_w16_offset(void *ifh_hdr, u32 pdu_w16_offset);
3428f68f53aSHoratiu Vultur void sparx5_set_port_ifh(void *ifh_hdr, u16 portno);
343f3cad261SSteen Hegelund bool sparx5_netdevice_check(const struct net_device *dev);
344f3cad261SSteen Hegelund struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno);
345f3cad261SSteen Hegelund int sparx5_register_netdevs(struct sparx5 *sparx5);
346f3cad261SSteen Hegelund void sparx5_destroy_netdevs(struct sparx5 *sparx5);
347f3cad261SSteen Hegelund void sparx5_unregister_netdevs(struct sparx5 *sparx5);
348f3cad261SSteen Hegelund 
3490933bd04SHoratiu Vultur /* sparx5_ptp.c */
3500933bd04SHoratiu Vultur int sparx5_ptp_init(struct sparx5 *sparx5);
3510933bd04SHoratiu Vultur void sparx5_ptp_deinit(struct sparx5 *sparx5);
352589a07b8SHoratiu Vultur int sparx5_ptp_hwtstamp_set(struct sparx5_port *port, struct ifreq *ifr);
353589a07b8SHoratiu Vultur int sparx5_ptp_hwtstamp_get(struct sparx5_port *port, struct ifreq *ifr);
35470dfe25cSHoratiu Vultur void sparx5_ptp_rxtstamp(struct sparx5 *sparx5, struct sk_buff *skb,
35570dfe25cSHoratiu Vultur 			 u64 timestamp);
35670dfe25cSHoratiu Vultur int sparx5_ptp_txtstamp_request(struct sparx5_port *port,
35770dfe25cSHoratiu Vultur 				struct sk_buff *skb);
35870dfe25cSHoratiu Vultur void sparx5_ptp_txtstamp_release(struct sparx5_port *port,
35970dfe25cSHoratiu Vultur 				 struct sk_buff *skb);
360d31d3791SHoratiu Vultur irqreturn_t sparx5_ptp_irq_handler(int irq, void *args);
3610933bd04SHoratiu Vultur 
3623cfa11baSSteen Hegelund /* Clock period in picoseconds */
3633cfa11baSSteen Hegelund static inline u32 sparx5_clk_period(enum sparx5_core_clockfreq cclock)
3643cfa11baSSteen Hegelund {
3653cfa11baSSteen Hegelund 	switch (cclock) {
3663cfa11baSSteen Hegelund 	case SPX5_CORE_CLOCK_250MHZ:
3673cfa11baSSteen Hegelund 		return 4000;
3683cfa11baSSteen Hegelund 	case SPX5_CORE_CLOCK_500MHZ:
3693cfa11baSSteen Hegelund 		return 2000;
3703cfa11baSSteen Hegelund 	case SPX5_CORE_CLOCK_625MHZ:
3713cfa11baSSteen Hegelund 	default:
3723cfa11baSSteen Hegelund 		return 1600;
3733cfa11baSSteen Hegelund 	}
3743cfa11baSSteen Hegelund }
3753cfa11baSSteen Hegelund 
376f3cad261SSteen Hegelund static inline bool sparx5_is_baser(phy_interface_t interface)
377f3cad261SSteen Hegelund {
378f3cad261SSteen Hegelund 	return interface == PHY_INTERFACE_MODE_5GBASER ||
379f3cad261SSteen Hegelund 		   interface == PHY_INTERFACE_MODE_10GBASER ||
380f3cad261SSteen Hegelund 		   interface == PHY_INTERFACE_MODE_25GBASER;
381f3cad261SSteen Hegelund }
382f3cad261SSteen Hegelund 
383f3cad261SSteen Hegelund extern const struct phylink_mac_ops sparx5_phylink_mac_ops;
384f3cad261SSteen Hegelund extern const struct phylink_pcs_ops sparx5_phylink_pcs_ops;
385af4b1102SSteen Hegelund extern const struct ethtool_ops sparx5_ethtool_ops;
386f3cad261SSteen Hegelund 
3873cfa11baSSteen Hegelund /* Calculate raw offset */
3883cfa11baSSteen Hegelund static inline __pure int spx5_offset(int id, int tinst, int tcnt,
3893cfa11baSSteen Hegelund 				     int gbase, int ginst,
3903cfa11baSSteen Hegelund 				     int gcnt, int gwidth,
3913cfa11baSSteen Hegelund 				     int raddr, int rinst,
3923cfa11baSSteen Hegelund 				     int rcnt, int rwidth)
3933cfa11baSSteen Hegelund {
3943cfa11baSSteen Hegelund 	WARN_ON((tinst) >= tcnt);
3953cfa11baSSteen Hegelund 	WARN_ON((ginst) >= gcnt);
3963cfa11baSSteen Hegelund 	WARN_ON((rinst) >= rcnt);
3973cfa11baSSteen Hegelund 	return gbase + ((ginst) * gwidth) +
3983cfa11baSSteen Hegelund 		raddr + ((rinst) * rwidth);
3993cfa11baSSteen Hegelund }
4003cfa11baSSteen Hegelund 
4013cfa11baSSteen Hegelund /* Read, Write and modify registers content.
4023cfa11baSSteen Hegelund  * The register definition macros start at the id
4033cfa11baSSteen Hegelund  */
4043cfa11baSSteen Hegelund static inline void __iomem *spx5_addr(void __iomem *base[],
4053cfa11baSSteen Hegelund 				      int id, int tinst, int tcnt,
4063cfa11baSSteen Hegelund 				      int gbase, int ginst,
4073cfa11baSSteen Hegelund 				      int gcnt, int gwidth,
4083cfa11baSSteen Hegelund 				      int raddr, int rinst,
4093cfa11baSSteen Hegelund 				      int rcnt, int rwidth)
4103cfa11baSSteen Hegelund {
4113cfa11baSSteen Hegelund 	WARN_ON((tinst) >= tcnt);
4123cfa11baSSteen Hegelund 	WARN_ON((ginst) >= gcnt);
4133cfa11baSSteen Hegelund 	WARN_ON((rinst) >= rcnt);
4143cfa11baSSteen Hegelund 	return base[id + (tinst)] +
4153cfa11baSSteen Hegelund 		gbase + ((ginst) * gwidth) +
4163cfa11baSSteen Hegelund 		raddr + ((rinst) * rwidth);
4173cfa11baSSteen Hegelund }
4183cfa11baSSteen Hegelund 
4193cfa11baSSteen Hegelund static inline void __iomem *spx5_inst_addr(void __iomem *base,
4203cfa11baSSteen Hegelund 					   int gbase, int ginst,
4213cfa11baSSteen Hegelund 					   int gcnt, int gwidth,
4223cfa11baSSteen Hegelund 					   int raddr, int rinst,
4233cfa11baSSteen Hegelund 					   int rcnt, int rwidth)
4243cfa11baSSteen Hegelund {
4253cfa11baSSteen Hegelund 	WARN_ON((ginst) >= gcnt);
4263cfa11baSSteen Hegelund 	WARN_ON((rinst) >= rcnt);
4273cfa11baSSteen Hegelund 	return base +
4283cfa11baSSteen Hegelund 		gbase + ((ginst) * gwidth) +
4293cfa11baSSteen Hegelund 		raddr + ((rinst) * rwidth);
4303cfa11baSSteen Hegelund }
4313cfa11baSSteen Hegelund 
4323cfa11baSSteen Hegelund static inline u32 spx5_rd(struct sparx5 *sparx5, int id, int tinst, int tcnt,
4333cfa11baSSteen Hegelund 			  int gbase, int ginst, int gcnt, int gwidth,
4343cfa11baSSteen Hegelund 			  int raddr, int rinst, int rcnt, int rwidth)
4353cfa11baSSteen Hegelund {
4363cfa11baSSteen Hegelund 	return readl(spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst,
4373cfa11baSSteen Hegelund 			       gcnt, gwidth, raddr, rinst, rcnt, rwidth));
4383cfa11baSSteen Hegelund }
4393cfa11baSSteen Hegelund 
4403cfa11baSSteen Hegelund static inline u32 spx5_inst_rd(void __iomem *iomem, int id, int tinst, int tcnt,
4413cfa11baSSteen Hegelund 			       int gbase, int ginst, int gcnt, int gwidth,
4423cfa11baSSteen Hegelund 			       int raddr, int rinst, int rcnt, int rwidth)
4433cfa11baSSteen Hegelund {
4443cfa11baSSteen Hegelund 	return readl(spx5_inst_addr(iomem, gbase, ginst,
4453cfa11baSSteen Hegelund 				     gcnt, gwidth, raddr, rinst, rcnt, rwidth));
4463cfa11baSSteen Hegelund }
4473cfa11baSSteen Hegelund 
4483cfa11baSSteen Hegelund static inline void spx5_wr(u32 val, struct sparx5 *sparx5,
4493cfa11baSSteen Hegelund 			   int id, int tinst, int tcnt,
4503cfa11baSSteen Hegelund 			   int gbase, int ginst, int gcnt, int gwidth,
4513cfa11baSSteen Hegelund 			   int raddr, int rinst, int rcnt, int rwidth)
4523cfa11baSSteen Hegelund {
4533cfa11baSSteen Hegelund 	writel(val, spx5_addr(sparx5->regs, id, tinst, tcnt,
4543cfa11baSSteen Hegelund 			      gbase, ginst, gcnt, gwidth,
4553cfa11baSSteen Hegelund 			      raddr, rinst, rcnt, rwidth));
4563cfa11baSSteen Hegelund }
4573cfa11baSSteen Hegelund 
4583cfa11baSSteen Hegelund static inline void spx5_inst_wr(u32 val, void __iomem *iomem,
4593cfa11baSSteen Hegelund 				int id, int tinst, int tcnt,
4603cfa11baSSteen Hegelund 				int gbase, int ginst, int gcnt, int gwidth,
4613cfa11baSSteen Hegelund 				int raddr, int rinst, int rcnt, int rwidth)
4623cfa11baSSteen Hegelund {
4633cfa11baSSteen Hegelund 	writel(val, spx5_inst_addr(iomem,
4643cfa11baSSteen Hegelund 				   gbase, ginst, gcnt, gwidth,
4653cfa11baSSteen Hegelund 				   raddr, rinst, rcnt, rwidth));
4663cfa11baSSteen Hegelund }
4673cfa11baSSteen Hegelund 
4683cfa11baSSteen Hegelund static inline void spx5_rmw(u32 val, u32 mask, 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 	u32 nval;
4743cfa11baSSteen Hegelund 
4753cfa11baSSteen Hegelund 	nval = readl(spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst,
4763cfa11baSSteen Hegelund 			       gcnt, gwidth, raddr, rinst, rcnt, rwidth));
4773cfa11baSSteen Hegelund 	nval = (nval & ~mask) | (val & mask);
4783cfa11baSSteen Hegelund 	writel(nval, spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst,
4793cfa11baSSteen Hegelund 			       gcnt, gwidth, raddr, rinst, rcnt, rwidth));
4803cfa11baSSteen Hegelund }
4813cfa11baSSteen Hegelund 
4823cfa11baSSteen Hegelund static inline void spx5_inst_rmw(u32 val, u32 mask, void __iomem *iomem,
4833cfa11baSSteen Hegelund 				 int id, int tinst, int tcnt,
4843cfa11baSSteen Hegelund 				 int gbase, int ginst, int gcnt, int gwidth,
4853cfa11baSSteen Hegelund 				 int raddr, int rinst, int rcnt, int rwidth)
4863cfa11baSSteen Hegelund {
4873cfa11baSSteen Hegelund 	u32 nval;
4883cfa11baSSteen Hegelund 
4893cfa11baSSteen Hegelund 	nval = readl(spx5_inst_addr(iomem, gbase, ginst, gcnt, gwidth, raddr,
4903cfa11baSSteen Hegelund 				    rinst, rcnt, rwidth));
4913cfa11baSSteen Hegelund 	nval = (nval & ~mask) | (val & mask);
4923cfa11baSSteen Hegelund 	writel(nval, spx5_inst_addr(iomem, gbase, ginst, gcnt, gwidth, raddr,
4933cfa11baSSteen Hegelund 				    rinst, rcnt, rwidth));
4943cfa11baSSteen Hegelund }
4953cfa11baSSteen Hegelund 
4963cfa11baSSteen Hegelund static inline void __iomem *spx5_inst_get(struct sparx5 *sparx5, int id, int tinst)
4973cfa11baSSteen Hegelund {
4983cfa11baSSteen Hegelund 	return sparx5->regs[id + tinst];
4993cfa11baSSteen Hegelund }
5003cfa11baSSteen Hegelund 
5013cfa11baSSteen Hegelund static inline void __iomem *spx5_reg_get(struct sparx5 *sparx5,
5023cfa11baSSteen Hegelund 					 int id, int tinst, int tcnt,
5033cfa11baSSteen Hegelund 					 int gbase, int ginst, int gcnt, int gwidth,
5043cfa11baSSteen Hegelund 					 int raddr, int rinst, int rcnt, int rwidth)
5053cfa11baSSteen Hegelund {
5063cfa11baSSteen Hegelund 	return spx5_addr(sparx5->regs, id, tinst, tcnt,
5073cfa11baSSteen Hegelund 			 gbase, ginst, gcnt, gwidth,
5083cfa11baSSteen Hegelund 			 raddr, rinst, rcnt, rwidth);
5093cfa11baSSteen Hegelund }
5103cfa11baSSteen Hegelund 
5113cfa11baSSteen Hegelund #endif	/* __SPARX5_MAIN_H__ */
512