162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * drivers/net/ethernet/ibm/emac/mal.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Memory Access Layer (MAL) support
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
862306a36Sopenharmony_ci *                <benh@kernel.crashing.org>
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * Based on the arch/ppc version of the driver:
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * Copyright (c) 2004, 2005 Zultys Technologies.
1362306a36Sopenharmony_ci * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
1462306a36Sopenharmony_ci *
1562306a36Sopenharmony_ci * Based on original work by
1662306a36Sopenharmony_ci *      Armin Kuster <akuster@mvista.com>
1762306a36Sopenharmony_ci *      Copyright 2002 MontaVista Softare Inc.
1862306a36Sopenharmony_ci */
1962306a36Sopenharmony_ci#ifndef __IBM_NEWEMAC_MAL_H
2062306a36Sopenharmony_ci#define __IBM_NEWEMAC_MAL_H
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/*
2362306a36Sopenharmony_ci * There are some variations on the MAL, we express them in this driver as
2462306a36Sopenharmony_ci * MAL Version 1 and 2 though that doesn't match any IBM terminology.
2562306a36Sopenharmony_ci *
2662306a36Sopenharmony_ci * We call MAL 1 the version in 405GP, 405GPR, 405EP, 440EP, 440GR and
2762306a36Sopenharmony_ci * NP405H.
2862306a36Sopenharmony_ci *
2962306a36Sopenharmony_ci * We call MAL 2 the version in 440GP, 440GX, 440SP, 440SPE and Axon
3062306a36Sopenharmony_ci *
3162306a36Sopenharmony_ci * The driver expects a "version" property in the emac node containing
3262306a36Sopenharmony_ci * a number 1 or 2. New device-trees for EMAC capable platforms are thus
3362306a36Sopenharmony_ci * required to include that when porting to arch/powerpc.
3462306a36Sopenharmony_ci */
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/* MALx DCR registers */
3762306a36Sopenharmony_ci#define	MAL_CFG			0x00
3862306a36Sopenharmony_ci#define	  MAL_CFG_SR		0x80000000
3962306a36Sopenharmony_ci#define   MAL_CFG_PLBB		0x00004000
4062306a36Sopenharmony_ci#define   MAL_CFG_OPBBL		0x00000080
4162306a36Sopenharmony_ci#define   MAL_CFG_EOPIE		0x00000004
4262306a36Sopenharmony_ci#define   MAL_CFG_LEA		0x00000002
4362306a36Sopenharmony_ci#define   MAL_CFG_SD		0x00000001
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/* MAL V1 CFG bits */
4662306a36Sopenharmony_ci#define   MAL1_CFG_PLBP_MASK	0x00c00000
4762306a36Sopenharmony_ci#define   MAL1_CFG_PLBP_10	0x00800000
4862306a36Sopenharmony_ci#define   MAL1_CFG_GA		0x00200000
4962306a36Sopenharmony_ci#define   MAL1_CFG_OA		0x00100000
5062306a36Sopenharmony_ci#define   MAL1_CFG_PLBLE	0x00080000
5162306a36Sopenharmony_ci#define   MAL1_CFG_PLBT_MASK	0x00078000
5262306a36Sopenharmony_ci#define   MAL1_CFG_DEFAULT	(MAL1_CFG_PLBP_10 | MAL1_CFG_PLBT_MASK)
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* MAL V2 CFG bits */
5562306a36Sopenharmony_ci#define   MAL2_CFG_RPP_MASK	0x00c00000
5662306a36Sopenharmony_ci#define   MAL2_CFG_RPP_10	0x00800000
5762306a36Sopenharmony_ci#define   MAL2_CFG_RMBS_MASK	0x00300000
5862306a36Sopenharmony_ci#define   MAL2_CFG_WPP_MASK	0x000c0000
5962306a36Sopenharmony_ci#define   MAL2_CFG_WPP_10	0x00080000
6062306a36Sopenharmony_ci#define   MAL2_CFG_WMBS_MASK	0x00030000
6162306a36Sopenharmony_ci#define   MAL2_CFG_PLBLE	0x00008000
6262306a36Sopenharmony_ci#define   MAL2_CFG_DEFAULT	(MAL2_CFG_RMBS_MASK | MAL2_CFG_WMBS_MASK | \
6362306a36Sopenharmony_ci				 MAL2_CFG_RPP_10 | MAL2_CFG_WPP_10)
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci#define MAL_ESR			0x01
6662306a36Sopenharmony_ci#define   MAL_ESR_EVB		0x80000000
6762306a36Sopenharmony_ci#define   MAL_ESR_CIDT		0x40000000
6862306a36Sopenharmony_ci#define   MAL_ESR_CID_MASK	0x3e000000
6962306a36Sopenharmony_ci#define   MAL_ESR_CID_SHIFT	25
7062306a36Sopenharmony_ci#define   MAL_ESR_DE		0x00100000
7162306a36Sopenharmony_ci#define   MAL_ESR_OTE		0x00040000
7262306a36Sopenharmony_ci#define   MAL_ESR_OSE		0x00020000
7362306a36Sopenharmony_ci#define   MAL_ESR_PEIN		0x00010000
7462306a36Sopenharmony_ci#define   MAL_ESR_DEI		0x00000010
7562306a36Sopenharmony_ci#define   MAL_ESR_OTEI		0x00000004
7662306a36Sopenharmony_ci#define   MAL_ESR_OSEI		0x00000002
7762306a36Sopenharmony_ci#define   MAL_ESR_PBEI		0x00000001
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci/* MAL V1 ESR bits */
8062306a36Sopenharmony_ci#define   MAL1_ESR_ONE		0x00080000
8162306a36Sopenharmony_ci#define   MAL1_ESR_ONEI		0x00000008
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci/* MAL V2 ESR bits */
8462306a36Sopenharmony_ci#define   MAL2_ESR_PTE		0x00800000
8562306a36Sopenharmony_ci#define   MAL2_ESR_PRE		0x00400000
8662306a36Sopenharmony_ci#define   MAL2_ESR_PWE		0x00200000
8762306a36Sopenharmony_ci#define   MAL2_ESR_PTEI		0x00000080
8862306a36Sopenharmony_ci#define   MAL2_ESR_PREI		0x00000040
8962306a36Sopenharmony_ci#define   MAL2_ESR_PWEI		0x00000020
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci#define MAL_IER			0x02
9362306a36Sopenharmony_ci/* MAL IER bits */
9462306a36Sopenharmony_ci#define   MAL_IER_DE		0x00000010
9562306a36Sopenharmony_ci#define   MAL_IER_OTE		0x00000004
9662306a36Sopenharmony_ci#define   MAL_IER_OE		0x00000002
9762306a36Sopenharmony_ci#define   MAL_IER_PE		0x00000001
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci/* PLB read/write/timeout errors */
10062306a36Sopenharmony_ci#define   MAL_IER_PTE		0x00000080
10162306a36Sopenharmony_ci#define   MAL_IER_PRE		0x00000040
10262306a36Sopenharmony_ci#define   MAL_IER_PWE		0x00000020
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci#define   MAL_IER_SOC_EVENTS	(MAL_IER_PTE | MAL_IER_PRE | MAL_IER_PWE)
10562306a36Sopenharmony_ci#define   MAL_IER_EVENTS	(MAL_IER_SOC_EVENTS | MAL_IER_DE | \
10662306a36Sopenharmony_ci				 MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE)
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci#define MAL_TXCASR		0x04
10962306a36Sopenharmony_ci#define MAL_TXCARR		0x05
11062306a36Sopenharmony_ci#define MAL_TXEOBISR		0x06
11162306a36Sopenharmony_ci#define MAL_TXDEIR		0x07
11262306a36Sopenharmony_ci#define MAL_RXCASR		0x10
11362306a36Sopenharmony_ci#define MAL_RXCARR		0x11
11462306a36Sopenharmony_ci#define MAL_RXEOBISR		0x12
11562306a36Sopenharmony_ci#define MAL_RXDEIR		0x13
11662306a36Sopenharmony_ci#define MAL_TXCTPR(n)		((n) + 0x20)
11762306a36Sopenharmony_ci#define MAL_RXCTPR(n)		((n) + 0x40)
11862306a36Sopenharmony_ci#define MAL_RCBS(n)		((n) + 0x60)
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/* In reality MAL can handle TX buffers up to 4095 bytes long,
12162306a36Sopenharmony_ci * but this isn't a good round number :) 		 --ebs
12262306a36Sopenharmony_ci */
12362306a36Sopenharmony_ci#define MAL_MAX_TX_SIZE		4080
12462306a36Sopenharmony_ci#define MAL_MAX_RX_SIZE		4080
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_cistatic inline int mal_rx_size(int len)
12762306a36Sopenharmony_ci{
12862306a36Sopenharmony_ci	len = (len + 0xf) & ~0xf;
12962306a36Sopenharmony_ci	return len > MAL_MAX_RX_SIZE ? MAL_MAX_RX_SIZE : len;
13062306a36Sopenharmony_ci}
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_cistatic inline int mal_tx_chunks(int len)
13362306a36Sopenharmony_ci{
13462306a36Sopenharmony_ci	return DIV_ROUND_UP(len, MAL_MAX_TX_SIZE);
13562306a36Sopenharmony_ci}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci#define MAL_CHAN_MASK(n)	(0x80000000 >> (n))
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/* MAL Buffer Descriptor structure */
14062306a36Sopenharmony_cistruct mal_descriptor {
14162306a36Sopenharmony_ci	u16 ctrl;		/* MAL / Commac status control bits */
14262306a36Sopenharmony_ci	u16 data_len;		/* Max length is 4K-1 (12 bits)     */
14362306a36Sopenharmony_ci	u32 data_ptr;		/* pointer to actual data buffer    */
14462306a36Sopenharmony_ci};
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci/* the following defines are for the MadMAL status and control registers. */
14762306a36Sopenharmony_ci/* MADMAL transmit and receive status/control bits  */
14862306a36Sopenharmony_ci#define MAL_RX_CTRL_EMPTY	0x8000
14962306a36Sopenharmony_ci#define MAL_RX_CTRL_WRAP	0x4000
15062306a36Sopenharmony_ci#define MAL_RX_CTRL_CM		0x2000
15162306a36Sopenharmony_ci#define MAL_RX_CTRL_LAST	0x1000
15262306a36Sopenharmony_ci#define MAL_RX_CTRL_FIRST	0x0800
15362306a36Sopenharmony_ci#define MAL_RX_CTRL_INTR	0x0400
15462306a36Sopenharmony_ci#define MAL_RX_CTRL_SINGLE	(MAL_RX_CTRL_LAST | MAL_RX_CTRL_FIRST)
15562306a36Sopenharmony_ci#define MAL_IS_SINGLE_RX(ctrl)	(((ctrl) & MAL_RX_CTRL_SINGLE) == MAL_RX_CTRL_SINGLE)
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci#define MAL_TX_CTRL_READY	0x8000
15862306a36Sopenharmony_ci#define MAL_TX_CTRL_WRAP	0x4000
15962306a36Sopenharmony_ci#define MAL_TX_CTRL_CM		0x2000
16062306a36Sopenharmony_ci#define MAL_TX_CTRL_LAST	0x1000
16162306a36Sopenharmony_ci#define MAL_TX_CTRL_INTR	0x0400
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistruct mal_commac_ops {
16462306a36Sopenharmony_ci	void	(*poll_tx) (void *dev);
16562306a36Sopenharmony_ci	int	(*poll_rx) (void *dev, int budget);
16662306a36Sopenharmony_ci	int	(*peek_rx) (void *dev);
16762306a36Sopenharmony_ci	void	(*rxde) (void *dev);
16862306a36Sopenharmony_ci};
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_cistruct mal_commac {
17162306a36Sopenharmony_ci	struct mal_commac_ops	*ops;
17262306a36Sopenharmony_ci	void			*dev;
17362306a36Sopenharmony_ci	struct list_head	poll_list;
17462306a36Sopenharmony_ci	long       		flags;
17562306a36Sopenharmony_ci#define MAL_COMMAC_RX_STOPPED		0
17662306a36Sopenharmony_ci#define MAL_COMMAC_POLL_DISABLED	1
17762306a36Sopenharmony_ci	u32			tx_chan_mask;
17862306a36Sopenharmony_ci	u32			rx_chan_mask;
17962306a36Sopenharmony_ci	struct list_head	list;
18062306a36Sopenharmony_ci};
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_cistruct mal_instance {
18362306a36Sopenharmony_ci	int			version;
18462306a36Sopenharmony_ci	dcr_host_t		dcr_host;
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	int			num_tx_chans;	/* Number of TX channels */
18762306a36Sopenharmony_ci	int			num_rx_chans;	/* Number of RX channels */
18862306a36Sopenharmony_ci	int 			txeob_irq;	/* TX End Of Buffer IRQ  */
18962306a36Sopenharmony_ci	int 			rxeob_irq;	/* RX End Of Buffer IRQ  */
19062306a36Sopenharmony_ci	int			txde_irq;	/* TX Descriptor Error IRQ */
19162306a36Sopenharmony_ci	int			rxde_irq;	/* RX Descriptor Error IRQ */
19262306a36Sopenharmony_ci	int			serr_irq;	/* MAL System Error IRQ    */
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	struct list_head	poll_list;
19562306a36Sopenharmony_ci	struct napi_struct	napi;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	struct list_head	list;
19862306a36Sopenharmony_ci	u32			tx_chan_mask;
19962306a36Sopenharmony_ci	u32			rx_chan_mask;
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci	dma_addr_t		bd_dma;
20262306a36Sopenharmony_ci	struct mal_descriptor	*bd_virt;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	struct platform_device	*ofdev;
20562306a36Sopenharmony_ci	int			index;
20662306a36Sopenharmony_ci	spinlock_t		lock;
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci	struct net_device	dummy_dev;
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	unsigned int features;
21162306a36Sopenharmony_ci};
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_cistatic inline u32 get_mal_dcrn(struct mal_instance *mal, int reg)
21462306a36Sopenharmony_ci{
21562306a36Sopenharmony_ci	return dcr_read(mal->dcr_host, reg);
21662306a36Sopenharmony_ci}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_cistatic inline void set_mal_dcrn(struct mal_instance *mal, int reg, u32 val)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	dcr_write(mal->dcr_host, reg, val);
22162306a36Sopenharmony_ci}
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci/* Features of various MAL implementations */
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci/* Set if you have interrupt coalescing and you have to clear the SDR
22662306a36Sopenharmony_ci * register for TXEOB and RXEOB interrupts to work
22762306a36Sopenharmony_ci */
22862306a36Sopenharmony_ci#define MAL_FTR_CLEAR_ICINTSTAT	0x00000001
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci/* Set if your MAL has SERR, TXDE, and RXDE OR'd into a single UIC
23162306a36Sopenharmony_ci * interrupt
23262306a36Sopenharmony_ci */
23362306a36Sopenharmony_ci#define MAL_FTR_COMMON_ERR_INT	0x00000002
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_cienum {
23662306a36Sopenharmony_ci	MAL_FTRS_ALWAYS = 0,
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	MAL_FTRS_POSSIBLE =
23962306a36Sopenharmony_ci#ifdef CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT
24062306a36Sopenharmony_ci		MAL_FTR_CLEAR_ICINTSTAT |
24162306a36Sopenharmony_ci#endif
24262306a36Sopenharmony_ci#ifdef CONFIG_IBM_EMAC_MAL_COMMON_ERR
24362306a36Sopenharmony_ci		MAL_FTR_COMMON_ERR_INT |
24462306a36Sopenharmony_ci#endif
24562306a36Sopenharmony_ci		0,
24662306a36Sopenharmony_ci};
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_cistatic inline int mal_has_feature(struct mal_instance *dev,
24962306a36Sopenharmony_ci		unsigned long feature)
25062306a36Sopenharmony_ci{
25162306a36Sopenharmony_ci	return (MAL_FTRS_ALWAYS & feature) ||
25262306a36Sopenharmony_ci		(MAL_FTRS_POSSIBLE & dev->features & feature);
25362306a36Sopenharmony_ci}
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci/* Register MAL devices */
25662306a36Sopenharmony_ciint mal_init(void);
25762306a36Sopenharmony_civoid mal_exit(void);
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ciint mal_register_commac(struct mal_instance *mal,
26062306a36Sopenharmony_ci			struct mal_commac *commac);
26162306a36Sopenharmony_civoid mal_unregister_commac(struct mal_instance *mal,
26262306a36Sopenharmony_ci			   struct mal_commac *commac);
26362306a36Sopenharmony_ciint mal_set_rcbs(struct mal_instance *mal, int channel, unsigned long size);
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci/* Returns BD ring offset for a particular channel
26662306a36Sopenharmony_ci   (in 'struct mal_descriptor' elements)
26762306a36Sopenharmony_ci*/
26862306a36Sopenharmony_ciint mal_tx_bd_offset(struct mal_instance *mal, int channel);
26962306a36Sopenharmony_ciint mal_rx_bd_offset(struct mal_instance *mal, int channel);
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_civoid mal_enable_tx_channel(struct mal_instance *mal, int channel);
27262306a36Sopenharmony_civoid mal_disable_tx_channel(struct mal_instance *mal, int channel);
27362306a36Sopenharmony_civoid mal_enable_rx_channel(struct mal_instance *mal, int channel);
27462306a36Sopenharmony_civoid mal_disable_rx_channel(struct mal_instance *mal, int channel);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_civoid mal_poll_disable(struct mal_instance *mal, struct mal_commac *commac);
27762306a36Sopenharmony_civoid mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac);
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci/* Add/remove EMAC to/from MAL polling list */
28062306a36Sopenharmony_civoid mal_poll_add(struct mal_instance *mal, struct mal_commac *commac);
28162306a36Sopenharmony_civoid mal_poll_del(struct mal_instance *mal, struct mal_commac *commac);
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci/* Ethtool MAL registers */
28462306a36Sopenharmony_cistruct mal_regs {
28562306a36Sopenharmony_ci	u32 tx_count;
28662306a36Sopenharmony_ci	u32 rx_count;
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	u32 cfg;
28962306a36Sopenharmony_ci	u32 esr;
29062306a36Sopenharmony_ci	u32 ier;
29162306a36Sopenharmony_ci	u32 tx_casr;
29262306a36Sopenharmony_ci	u32 tx_carr;
29362306a36Sopenharmony_ci	u32 tx_eobisr;
29462306a36Sopenharmony_ci	u32 tx_deir;
29562306a36Sopenharmony_ci	u32 rx_casr;
29662306a36Sopenharmony_ci	u32 rx_carr;
29762306a36Sopenharmony_ci	u32 rx_eobisr;
29862306a36Sopenharmony_ci	u32 rx_deir;
29962306a36Sopenharmony_ci	u32 tx_ctpr[32];
30062306a36Sopenharmony_ci	u32 rx_ctpr[32];
30162306a36Sopenharmony_ci	u32 rcbs[32];
30262306a36Sopenharmony_ci};
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ciint mal_get_regs_len(struct mal_instance *mal);
30562306a36Sopenharmony_civoid *mal_dump_regs(struct mal_instance *mal, void *buf);
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci#endif /* __IBM_NEWEMAC_MAL_H */
308