162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * NetCP driver local header
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2014 Texas Instruments Incorporated
662306a36Sopenharmony_ci * Authors:	Sandeep Nair <sandeep_n@ti.com>
762306a36Sopenharmony_ci *		Sandeep Paulraj <s-paulraj@ti.com>
862306a36Sopenharmony_ci *		Cyril Chemparathy <cyril@ti.com>
962306a36Sopenharmony_ci *		Santosh Shilimkar <santosh.shilimkar@ti.com>
1062306a36Sopenharmony_ci *		Wingman Kwok <w-kwok2@ti.com>
1162306a36Sopenharmony_ci *		Murali Karicheri <m-karicheri2@ti.com>
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci#ifndef __NETCP_H__
1462306a36Sopenharmony_ci#define __NETCP_H__
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <linux/netdevice.h>
1762306a36Sopenharmony_ci#include <linux/soc/ti/knav_dma.h>
1862306a36Sopenharmony_ci#include <linux/u64_stats_sync.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/* Maximum Ethernet frame size supported by Keystone switch */
2162306a36Sopenharmony_ci#define NETCP_MAX_FRAME_SIZE		9504
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define SGMII_LINK_MAC_MAC_AUTONEG	0
2462306a36Sopenharmony_ci#define SGMII_LINK_MAC_PHY		1
2562306a36Sopenharmony_ci#define SGMII_LINK_MAC_MAC_FORCED	2
2662306a36Sopenharmony_ci#define SGMII_LINK_MAC_FIBER		3
2762306a36Sopenharmony_ci#define SGMII_LINK_MAC_PHY_NO_MDIO	4
2862306a36Sopenharmony_ci#define RGMII_LINK_MAC_PHY		5
2962306a36Sopenharmony_ci#define RGMII_LINK_MAC_PHY_NO_MDIO	7
3062306a36Sopenharmony_ci#define XGMII_LINK_MAC_PHY		10
3162306a36Sopenharmony_ci#define XGMII_LINK_MAC_MAC_FORCED	11
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cistruct netcp_device;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistruct netcp_tx_pipe {
3662306a36Sopenharmony_ci	struct netcp_device	*netcp_device;
3762306a36Sopenharmony_ci	void			*dma_queue;
3862306a36Sopenharmony_ci	unsigned int		dma_queue_id;
3962306a36Sopenharmony_ci	/* To port for packet forwarded to switch. Used only by ethss */
4062306a36Sopenharmony_ci	u8			switch_to_port;
4162306a36Sopenharmony_ci#define	SWITCH_TO_PORT_IN_TAGINFO	BIT(0)
4262306a36Sopenharmony_ci	u8			flags;
4362306a36Sopenharmony_ci	void			*dma_channel;
4462306a36Sopenharmony_ci	const char		*dma_chan_name;
4562306a36Sopenharmony_ci};
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#define ADDR_NEW			BIT(0)
4862306a36Sopenharmony_ci#define ADDR_VALID			BIT(1)
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cienum netcp_addr_type {
5162306a36Sopenharmony_ci	ADDR_ANY,
5262306a36Sopenharmony_ci	ADDR_DEV,
5362306a36Sopenharmony_ci	ADDR_UCAST,
5462306a36Sopenharmony_ci	ADDR_MCAST,
5562306a36Sopenharmony_ci	ADDR_BCAST
5662306a36Sopenharmony_ci};
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_cistruct netcp_addr {
5962306a36Sopenharmony_ci	struct netcp_intf	*netcp;
6062306a36Sopenharmony_ci	unsigned char		addr[ETH_ALEN];
6162306a36Sopenharmony_ci	enum netcp_addr_type	type;
6262306a36Sopenharmony_ci	unsigned int		flags;
6362306a36Sopenharmony_ci	struct list_head	node;
6462306a36Sopenharmony_ci};
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistruct netcp_stats {
6762306a36Sopenharmony_ci	struct u64_stats_sync   syncp_rx ____cacheline_aligned_in_smp;
6862306a36Sopenharmony_ci	u64                     rx_packets;
6962306a36Sopenharmony_ci	u64                     rx_bytes;
7062306a36Sopenharmony_ci	u32                     rx_errors;
7162306a36Sopenharmony_ci	u32                     rx_dropped;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	struct u64_stats_sync   syncp_tx ____cacheline_aligned_in_smp;
7462306a36Sopenharmony_ci	u64                     tx_packets;
7562306a36Sopenharmony_ci	u64                     tx_bytes;
7662306a36Sopenharmony_ci	u32                     tx_errors;
7762306a36Sopenharmony_ci	u32                     tx_dropped;
7862306a36Sopenharmony_ci};
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cistruct netcp_intf {
8162306a36Sopenharmony_ci	struct device		*dev;
8262306a36Sopenharmony_ci	struct device		*ndev_dev;
8362306a36Sopenharmony_ci	struct net_device	*ndev;
8462306a36Sopenharmony_ci	bool			big_endian;
8562306a36Sopenharmony_ci	unsigned int		tx_compl_qid;
8662306a36Sopenharmony_ci	void			*tx_pool;
8762306a36Sopenharmony_ci	struct list_head	txhook_list_head;
8862306a36Sopenharmony_ci	unsigned int		tx_pause_threshold;
8962306a36Sopenharmony_ci	void			*tx_compl_q;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	unsigned int		tx_resume_threshold;
9262306a36Sopenharmony_ci	void			*rx_queue;
9362306a36Sopenharmony_ci	void			*rx_pool;
9462306a36Sopenharmony_ci	struct list_head	rxhook_list_head;
9562306a36Sopenharmony_ci	unsigned int		rx_queue_id;
9662306a36Sopenharmony_ci	void			*rx_fdq[KNAV_DMA_FDQ_PER_CHAN];
9762306a36Sopenharmony_ci	struct napi_struct	rx_napi;
9862306a36Sopenharmony_ci	struct napi_struct	tx_napi;
9962306a36Sopenharmony_ci#define ETH_SW_CAN_REMOVE_ETH_FCS	BIT(0)
10062306a36Sopenharmony_ci	u32			hw_cap;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	/* 64-bit netcp stats */
10362306a36Sopenharmony_ci	struct netcp_stats	stats;
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	void			*rx_channel;
10662306a36Sopenharmony_ci	const char		*dma_chan_name;
10762306a36Sopenharmony_ci	u32			rx_pool_size;
10862306a36Sopenharmony_ci	u32			rx_pool_region_id;
10962306a36Sopenharmony_ci	u32			tx_pool_size;
11062306a36Sopenharmony_ci	u32			tx_pool_region_id;
11162306a36Sopenharmony_ci	struct list_head	module_head;
11262306a36Sopenharmony_ci	struct list_head	interface_list;
11362306a36Sopenharmony_ci	struct list_head	addr_list;
11462306a36Sopenharmony_ci	bool			netdev_registered;
11562306a36Sopenharmony_ci	bool			primary_module_attached;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	/* Lock used for protecting Rx/Tx hook list management */
11862306a36Sopenharmony_ci	spinlock_t		lock;
11962306a36Sopenharmony_ci	struct netcp_device	*netcp_device;
12062306a36Sopenharmony_ci	struct device_node	*node_interface;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	/* DMA configuration data */
12362306a36Sopenharmony_ci	u32			msg_enable;
12462306a36Sopenharmony_ci	u32			rx_queue_depths[KNAV_DMA_FDQ_PER_CHAN];
12562306a36Sopenharmony_ci};
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci#define	NETCP_PSDATA_LEN		KNAV_DMA_NUM_PS_WORDS
12862306a36Sopenharmony_cistruct netcp_packet {
12962306a36Sopenharmony_ci	struct sk_buff		*skb;
13062306a36Sopenharmony_ci	__le32			*epib;
13162306a36Sopenharmony_ci	u32			*psdata;
13262306a36Sopenharmony_ci	u32			eflags;
13362306a36Sopenharmony_ci	unsigned int		psdata_len;
13462306a36Sopenharmony_ci	struct netcp_intf	*netcp;
13562306a36Sopenharmony_ci	struct netcp_tx_pipe	*tx_pipe;
13662306a36Sopenharmony_ci	bool			rxtstamp_complete;
13762306a36Sopenharmony_ci	void			*ts_context;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	void (*txtstamp)(void *ctx, struct sk_buff *skb);
14062306a36Sopenharmony_ci};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistatic inline u32 *netcp_push_psdata(struct netcp_packet *p_info,
14362306a36Sopenharmony_ci				     unsigned int bytes)
14462306a36Sopenharmony_ci{
14562306a36Sopenharmony_ci	u32 *buf;
14662306a36Sopenharmony_ci	unsigned int words;
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	if ((bytes & 0x03) != 0)
14962306a36Sopenharmony_ci		return NULL;
15062306a36Sopenharmony_ci	words = bytes >> 2;
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	if ((p_info->psdata_len + words) > NETCP_PSDATA_LEN)
15362306a36Sopenharmony_ci		return NULL;
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	p_info->psdata_len += words;
15662306a36Sopenharmony_ci	buf = &p_info->psdata[NETCP_PSDATA_LEN - p_info->psdata_len];
15762306a36Sopenharmony_ci	return buf;
15862306a36Sopenharmony_ci}
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_cistatic inline int netcp_align_psdata(struct netcp_packet *p_info,
16162306a36Sopenharmony_ci				     unsigned int byte_align)
16262306a36Sopenharmony_ci{
16362306a36Sopenharmony_ci	int padding;
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	switch (byte_align) {
16662306a36Sopenharmony_ci	case 0:
16762306a36Sopenharmony_ci		padding = -EINVAL;
16862306a36Sopenharmony_ci		break;
16962306a36Sopenharmony_ci	case 1:
17062306a36Sopenharmony_ci	case 2:
17162306a36Sopenharmony_ci	case 4:
17262306a36Sopenharmony_ci		padding = 0;
17362306a36Sopenharmony_ci		break;
17462306a36Sopenharmony_ci	case 8:
17562306a36Sopenharmony_ci		padding = (p_info->psdata_len << 2) % 8;
17662306a36Sopenharmony_ci		break;
17762306a36Sopenharmony_ci	case 16:
17862306a36Sopenharmony_ci		padding = (p_info->psdata_len << 2) % 16;
17962306a36Sopenharmony_ci		break;
18062306a36Sopenharmony_ci	default:
18162306a36Sopenharmony_ci		padding = (p_info->psdata_len << 2) % byte_align;
18262306a36Sopenharmony_ci		break;
18362306a36Sopenharmony_ci	}
18462306a36Sopenharmony_ci	return padding;
18562306a36Sopenharmony_ci}
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_cistruct netcp_module {
18862306a36Sopenharmony_ci	const char		*name;
18962306a36Sopenharmony_ci	struct module		*owner;
19062306a36Sopenharmony_ci	bool			primary;
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci	/* probe/remove: called once per NETCP instance */
19362306a36Sopenharmony_ci	int	(*probe)(struct netcp_device *netcp_device,
19462306a36Sopenharmony_ci			 struct device *device, struct device_node *node,
19562306a36Sopenharmony_ci			 void **inst_priv);
19662306a36Sopenharmony_ci	int	(*remove)(struct netcp_device *netcp_device, void *inst_priv);
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	/* attach/release: called once per network interface */
19962306a36Sopenharmony_ci	int	(*attach)(void *inst_priv, struct net_device *ndev,
20062306a36Sopenharmony_ci			  struct device_node *node, void **intf_priv);
20162306a36Sopenharmony_ci	int	(*release)(void *intf_priv);
20262306a36Sopenharmony_ci	int	(*open)(void *intf_priv, struct net_device *ndev);
20362306a36Sopenharmony_ci	int	(*close)(void *intf_priv, struct net_device *ndev);
20462306a36Sopenharmony_ci	int	(*add_addr)(void *intf_priv, struct netcp_addr *naddr);
20562306a36Sopenharmony_ci	int	(*del_addr)(void *intf_priv, struct netcp_addr *naddr);
20662306a36Sopenharmony_ci	int	(*add_vid)(void *intf_priv, int vid);
20762306a36Sopenharmony_ci	int	(*del_vid)(void *intf_priv, int vid);
20862306a36Sopenharmony_ci	int	(*ioctl)(void *intf_priv, struct ifreq *req, int cmd);
20962306a36Sopenharmony_ci	int	(*set_rx_mode)(void *intf_priv, bool promisc);
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	/* used internally */
21262306a36Sopenharmony_ci	struct list_head	module_list;
21362306a36Sopenharmony_ci	struct list_head	interface_list;
21462306a36Sopenharmony_ci};
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ciint netcp_register_module(struct netcp_module *module);
21762306a36Sopenharmony_civoid netcp_unregister_module(struct netcp_module *module);
21862306a36Sopenharmony_civoid *netcp_module_get_intf_data(struct netcp_module *module,
21962306a36Sopenharmony_ci				 struct netcp_intf *intf);
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ciint netcp_txpipe_init(struct netcp_tx_pipe *tx_pipe,
22262306a36Sopenharmony_ci		      struct netcp_device *netcp_device,
22362306a36Sopenharmony_ci		      const char *dma_chan_name, unsigned int dma_queue_id);
22462306a36Sopenharmony_ciint netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe);
22562306a36Sopenharmony_ciint netcp_txpipe_close(struct netcp_tx_pipe *tx_pipe);
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_citypedef int netcp_hook_rtn(int order, void *data, struct netcp_packet *packet);
22862306a36Sopenharmony_ciint netcp_register_txhook(struct netcp_intf *netcp_priv, int order,
22962306a36Sopenharmony_ci			  netcp_hook_rtn *hook_rtn, void *hook_data);
23062306a36Sopenharmony_ciint netcp_unregister_txhook(struct netcp_intf *netcp_priv, int order,
23162306a36Sopenharmony_ci			    netcp_hook_rtn *hook_rtn, void *hook_data);
23262306a36Sopenharmony_ciint netcp_register_rxhook(struct netcp_intf *netcp_priv, int order,
23362306a36Sopenharmony_ci			  netcp_hook_rtn *hook_rtn, void *hook_data);
23462306a36Sopenharmony_ciint netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order,
23562306a36Sopenharmony_ci			    netcp_hook_rtn *hook_rtn, void *hook_data);
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci/* SGMII functions */
23862306a36Sopenharmony_ciint netcp_sgmii_reset(void __iomem *sgmii_ofs, int port);
23962306a36Sopenharmony_cibool netcp_sgmii_rtreset(void __iomem *sgmii_ofs, int port, bool set);
24062306a36Sopenharmony_ciint netcp_sgmii_get_port_link(void __iomem *sgmii_ofs, int port);
24162306a36Sopenharmony_ciint netcp_sgmii_config(void __iomem *sgmii_ofs, int port, u32 interface);
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci/* XGBE SERDES init functions */
24462306a36Sopenharmony_ciint netcp_xgbe_serdes_init(void __iomem *serdes_regs, void __iomem *xgbe_regs);
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci#endif	/* __NETCP_H__ */
247