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>
20e0305cc1SSteen Hegelund #include <linux/debugfs.h>
213cfa11baSSteen Hegelund 
2290d40252SCasper Andersson #include "sparx5_main_regs.h"
2390d40252SCasper Andersson 
243cfa11baSSteen Hegelund /* Target chip type */
253cfa11baSSteen Hegelund enum spx5_target_chiptype {
263cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7546    = 0x7546,  /* SparX-5-64  Enterprise */
273cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7549    = 0x7549,  /* SparX-5-90  Enterprise */
283cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7552    = 0x7552,  /* SparX-5-128 Enterprise */
293cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7556    = 0x7556,  /* SparX-5-160 Enterprise */
303cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7558    = 0x7558,  /* SparX-5-200 Enterprise */
313cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7546TSN = 0x47546, /* SparX-5-64i Industrial */
323cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7549TSN = 0x47549, /* SparX-5-90i Industrial */
333cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7552TSN = 0x47552, /* SparX-5-128i Industrial */
343cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7556TSN = 0x47556, /* SparX-5-160i Industrial */
353cfa11baSSteen Hegelund 	SPX5_TARGET_CT_7558TSN = 0x47558, /* SparX-5-200i Industrial */
363cfa11baSSteen Hegelund };
373cfa11baSSteen Hegelund 
383cfa11baSSteen Hegelund enum sparx5_port_max_tags {
393cfa11baSSteen Hegelund 	SPX5_PORT_MAX_TAGS_NONE,  /* No extra tags allowed */
403cfa11baSSteen Hegelund 	SPX5_PORT_MAX_TAGS_ONE,   /* Single tag allowed */
413cfa11baSSteen Hegelund 	SPX5_PORT_MAX_TAGS_TWO    /* Single and double tag allowed */
423cfa11baSSteen Hegelund };
433cfa11baSSteen Hegelund 
443cfa11baSSteen Hegelund enum sparx5_vlan_port_type {
453cfa11baSSteen Hegelund 	SPX5_VLAN_PORT_TYPE_UNAWARE, /* VLAN unaware port */
463cfa11baSSteen Hegelund 	SPX5_VLAN_PORT_TYPE_C,       /* C-port */
473cfa11baSSteen Hegelund 	SPX5_VLAN_PORT_TYPE_S,       /* S-port */
483cfa11baSSteen Hegelund 	SPX5_VLAN_PORT_TYPE_S_CUSTOM /* S-port using custom type */
493cfa11baSSteen Hegelund };
503cfa11baSSteen Hegelund 
513cfa11baSSteen Hegelund #define SPX5_PORTS             65
523cfa11baSSteen Hegelund #define SPX5_PORT_CPU          (SPX5_PORTS)  /* Next port is CPU port */
533cfa11baSSteen Hegelund #define SPX5_PORT_CPU_0        (SPX5_PORT_CPU + 0) /* CPU Port 65 */
543cfa11baSSteen Hegelund #define SPX5_PORT_CPU_1        (SPX5_PORT_CPU + 1) /* CPU Port 66 */
553cfa11baSSteen Hegelund #define SPX5_PORT_VD0          (SPX5_PORT_CPU + 2) /* VD0/Port 67 used for IPMC */
563cfa11baSSteen Hegelund #define SPX5_PORT_VD1          (SPX5_PORT_CPU + 3) /* VD1/Port 68 used for AFI/OAM */
573cfa11baSSteen Hegelund #define SPX5_PORT_VD2          (SPX5_PORT_CPU + 4) /* VD2/Port 69 used for IPinIP*/
583cfa11baSSteen Hegelund #define SPX5_PORTS_ALL         (SPX5_PORT_CPU + 5) /* Total number of ports */
593cfa11baSSteen Hegelund 
603cfa11baSSteen Hegelund #define PGID_BASE              SPX5_PORTS /* Starts after port PGIDs */
613cfa11baSSteen Hegelund #define PGID_UC_FLOOD          (PGID_BASE + 0)
623cfa11baSSteen Hegelund #define PGID_MC_FLOOD          (PGID_BASE + 1)
633cfa11baSSteen Hegelund #define PGID_IPV4_MC_DATA      (PGID_BASE + 2)
643cfa11baSSteen Hegelund #define PGID_IPV4_MC_CTRL      (PGID_BASE + 3)
653cfa11baSSteen Hegelund #define PGID_IPV6_MC_DATA      (PGID_BASE + 4)
663cfa11baSSteen Hegelund #define PGID_IPV6_MC_CTRL      (PGID_BASE + 5)
673cfa11baSSteen Hegelund #define PGID_BCAST	       (PGID_BASE + 6)
683cfa11baSSteen Hegelund #define PGID_CPU	       (PGID_BASE + 7)
69ad238fc6SCasper Andersson #define PGID_MCAST_START       (PGID_BASE + 8)
703cfa11baSSteen Hegelund 
71af9b45d0SCasper Andersson #define PGID_TABLE_SIZE	       3290
72af9b45d0SCasper Andersson 
733cfa11baSSteen Hegelund #define IFH_LEN                9 /* 36 bytes */
743cfa11baSSteen Hegelund #define NULL_VID               0
753cfa11baSSteen Hegelund #define SPX5_MACT_PULL_DELAY   (2 * HZ)
763cfa11baSSteen Hegelund #define SPX5_STATS_CHECK_DELAY (1 * HZ)
773cfa11baSSteen Hegelund #define SPX5_PRIOS             8     /* Number of priority queues */
783cfa11baSSteen Hegelund #define SPX5_BUFFER_CELL_SZ    184   /* Cell size  */
793cfa11baSSteen Hegelund #define SPX5_BUFFER_MEMORY     4194280 /* 22795 words * 184 bytes */
803cfa11baSSteen Hegelund 
81f3cad261SSteen Hegelund #define XTR_QUEUE     0
82f3cad261SSteen Hegelund #define INJ_QUEUE     0
83f3cad261SSteen Hegelund 
8410615907SSteen Hegelund #define FDMA_DCB_MAX			64
8510615907SSteen Hegelund #define FDMA_RX_DCB_MAX_DBS		15
8610615907SSteen Hegelund #define FDMA_TX_DCB_MAX_DBS		1
8710615907SSteen Hegelund 
880933bd04SHoratiu Vultur #define SPARX5_PHC_COUNT		3
890933bd04SHoratiu Vultur #define SPARX5_PHC_PORT			0
900933bd04SHoratiu Vultur 
91589a07b8SHoratiu Vultur #define IFH_REW_OP_NOOP			0x0
92589a07b8SHoratiu Vultur #define IFH_REW_OP_ONE_STEP_PTP		0x3
93589a07b8SHoratiu Vultur #define IFH_REW_OP_TWO_STEP_PTP		0x4
94589a07b8SHoratiu Vultur 
9570dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_NONE		0x0
9670dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_PTP		0x5
9770dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_IPV4_UDP_PTP	0x6
9870dfe25cSHoratiu Vultur #define IFH_PDU_TYPE_IPV6_UDP_PTP	0x7
9970dfe25cSHoratiu Vultur 
1003cfa11baSSteen Hegelund struct sparx5;
1013cfa11baSSteen Hegelund 
10210615907SSteen Hegelund struct sparx5_db_hw {
10310615907SSteen Hegelund 	u64 dataptr;
10410615907SSteen Hegelund 	u64 status;
10510615907SSteen Hegelund };
10610615907SSteen Hegelund 
10710615907SSteen Hegelund struct sparx5_rx_dcb_hw {
10810615907SSteen Hegelund 	u64 nextptr;
10910615907SSteen Hegelund 	u64 info;
11010615907SSteen Hegelund 	struct sparx5_db_hw db[FDMA_RX_DCB_MAX_DBS];
11110615907SSteen Hegelund };
11210615907SSteen Hegelund 
11310615907SSteen Hegelund struct sparx5_tx_dcb_hw {
11410615907SSteen Hegelund 	u64 nextptr;
11510615907SSteen Hegelund 	u64 info;
11610615907SSteen Hegelund 	struct sparx5_db_hw db[FDMA_TX_DCB_MAX_DBS];
11710615907SSteen Hegelund };
11810615907SSteen Hegelund 
11910615907SSteen Hegelund /* Frame DMA receive state:
12010615907SSteen Hegelund  * For each DB, there is a SKB, and the skb data pointer is mapped in
12110615907SSteen Hegelund  * the DB. Once a frame is received the skb is given to the upper layers
12210615907SSteen Hegelund  * and a new skb is added to the dcb.
12310615907SSteen Hegelund  * When the db_index reached FDMA_RX_DCB_MAX_DBS the DB is reused.
12410615907SSteen Hegelund  */
12510615907SSteen Hegelund struct sparx5_rx {
12610615907SSteen Hegelund 	struct sparx5_rx_dcb_hw *dcb_entries;
12710615907SSteen Hegelund 	struct sparx5_rx_dcb_hw *last_entry;
12810615907SSteen Hegelund 	struct sk_buff *skb[FDMA_DCB_MAX][FDMA_RX_DCB_MAX_DBS];
12910615907SSteen Hegelund 	int db_index;
13010615907SSteen Hegelund 	int dcb_index;
13110615907SSteen Hegelund 	dma_addr_t dma;
13210615907SSteen Hegelund 	struct napi_struct napi;
13310615907SSteen Hegelund 	u32 channel_id;
13410615907SSteen Hegelund 	struct net_device *ndev;
13510615907SSteen Hegelund 	u64 packets;
13610615907SSteen Hegelund };
13710615907SSteen Hegelund 
13810615907SSteen Hegelund /* Frame DMA transmit state:
13910615907SSteen Hegelund  * DCBs are chained using the DCBs nextptr field.
14010615907SSteen Hegelund  */
14110615907SSteen Hegelund struct sparx5_tx {
14210615907SSteen Hegelund 	struct sparx5_tx_dcb_hw *curr_entry;
14310615907SSteen Hegelund 	struct sparx5_tx_dcb_hw *first_entry;
14410615907SSteen Hegelund 	struct list_head db_list;
14510615907SSteen Hegelund 	dma_addr_t dma;
14610615907SSteen Hegelund 	u32 channel_id;
14710615907SSteen Hegelund 	u64 packets;
14810615907SSteen Hegelund 	u64 dropped;
14910615907SSteen Hegelund };
15010615907SSteen Hegelund 
1513cfa11baSSteen Hegelund struct sparx5_port_config {
1523cfa11baSSteen Hegelund 	phy_interface_t portmode;
1533cfa11baSSteen Hegelund 	u32 bandwidth;
1543cfa11baSSteen Hegelund 	int speed;
1553cfa11baSSteen Hegelund 	int duplex;
1563cfa11baSSteen Hegelund 	enum phy_media media;
1573cfa11baSSteen Hegelund 	bool inband;
1583cfa11baSSteen Hegelund 	bool power_down;
1593cfa11baSSteen Hegelund 	bool autoneg;
1603cfa11baSSteen Hegelund 	bool serdes_reset;
1613cfa11baSSteen Hegelund 	u32 pause;
1623cfa11baSSteen Hegelund 	u32 pause_adv;
1633cfa11baSSteen Hegelund 	phy_interface_t phy_mode;
1643cfa11baSSteen Hegelund 	u32 sd_sgpio;
1653cfa11baSSteen Hegelund };
1663cfa11baSSteen Hegelund 
1673cfa11baSSteen Hegelund struct sparx5_port {
1683cfa11baSSteen Hegelund 	struct net_device *ndev;
1693cfa11baSSteen Hegelund 	struct sparx5 *sparx5;
1703cfa11baSSteen Hegelund 	struct device_node *of_node;
1713cfa11baSSteen Hegelund 	struct phy *serdes;
1723cfa11baSSteen Hegelund 	struct sparx5_port_config conf;
173f3cad261SSteen Hegelund 	struct phylink_config phylink_config;
174f3cad261SSteen Hegelund 	struct phylink *phylink;
175f3cad261SSteen Hegelund 	struct phylink_pcs phylink_pcs;
1763cfa11baSSteen Hegelund 	u16 portno;
1773cfa11baSSteen Hegelund 	/* Ingress default VLAN (pvid) */
1783cfa11baSSteen Hegelund 	u16 pvid;
1793cfa11baSSteen Hegelund 	/* Egress default VLAN (vid) */
1803cfa11baSSteen Hegelund 	u16 vid;
1813cfa11baSSteen Hegelund 	bool signd_internal;
1823cfa11baSSteen Hegelund 	bool signd_active_high;
1833cfa11baSSteen Hegelund 	bool signd_enable;
1843cfa11baSSteen Hegelund 	bool flow_control;
1853cfa11baSSteen Hegelund 	enum sparx5_port_max_tags max_vlan_tags;
1863cfa11baSSteen Hegelund 	enum sparx5_vlan_port_type vlan_type;
1873cfa11baSSteen Hegelund 	u32 custom_etype;
1883cfa11baSSteen Hegelund 	bool vlan_aware;
189f3cad261SSteen Hegelund 	struct hrtimer inj_timer;
190589a07b8SHoratiu Vultur 	/* ptp */
191589a07b8SHoratiu Vultur 	u8 ptp_cmd;
19270dfe25cSHoratiu Vultur 	u16 ts_id;
19370dfe25cSHoratiu Vultur 	struct sk_buff_head tx_skbs;
19404e551d6SCasper Andersson 	bool is_mrouter;
1951c14432dSSteen Hegelund 	struct list_head tc_templates; /* list of TC templates on this port */
1963cfa11baSSteen Hegelund };
1973cfa11baSSteen Hegelund 
1983cfa11baSSteen Hegelund enum sparx5_core_clockfreq {
1993cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_DEFAULT,  /* Defaults to the highest supported frequency */
2003cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_250MHZ,   /* 250MHZ core clock frequency */
2013cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_500MHZ,   /* 500MHZ core clock frequency */
2023cfa11baSSteen Hegelund 	SPX5_CORE_CLOCK_625MHZ,   /* 625MHZ core clock frequency */
2033cfa11baSSteen Hegelund };
2043cfa11baSSteen Hegelund 
2050933bd04SHoratiu Vultur struct sparx5_phc {
2060933bd04SHoratiu Vultur 	struct ptp_clock *clock;
2070933bd04SHoratiu Vultur 	struct ptp_clock_info info;
2087bdde444SVladimir Oltean 	struct kernel_hwtstamp_config hwtstamp_config;
2090933bd04SHoratiu Vultur 	struct sparx5 *sparx5;
2100933bd04SHoratiu Vultur 	u8 index;
2110933bd04SHoratiu Vultur };
2120933bd04SHoratiu Vultur 
21370dfe25cSHoratiu Vultur struct sparx5_skb_cb {
21470dfe25cSHoratiu Vultur 	u8 rew_op;
21570dfe25cSHoratiu Vultur 	u8 pdu_type;
21670dfe25cSHoratiu Vultur 	u8 pdu_w16_offset;
21770dfe25cSHoratiu Vultur 	u16 ts_id;
21870dfe25cSHoratiu Vultur 	unsigned long jiffies;
21970dfe25cSHoratiu Vultur };
22070dfe25cSHoratiu Vultur 
221c8a3ea43SCasper Andersson struct sparx5_mdb_entry {
222c8a3ea43SCasper Andersson 	struct list_head list;
223c8a3ea43SCasper Andersson 	DECLARE_BITMAP(port_mask, SPX5_PORTS);
224c8a3ea43SCasper Andersson 	unsigned char addr[ETH_ALEN];
225c8a3ea43SCasper Andersson 	bool cpu_copy;
226c8a3ea43SCasper Andersson 	u16 vid;
227c8a3ea43SCasper Andersson 	u16 pgid_idx;
228c8a3ea43SCasper Andersson };
229c8a3ea43SCasper Andersson 
23070dfe25cSHoratiu Vultur #define SPARX5_PTP_TIMEOUT		msecs_to_jiffies(10)
23170dfe25cSHoratiu Vultur #define SPARX5_SKB_CB(skb) \
23270dfe25cSHoratiu Vultur 	((struct sparx5_skb_cb *)((skb)->cb))
23370dfe25cSHoratiu Vultur 
2343cfa11baSSteen Hegelund struct sparx5 {
2353cfa11baSSteen Hegelund 	struct platform_device *pdev;
2363cfa11baSSteen Hegelund 	struct device *dev;
2373cfa11baSSteen Hegelund 	u32 chip_id;
2383cfa11baSSteen Hegelund 	enum spx5_target_chiptype target_ct;
2393cfa11baSSteen Hegelund 	void __iomem *regs[NUM_TARGETS];
2403cfa11baSSteen Hegelund 	int port_count;
2413cfa11baSSteen Hegelund 	struct mutex lock; /* MAC reg lock */
2423cfa11baSSteen Hegelund 	/* port structures are in net device */
2433cfa11baSSteen Hegelund 	struct sparx5_port *ports[SPX5_PORTS];
2443cfa11baSSteen Hegelund 	enum sparx5_core_clockfreq coreclock;
245af4b1102SSteen Hegelund 	/* Statistics */
246af4b1102SSteen Hegelund 	u32 num_stats;
247af4b1102SSteen Hegelund 	u32 num_ethtool_stats;
248af4b1102SSteen Hegelund 	const char * const *stats_layout;
249af4b1102SSteen Hegelund 	u64 *stats;
250af4b1102SSteen Hegelund 	/* Workqueue for reading stats */
251af4b1102SSteen Hegelund 	struct mutex queue_stats_lock;
252af4b1102SSteen Hegelund 	struct delayed_work stats_work;
253af4b1102SSteen Hegelund 	struct workqueue_struct *stats_queue;
254d6fce514SSteen Hegelund 	/* Notifiers */
255d6fce514SSteen Hegelund 	struct notifier_block netdevice_nb;
256d6fce514SSteen Hegelund 	struct notifier_block switchdev_nb;
257d6fce514SSteen Hegelund 	struct notifier_block switchdev_blocking_nb;
258b37a1baeSSteen Hegelund 	/* Switch state */
2593cfa11baSSteen Hegelund 	u8 base_mac[ETH_ALEN];
260d6fce514SSteen Hegelund 	/* Associated bridge device (when bridged) */
261d6fce514SSteen Hegelund 	struct net_device *hw_bridge_dev;
26278eab33bSSteen Hegelund 	/* Bridged interfaces */
263d6fce514SSteen Hegelund 	DECLARE_BITMAP(bridge_mask, SPX5_PORTS);
26478eab33bSSteen Hegelund 	DECLARE_BITMAP(bridge_fwd_mask, SPX5_PORTS);
26578eab33bSSteen Hegelund 	DECLARE_BITMAP(bridge_lrn_mask, SPX5_PORTS);
26678eab33bSSteen Hegelund 	DECLARE_BITMAP(vlan_mask[VLAN_N_VID], SPX5_PORTS);
267b37a1baeSSteen Hegelund 	/* SW MAC table */
268b37a1baeSSteen Hegelund 	struct list_head mact_entries;
269b37a1baeSSteen Hegelund 	/* mac table list (mact_entries) mutex */
270b37a1baeSSteen Hegelund 	struct mutex mact_lock;
271c8a3ea43SCasper Andersson 	/* SW MDB table */
272c8a3ea43SCasper Andersson 	struct list_head mdb_entries;
273c8a3ea43SCasper Andersson 	/* mdb list mutex */
274c8a3ea43SCasper Andersson 	struct mutex mdb_lock;
275b37a1baeSSteen Hegelund 	struct delayed_work mact_work;
276b37a1baeSSteen Hegelund 	struct workqueue_struct *mact_queue;
2773cfa11baSSteen Hegelund 	/* Board specifics */
2783cfa11baSSteen Hegelund 	bool sd_sgpio_remapping;
279f3cad261SSteen Hegelund 	/* Register based inj/xtr */
280f3cad261SSteen Hegelund 	int xtr_irq;
28110615907SSteen Hegelund 	/* Frame DMA */
28210615907SSteen Hegelund 	int fdma_irq;
283*9adfd66bSHoratiu Vultur 	spinlock_t tx_lock; /* lock for frame transmission */
28410615907SSteen Hegelund 	struct sparx5_rx rx;
28510615907SSteen Hegelund 	struct sparx5_tx tx;
2860933bd04SHoratiu Vultur 	/* PTP */
2870933bd04SHoratiu Vultur 	bool ptp;
2880933bd04SHoratiu Vultur 	struct sparx5_phc phc[SPARX5_PHC_COUNT];
2890933bd04SHoratiu Vultur 	spinlock_t ptp_clock_lock; /* lock for phc */
29070dfe25cSHoratiu Vultur 	spinlock_t ptp_ts_id_lock; /* lock for ts_id */
291589a07b8SHoratiu Vultur 	struct mutex ptp_lock; /* lock for ptp interface state */
29270dfe25cSHoratiu Vultur 	u16 ptp_skbs;
293d31d3791SHoratiu Vultur 	int ptp_irq;
2948beef08fSSteen Hegelund 	/* VCAP */
2958beef08fSSteen Hegelund 	struct vcap_control *vcap_ctrl;
296af9b45d0SCasper Andersson 	/* PGID allocation map */
297af9b45d0SCasper Andersson 	u8 pgid_map[PGID_TABLE_SIZE];
298e0305cc1SSteen Hegelund 	/* Common root for debugfs */
299e0305cc1SSteen Hegelund 	struct dentry *debugfs_root;
3003cfa11baSSteen Hegelund };
3013cfa11baSSteen Hegelund 
302d6fce514SSteen Hegelund /* sparx5_switchdev.c */
303d6fce514SSteen Hegelund int sparx5_register_notifier_blocks(struct sparx5 *sparx5);
304d6fce514SSteen Hegelund void sparx5_unregister_notifier_blocks(struct sparx5 *sparx5);
305d6fce514SSteen Hegelund 
306f3cad261SSteen Hegelund /* sparx5_packet.c */
30710615907SSteen Hegelund struct frame_info {
30810615907SSteen Hegelund 	int src_port;
30970dfe25cSHoratiu Vultur 	u32 timestamp;
31010615907SSteen Hegelund };
31110615907SSteen Hegelund 
31210615907SSteen Hegelund void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp);
31310615907SSteen Hegelund void sparx5_ifh_parse(u32 *ifh, struct frame_info *info);
314f3cad261SSteen Hegelund irqreturn_t sparx5_xtr_handler(int irq, void *_priv);
31573ea7350SNathan Huckleberry netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev);
316f3cad261SSteen Hegelund int sparx5_manual_injection_mode(struct sparx5 *sparx5);
317f3cad261SSteen Hegelund void sparx5_port_inj_timer_setup(struct sparx5_port *port);
318f3cad261SSteen Hegelund 
31910615907SSteen Hegelund /* sparx5_fdma.c */
32010615907SSteen Hegelund int sparx5_fdma_start(struct sparx5 *sparx5);
32110615907SSteen Hegelund int sparx5_fdma_stop(struct sparx5 *sparx5);
32210615907SSteen Hegelund int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb);
32310615907SSteen Hegelund irqreturn_t sparx5_fdma_handler(int irq, void *args);
32410615907SSteen Hegelund 
325b37a1baeSSteen Hegelund /* sparx5_mactable.c */
326b37a1baeSSteen Hegelund void sparx5_mact_pull_work(struct work_struct *work);
327b37a1baeSSteen Hegelund int sparx5_mact_learn(struct sparx5 *sparx5, int port,
328b37a1baeSSteen Hegelund 		      const unsigned char mac[ETH_ALEN], u16 vid);
329b37a1baeSSteen Hegelund bool sparx5_mact_getnext(struct sparx5 *sparx5,
330b37a1baeSSteen Hegelund 			 unsigned char mac[ETH_ALEN], u16 *vid, u32 *pcfg2);
33175554fe0SCasper Andersson int sparx5_mact_find(struct sparx5 *sparx5,
3323bacfccdSCasper Andersson 		     const unsigned char mac[ETH_ALEN], u16 vid, u32 *pcfg2);
333b37a1baeSSteen Hegelund int sparx5_mact_forget(struct sparx5 *sparx5,
334b37a1baeSSteen Hegelund 		       const unsigned char mac[ETH_ALEN], u16 vid);
335b37a1baeSSteen Hegelund int sparx5_add_mact_entry(struct sparx5 *sparx5,
3369f01cfbfSCasper Andersson 			  struct net_device *dev,
3379f01cfbfSCasper Andersson 			  u16 portno,
338b37a1baeSSteen Hegelund 			  const unsigned char *addr, u16 vid);
339b37a1baeSSteen Hegelund int sparx5_del_mact_entry(struct sparx5 *sparx5,
340b37a1baeSSteen Hegelund 			  const unsigned char *addr,
341b37a1baeSSteen Hegelund 			  u16 vid);
342b37a1baeSSteen Hegelund int sparx5_mc_sync(struct net_device *dev, const unsigned char *addr);
343b37a1baeSSteen Hegelund int sparx5_mc_unsync(struct net_device *dev, const unsigned char *addr);
344b37a1baeSSteen Hegelund void sparx5_set_ageing(struct sparx5 *sparx5, int msecs);
345b37a1baeSSteen Hegelund void sparx5_mact_init(struct sparx5 *sparx5);
346b37a1baeSSteen Hegelund 
34778eab33bSSteen Hegelund /* sparx5_vlan.c */
34878eab33bSSteen Hegelund void sparx5_pgid_update_mask(struct sparx5_port *port, int pgid, bool enable);
34904e551d6SCasper Andersson void sparx5_pgid_clear(struct sparx5 *spx5, int pgid);
350ad238fc6SCasper Andersson void sparx5_pgid_read_mask(struct sparx5 *sparx5, int pgid, u32 portmask[3]);
35178eab33bSSteen Hegelund void sparx5_update_fwd(struct sparx5 *sparx5);
35278eab33bSSteen Hegelund void sparx5_vlan_init(struct sparx5 *sparx5);
35378eab33bSSteen Hegelund void sparx5_vlan_port_setup(struct sparx5 *sparx5, int portno);
35478eab33bSSteen Hegelund int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid,
35578eab33bSSteen Hegelund 			bool untagged);
35678eab33bSSteen Hegelund int sparx5_vlan_vid_del(struct sparx5_port *port, u16 vid);
35778eab33bSSteen Hegelund void sparx5_vlan_port_apply(struct sparx5 *sparx5, struct sparx5_port *port);
35878eab33bSSteen Hegelund 
3590a9d48adSSteen Hegelund /* sparx5_calendar.c */
3600a9d48adSSteen Hegelund int sparx5_config_auto_calendar(struct sparx5 *sparx5);
3610a9d48adSSteen Hegelund int sparx5_config_dsm_calendar(struct sparx5 *sparx5);
3620a9d48adSSteen Hegelund 
363af4b1102SSteen Hegelund /* sparx5_ethtool.c */
364af4b1102SSteen Hegelund void sparx5_get_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats);
365af4b1102SSteen Hegelund int sparx_stats_init(struct sparx5 *sparx5);
366af4b1102SSteen Hegelund 
36792ef3d01SDaniel Machon /* sparx5_dcb.c */
36892ef3d01SDaniel Machon #ifdef CONFIG_SPARX5_DCB
36992ef3d01SDaniel Machon int sparx5_dcb_init(struct sparx5 *sparx5);
37092ef3d01SDaniel Machon #else
sparx5_dcb_init(struct sparx5 * sparx5)37192ef3d01SDaniel Machon static inline int sparx5_dcb_init(struct sparx5 *sparx5)
37292ef3d01SDaniel Machon {
37392ef3d01SDaniel Machon 	return 0;
37492ef3d01SDaniel Machon }
37592ef3d01SDaniel Machon #endif
37692ef3d01SDaniel Machon 
377f3cad261SSteen Hegelund /* sparx5_netdev.c */
37870dfe25cSHoratiu Vultur void sparx5_set_port_ifh_timestamp(void *ifh_hdr, u64 timestamp);
37970dfe25cSHoratiu Vultur void sparx5_set_port_ifh_rew_op(void *ifh_hdr, u32 rew_op);
38070dfe25cSHoratiu Vultur void sparx5_set_port_ifh_pdu_type(void *ifh_hdr, u32 pdu_type);
38170dfe25cSHoratiu Vultur void sparx5_set_port_ifh_pdu_w16_offset(void *ifh_hdr, u32 pdu_w16_offset);
3828f68f53aSHoratiu Vultur void sparx5_set_port_ifh(void *ifh_hdr, u16 portno);
383f3cad261SSteen Hegelund bool sparx5_netdevice_check(const struct net_device *dev);
384f3cad261SSteen Hegelund struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno);
385f3cad261SSteen Hegelund int sparx5_register_netdevs(struct sparx5 *sparx5);
386f3cad261SSteen Hegelund void sparx5_destroy_netdevs(struct sparx5 *sparx5);
387f3cad261SSteen Hegelund void sparx5_unregister_netdevs(struct sparx5 *sparx5);
388f3cad261SSteen Hegelund 
3890933bd04SHoratiu Vultur /* sparx5_ptp.c */
3900933bd04SHoratiu Vultur int sparx5_ptp_init(struct sparx5 *sparx5);
3910933bd04SHoratiu Vultur void sparx5_ptp_deinit(struct sparx5 *sparx5);
3927bdde444SVladimir Oltean int sparx5_ptp_hwtstamp_set(struct sparx5_port *port,
3937bdde444SVladimir Oltean 			    struct kernel_hwtstamp_config *cfg,
3947bdde444SVladimir Oltean 			    struct netlink_ext_ack *extack);
3957bdde444SVladimir Oltean void sparx5_ptp_hwtstamp_get(struct sparx5_port *port,
3967bdde444SVladimir Oltean 			     struct kernel_hwtstamp_config *cfg);
39770dfe25cSHoratiu Vultur void sparx5_ptp_rxtstamp(struct sparx5 *sparx5, struct sk_buff *skb,
39870dfe25cSHoratiu Vultur 			 u64 timestamp);
39970dfe25cSHoratiu Vultur int sparx5_ptp_txtstamp_request(struct sparx5_port *port,
40070dfe25cSHoratiu Vultur 				struct sk_buff *skb);
40170dfe25cSHoratiu Vultur void sparx5_ptp_txtstamp_release(struct sparx5_port *port,
40270dfe25cSHoratiu Vultur 				 struct sk_buff *skb);
403d31d3791SHoratiu Vultur irqreturn_t sparx5_ptp_irq_handler(int irq, void *args);
4049e02131eSDaniel Machon int sparx5_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts);
4050933bd04SHoratiu Vultur 
4068beef08fSSteen Hegelund /* sparx5_vcap_impl.c */
4078beef08fSSteen Hegelund int sparx5_vcap_init(struct sparx5 *sparx5);
4088beef08fSSteen Hegelund void sparx5_vcap_destroy(struct sparx5 *sparx5);
4098beef08fSSteen Hegelund 
410af9b45d0SCasper Andersson /* sparx5_pgid.c */
411af9b45d0SCasper Andersson enum sparx5_pgid_type {
412af9b45d0SCasper Andersson 	SPX5_PGID_FREE,
413af9b45d0SCasper Andersson 	SPX5_PGID_RESERVED,
414af9b45d0SCasper Andersson 	SPX5_PGID_MULTICAST,
415af9b45d0SCasper Andersson };
416af9b45d0SCasper Andersson 
417af9b45d0SCasper Andersson void sparx5_pgid_init(struct sparx5 *spx5);
418af9b45d0SCasper Andersson int sparx5_pgid_alloc_mcast(struct sparx5 *spx5, u16 *idx);
419af9b45d0SCasper Andersson int sparx5_pgid_free(struct sparx5 *spx5, u16 idx);
420af9b45d0SCasper Andersson 
421bb535c0dSDaniel Machon /* sparx5_pool.c */
422bb535c0dSDaniel Machon struct sparx5_pool_entry {
423bb535c0dSDaniel Machon 	u16 ref_cnt;
424bb535c0dSDaniel Machon 	u32 idx; /* tc index */
425bb535c0dSDaniel Machon };
426bb535c0dSDaniel Machon 
427bb535c0dSDaniel Machon u32 sparx5_pool_idx_to_id(u32 idx);
428bb535c0dSDaniel Machon int sparx5_pool_put(struct sparx5_pool_entry *pool, int size, u32 id);
429bb535c0dSDaniel Machon int sparx5_pool_get(struct sparx5_pool_entry *pool, int size, u32 *id);
430bb535c0dSDaniel Machon int sparx5_pool_get_with_idx(struct sparx5_pool_entry *pool, int size, u32 idx,
431bb535c0dSDaniel Machon 			     u32 *id);
432bb535c0dSDaniel Machon 
4339bf50889SDaniel Machon /* sparx5_sdlb.c */
4349bf50889SDaniel Machon #define SPX5_SDLB_PUP_TOKEN_DISABLE 0x1FFF
4359bf50889SDaniel Machon #define SPX5_SDLB_PUP_TOKEN_MAX (SPX5_SDLB_PUP_TOKEN_DISABLE - 1)
4369bf50889SDaniel Machon #define SPX5_SDLB_GROUP_RATE_MAX 25000000000ULL
4379bf50889SDaniel Machon #define SPX5_SDLB_2CYCLES_TYPE2_THRES_OFFSET 13
4389bf50889SDaniel Machon #define SPX5_SDLB_CNT 4096
4399bf50889SDaniel Machon #define SPX5_SDLB_GROUP_CNT 10
4409bf50889SDaniel Machon #define SPX5_CLK_PER_100PS_DEFAULT 16
4419bf50889SDaniel Machon 
4429bf50889SDaniel Machon struct sparx5_sdlb_group {
4439bf50889SDaniel Machon 	u64 max_rate;
4449bf50889SDaniel Machon 	u32 min_burst;
4459bf50889SDaniel Machon 	u32 frame_size;
4469bf50889SDaniel Machon 	u32 pup_interval;
4479bf50889SDaniel Machon 	u32 nsets;
4489bf50889SDaniel Machon };
4499bf50889SDaniel Machon 
4509bf50889SDaniel Machon extern struct sparx5_sdlb_group sdlb_groups[SPX5_SDLB_GROUP_CNT];
4519bf50889SDaniel Machon int sparx5_sdlb_pup_token_get(struct sparx5 *sparx5, u32 pup_interval,
4529bf50889SDaniel Machon 			      u64 rate);
4539bf50889SDaniel Machon 
4549bf50889SDaniel Machon int sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5);
4559bf50889SDaniel Machon int sparx5_sdlb_group_get_by_rate(struct sparx5 *sparx5, u32 rate, u32 burst);
4569bf50889SDaniel Machon int sparx5_sdlb_group_get_by_index(struct sparx5 *sparx5, u32 idx, u32 *group);
4579bf50889SDaniel Machon 
4589bf50889SDaniel Machon int sparx5_sdlb_group_add(struct sparx5 *sparx5, u32 group, u32 idx);
4599bf50889SDaniel Machon int sparx5_sdlb_group_del(struct sparx5 *sparx5, u32 group, u32 idx);
4609bf50889SDaniel Machon 
4619bf50889SDaniel Machon void sparx5_sdlb_group_init(struct sparx5 *sparx5, u64 max_rate, u32 min_burst,
4629bf50889SDaniel Machon 			    u32 frame_size, u32 idx);
463e116b19dSDaniel Machon 
4641db82abfSDaniel Machon /* sparx5_police.c */
4651db82abfSDaniel Machon enum {
4661db82abfSDaniel Machon 	/* More policer types will be added later */
4671db82abfSDaniel Machon 	SPX5_POL_SERVICE
4681db82abfSDaniel Machon };
4691db82abfSDaniel Machon 
4701db82abfSDaniel Machon struct sparx5_policer {
4711db82abfSDaniel Machon 	u32 type;
4721db82abfSDaniel Machon 	u32 idx;
4731db82abfSDaniel Machon 	u64 rate;
4741db82abfSDaniel Machon 	u32 burst;
4751db82abfSDaniel Machon 	u32 group;
4761db82abfSDaniel Machon 	u8 event_mask;
4771db82abfSDaniel Machon };
4781db82abfSDaniel Machon 
4791db82abfSDaniel Machon int sparx5_policer_conf_set(struct sparx5 *sparx5, struct sparx5_policer *pol);
4809bf50889SDaniel Machon 
481d2185e79SDaniel Machon /* sparx5_psfp.c */
482c70a5e2cSDaniel Machon #define SPX5_PSFP_GCE_CNT 4
483c70a5e2cSDaniel Machon #define SPX5_PSFP_SG_CNT 1024
484c70a5e2cSDaniel Machon #define SPX5_PSFP_SG_MIN_CYCLE_TIME_NS (1 * NSEC_PER_USEC)
485c70a5e2cSDaniel Machon #define SPX5_PSFP_SG_MAX_CYCLE_TIME_NS ((1 * NSEC_PER_SEC) - 1)
486c70a5e2cSDaniel Machon #define SPX5_PSFP_SG_MAX_IPV (SPX5_PRIOS - 1)
487c70a5e2cSDaniel Machon #define SPX5_PSFP_SG_OPEN (SPX5_PSFP_SG_CNT - 1)
488c70a5e2cSDaniel Machon #define SPX5_PSFP_SG_CYCLE_TIME_DEFAULT 1000000
489c70a5e2cSDaniel Machon #define SPX5_PSFP_SF_MAX_SDU 16383
490c70a5e2cSDaniel Machon 
491d2185e79SDaniel Machon struct sparx5_psfp_fm {
492d2185e79SDaniel Machon 	struct sparx5_policer pol;
493d2185e79SDaniel Machon };
494d2185e79SDaniel Machon 
495c70a5e2cSDaniel Machon struct sparx5_psfp_gce {
496c70a5e2cSDaniel Machon 	bool gate_state;            /* StreamGateState */
497c70a5e2cSDaniel Machon 	u32 interval;               /* TimeInterval */
498c70a5e2cSDaniel Machon 	u32 ipv;                    /* InternalPriorityValue */
499c70a5e2cSDaniel Machon 	u32 maxoctets;              /* IntervalOctetMax */
500c70a5e2cSDaniel Machon };
501c70a5e2cSDaniel Machon 
502c70a5e2cSDaniel Machon struct sparx5_psfp_sg {
503c70a5e2cSDaniel Machon 	bool gate_state;            /* PSFPAdminGateStates */
504c70a5e2cSDaniel Machon 	bool gate_enabled;          /* PSFPGateEnabled */
505c70a5e2cSDaniel Machon 	u32 ipv;                    /* PSFPAdminIPV */
506c70a5e2cSDaniel Machon 	struct timespec64 basetime; /* PSFPAdminBaseTime */
507c70a5e2cSDaniel Machon 	u32 cycletime;              /* PSFPAdminCycleTime */
508c70a5e2cSDaniel Machon 	u32 cycletimeext;           /* PSFPAdminCycleTimeExtension */
509c70a5e2cSDaniel Machon 	u32 num_entries;            /* PSFPAdminControlListLength */
510c70a5e2cSDaniel Machon 	struct sparx5_psfp_gce gce[SPX5_PSFP_GCE_CNT];
511c70a5e2cSDaniel Machon };
512c70a5e2cSDaniel Machon 
513ae3e691fSDaniel Machon struct sparx5_psfp_sf {
514ae3e691fSDaniel Machon 	bool sblock_osize_ena;
515ae3e691fSDaniel Machon 	bool sblock_osize;
516ae3e691fSDaniel Machon 	u32 max_sdu;
517ae3e691fSDaniel Machon 	u32 sgid; /* Gate id */
518ae3e691fSDaniel Machon 	u32 fmid; /* Flow meter id */
519ae3e691fSDaniel Machon };
520ae3e691fSDaniel Machon 
521d2185e79SDaniel Machon int sparx5_psfp_fm_add(struct sparx5 *sparx5, u32 uidx,
522d2185e79SDaniel Machon 		       struct sparx5_psfp_fm *fm, u32 *id);
523d2185e79SDaniel Machon int sparx5_psfp_fm_del(struct sparx5 *sparx5, u32 id);
524d2185e79SDaniel Machon 
525c70a5e2cSDaniel Machon int sparx5_psfp_sg_add(struct sparx5 *sparx5, u32 uidx,
526c70a5e2cSDaniel Machon 		       struct sparx5_psfp_sg *sg, u32 *id);
527c70a5e2cSDaniel Machon int sparx5_psfp_sg_del(struct sparx5 *sparx5, u32 id);
528c70a5e2cSDaniel Machon 
529ae3e691fSDaniel Machon int sparx5_psfp_sf_add(struct sparx5 *sparx5, const struct sparx5_psfp_sf *sf,
530ae3e691fSDaniel Machon 		       u32 *id);
531ae3e691fSDaniel Machon int sparx5_psfp_sf_del(struct sparx5 *sparx5, u32 id);
532ae3e691fSDaniel Machon 
533ae3e691fSDaniel Machon u32 sparx5_psfp_isdx_get_sf(struct sparx5 *sparx5, u32 isdx);
534ae3e691fSDaniel Machon u32 sparx5_psfp_isdx_get_fm(struct sparx5 *sparx5, u32 isdx);
535ae3e691fSDaniel Machon u32 sparx5_psfp_sf_get_sg(struct sparx5 *sparx5, u32 sfid);
536ae3e691fSDaniel Machon void sparx5_isdx_conf_set(struct sparx5 *sparx5, u32 isdx, u32 sfid, u32 fmid);
537ae3e691fSDaniel Machon 
538e116b19dSDaniel Machon void sparx5_psfp_init(struct sparx5 *sparx5);
539e116b19dSDaniel Machon 
5409e02131eSDaniel Machon /* sparx5_qos.c */
5419e02131eSDaniel Machon void sparx5_new_base_time(struct sparx5 *sparx5, const u32 cycle_time,
5429e02131eSDaniel Machon 			  const ktime_t org_base_time, ktime_t *new_base_time);
5439e02131eSDaniel Machon 
5443cfa11baSSteen Hegelund /* Clock period in picoseconds */
sparx5_clk_period(enum sparx5_core_clockfreq cclock)5453cfa11baSSteen Hegelund static inline u32 sparx5_clk_period(enum sparx5_core_clockfreq cclock)
5463cfa11baSSteen Hegelund {
5473cfa11baSSteen Hegelund 	switch (cclock) {
5483cfa11baSSteen Hegelund 	case SPX5_CORE_CLOCK_250MHZ:
5493cfa11baSSteen Hegelund 		return 4000;
5503cfa11baSSteen Hegelund 	case SPX5_CORE_CLOCK_500MHZ:
5513cfa11baSSteen Hegelund 		return 2000;
5523cfa11baSSteen Hegelund 	case SPX5_CORE_CLOCK_625MHZ:
5533cfa11baSSteen Hegelund 	default:
5543cfa11baSSteen Hegelund 		return 1600;
5553cfa11baSSteen Hegelund 	}
5563cfa11baSSteen Hegelund }
5573cfa11baSSteen Hegelund 
sparx5_is_baser(phy_interface_t interface)558f3cad261SSteen Hegelund static inline bool sparx5_is_baser(phy_interface_t interface)
559f3cad261SSteen Hegelund {
560f3cad261SSteen Hegelund 	return interface == PHY_INTERFACE_MODE_5GBASER ||
561f3cad261SSteen Hegelund 		   interface == PHY_INTERFACE_MODE_10GBASER ||
562f3cad261SSteen Hegelund 		   interface == PHY_INTERFACE_MODE_25GBASER;
563f3cad261SSteen Hegelund }
564f3cad261SSteen Hegelund 
565f3cad261SSteen Hegelund extern const struct phylink_mac_ops sparx5_phylink_mac_ops;
566f3cad261SSteen Hegelund extern const struct phylink_pcs_ops sparx5_phylink_pcs_ops;
567af4b1102SSteen Hegelund extern const struct ethtool_ops sparx5_ethtool_ops;
56892ef3d01SDaniel Machon extern const struct dcbnl_rtnl_ops sparx5_dcbnl_ops;
569f3cad261SSteen Hegelund 
5703cfa11baSSteen Hegelund /* Calculate raw offset */
spx5_offset(int id,int tinst,int tcnt,int gbase,int ginst,int gcnt,int gwidth,int raddr,int rinst,int rcnt,int rwidth)5713cfa11baSSteen Hegelund static inline __pure int spx5_offset(int id, int tinst, int tcnt,
5723cfa11baSSteen Hegelund 				     int gbase, int ginst,
5733cfa11baSSteen Hegelund 				     int gcnt, int gwidth,
5743cfa11baSSteen Hegelund 				     int raddr, int rinst,
5753cfa11baSSteen Hegelund 				     int rcnt, int rwidth)
5763cfa11baSSteen Hegelund {
5773cfa11baSSteen Hegelund 	WARN_ON((tinst) >= tcnt);
5783cfa11baSSteen Hegelund 	WARN_ON((ginst) >= gcnt);
5793cfa11baSSteen Hegelund 	WARN_ON((rinst) >= rcnt);
5803cfa11baSSteen Hegelund 	return gbase + ((ginst) * gwidth) +
5813cfa11baSSteen Hegelund 		raddr + ((rinst) * rwidth);
5823cfa11baSSteen Hegelund }
5833cfa11baSSteen Hegelund 
5843cfa11baSSteen Hegelund /* Read, Write and modify registers content.
5853cfa11baSSteen Hegelund  * The register definition macros start at the id
5863cfa11baSSteen Hegelund  */
spx5_addr(void __iomem * base[],int id,int tinst,int tcnt,int gbase,int ginst,int gcnt,int gwidth,int raddr,int rinst,int rcnt,int rwidth)5873cfa11baSSteen Hegelund static inline void __iomem *spx5_addr(void __iomem *base[],
5883cfa11baSSteen Hegelund 				      int id, int tinst, int tcnt,
5893cfa11baSSteen Hegelund 				      int gbase, int ginst,
5903cfa11baSSteen Hegelund 				      int gcnt, int gwidth,
5913cfa11baSSteen Hegelund 				      int raddr, int rinst,
5923cfa11baSSteen Hegelund 				      int rcnt, int rwidth)
5933cfa11baSSteen Hegelund {
5943cfa11baSSteen Hegelund 	WARN_ON((tinst) >= tcnt);
5953cfa11baSSteen Hegelund 	WARN_ON((ginst) >= gcnt);
5963cfa11baSSteen Hegelund 	WARN_ON((rinst) >= rcnt);
5973cfa11baSSteen Hegelund 	return base[id + (tinst)] +
5983cfa11baSSteen Hegelund 		gbase + ((ginst) * gwidth) +
5993cfa11baSSteen Hegelund 		raddr + ((rinst) * rwidth);
6003cfa11baSSteen Hegelund }
6013cfa11baSSteen Hegelund 
spx5_inst_addr(void __iomem * base,int gbase,int ginst,int gcnt,int gwidth,int raddr,int rinst,int rcnt,int rwidth)6023cfa11baSSteen Hegelund static inline void __iomem *spx5_inst_addr(void __iomem *base,
6033cfa11baSSteen Hegelund 					   int gbase, int ginst,
6043cfa11baSSteen Hegelund 					   int gcnt, int gwidth,
6053cfa11baSSteen Hegelund 					   int raddr, int rinst,
6063cfa11baSSteen Hegelund 					   int rcnt, int rwidth)
6073cfa11baSSteen Hegelund {
6083cfa11baSSteen Hegelund 	WARN_ON((ginst) >= gcnt);
6093cfa11baSSteen Hegelund 	WARN_ON((rinst) >= rcnt);
6103cfa11baSSteen Hegelund 	return base +
6113cfa11baSSteen Hegelund 		gbase + ((ginst) * gwidth) +
6123cfa11baSSteen Hegelund 		raddr + ((rinst) * rwidth);
6133cfa11baSSteen Hegelund }
6143cfa11baSSteen Hegelund 
spx5_rd(struct sparx5 * sparx5,int id,int tinst,int tcnt,int gbase,int ginst,int gcnt,int gwidth,int raddr,int rinst,int rcnt,int rwidth)6153cfa11baSSteen Hegelund static inline u32 spx5_rd(struct sparx5 *sparx5, int id, int tinst, int tcnt,
6163cfa11baSSteen Hegelund 			  int gbase, int ginst, int gcnt, int gwidth,
6173cfa11baSSteen Hegelund 			  int raddr, int rinst, int rcnt, int rwidth)
6183cfa11baSSteen Hegelund {
6193cfa11baSSteen Hegelund 	return readl(spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst,
6203cfa11baSSteen Hegelund 			       gcnt, gwidth, raddr, rinst, rcnt, rwidth));
6213cfa11baSSteen Hegelund }
6223cfa11baSSteen Hegelund 
spx5_inst_rd(void __iomem * iomem,int id,int tinst,int tcnt,int gbase,int ginst,int gcnt,int gwidth,int raddr,int rinst,int rcnt,int rwidth)6233cfa11baSSteen Hegelund static inline u32 spx5_inst_rd(void __iomem *iomem, int id, int tinst, int tcnt,
6243cfa11baSSteen Hegelund 			       int gbase, int ginst, int gcnt, int gwidth,
6253cfa11baSSteen Hegelund 			       int raddr, int rinst, int rcnt, int rwidth)
6263cfa11baSSteen Hegelund {
6273cfa11baSSteen Hegelund 	return readl(spx5_inst_addr(iomem, gbase, ginst,
6283cfa11baSSteen Hegelund 				     gcnt, gwidth, raddr, rinst, rcnt, rwidth));
6293cfa11baSSteen Hegelund }
6303cfa11baSSteen Hegelund 
spx5_wr(u32 val,struct sparx5 * sparx5,int id,int tinst,int tcnt,int gbase,int ginst,int gcnt,int gwidth,int raddr,int rinst,int rcnt,int rwidth)6313cfa11baSSteen Hegelund static inline void spx5_wr(u32 val, struct sparx5 *sparx5,
6323cfa11baSSteen Hegelund 			   int id, int tinst, int tcnt,
6333cfa11baSSteen Hegelund 			   int gbase, int ginst, int gcnt, int gwidth,
6343cfa11baSSteen Hegelund 			   int raddr, int rinst, int rcnt, int rwidth)
6353cfa11baSSteen Hegelund {
6363cfa11baSSteen Hegelund 	writel(val, spx5_addr(sparx5->regs, id, tinst, tcnt,
6373cfa11baSSteen Hegelund 			      gbase, ginst, gcnt, gwidth,
6383cfa11baSSteen Hegelund 			      raddr, rinst, rcnt, rwidth));
6393cfa11baSSteen Hegelund }
6403cfa11baSSteen Hegelund 
spx5_inst_wr(u32 val,void __iomem * iomem,int id,int tinst,int tcnt,int gbase,int ginst,int gcnt,int gwidth,int raddr,int rinst,int rcnt,int rwidth)6413cfa11baSSteen Hegelund static inline void spx5_inst_wr(u32 val, void __iomem *iomem,
6423cfa11baSSteen Hegelund 				int id, int tinst, int tcnt,
6433cfa11baSSteen Hegelund 				int gbase, int ginst, int gcnt, int gwidth,
6443cfa11baSSteen Hegelund 				int raddr, int rinst, int rcnt, int rwidth)
6453cfa11baSSteen Hegelund {
6463cfa11baSSteen Hegelund 	writel(val, spx5_inst_addr(iomem,
6473cfa11baSSteen Hegelund 				   gbase, ginst, gcnt, gwidth,
6483cfa11baSSteen Hegelund 				   raddr, rinst, rcnt, rwidth));
6493cfa11baSSteen Hegelund }
6503cfa11baSSteen Hegelund 
spx5_rmw(u32 val,u32 mask,struct sparx5 * sparx5,int id,int tinst,int tcnt,int gbase,int ginst,int gcnt,int gwidth,int raddr,int rinst,int rcnt,int rwidth)6513cfa11baSSteen Hegelund static inline void spx5_rmw(u32 val, u32 mask, struct sparx5 *sparx5,
6523cfa11baSSteen Hegelund 			    int id, int tinst, int tcnt,
6533cfa11baSSteen Hegelund 			    int gbase, int ginst, int gcnt, int gwidth,
6543cfa11baSSteen Hegelund 			    int raddr, int rinst, int rcnt, int rwidth)
6553cfa11baSSteen Hegelund {
6563cfa11baSSteen Hegelund 	u32 nval;
6573cfa11baSSteen Hegelund 
6583cfa11baSSteen Hegelund 	nval = readl(spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst,
6593cfa11baSSteen Hegelund 			       gcnt, gwidth, raddr, rinst, rcnt, rwidth));
6603cfa11baSSteen Hegelund 	nval = (nval & ~mask) | (val & mask);
6613cfa11baSSteen Hegelund 	writel(nval, spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst,
6623cfa11baSSteen Hegelund 			       gcnt, gwidth, raddr, rinst, rcnt, rwidth));
6633cfa11baSSteen Hegelund }
6643cfa11baSSteen Hegelund 
spx5_inst_rmw(u32 val,u32 mask,void __iomem * iomem,int id,int tinst,int tcnt,int gbase,int ginst,int gcnt,int gwidth,int raddr,int rinst,int rcnt,int rwidth)6653cfa11baSSteen Hegelund static inline void spx5_inst_rmw(u32 val, u32 mask, void __iomem *iomem,
6663cfa11baSSteen Hegelund 				 int id, int tinst, int tcnt,
6673cfa11baSSteen Hegelund 				 int gbase, int ginst, int gcnt, int gwidth,
6683cfa11baSSteen Hegelund 				 int raddr, int rinst, int rcnt, int rwidth)
6693cfa11baSSteen Hegelund {
6703cfa11baSSteen Hegelund 	u32 nval;
6713cfa11baSSteen Hegelund 
6723cfa11baSSteen Hegelund 	nval = readl(spx5_inst_addr(iomem, gbase, ginst, gcnt, gwidth, raddr,
6733cfa11baSSteen Hegelund 				    rinst, rcnt, rwidth));
6743cfa11baSSteen Hegelund 	nval = (nval & ~mask) | (val & mask);
6753cfa11baSSteen Hegelund 	writel(nval, spx5_inst_addr(iomem, gbase, ginst, gcnt, gwidth, raddr,
6763cfa11baSSteen Hegelund 				    rinst, rcnt, rwidth));
6773cfa11baSSteen Hegelund }
6783cfa11baSSteen Hegelund 
spx5_inst_get(struct sparx5 * sparx5,int id,int tinst)6793cfa11baSSteen Hegelund static inline void __iomem *spx5_inst_get(struct sparx5 *sparx5, int id, int tinst)
6803cfa11baSSteen Hegelund {
6813cfa11baSSteen Hegelund 	return sparx5->regs[id + tinst];
6823cfa11baSSteen Hegelund }
6833cfa11baSSteen Hegelund 
spx5_reg_get(struct sparx5 * sparx5,int id,int tinst,int tcnt,int gbase,int ginst,int gcnt,int gwidth,int raddr,int rinst,int rcnt,int rwidth)6843cfa11baSSteen Hegelund static inline void __iomem *spx5_reg_get(struct sparx5 *sparx5,
6853cfa11baSSteen Hegelund 					 int id, int tinst, int tcnt,
6863cfa11baSSteen Hegelund 					 int gbase, int ginst, int gcnt, int gwidth,
6873cfa11baSSteen Hegelund 					 int raddr, int rinst, int rcnt, int rwidth)
6883cfa11baSSteen Hegelund {
6893cfa11baSSteen Hegelund 	return spx5_addr(sparx5->regs, id, tinst, tcnt,
6903cfa11baSSteen Hegelund 			 gbase, ginst, gcnt, gwidth,
6913cfa11baSSteen Hegelund 			 raddr, rinst, rcnt, rwidth);
6923cfa11baSSteen Hegelund }
6933cfa11baSSteen Hegelund 
6943cfa11baSSteen Hegelund #endif	/* __SPARX5_MAIN_H__ */
695