230 lines
		
	
	
	
		
			6.3 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			230 lines
		
	
	
	
		
			6.3 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * NetCP driver local header | ||
|  |  * | ||
|  |  * Copyright (C) 2014 Texas Instruments Incorporated | ||
|  |  * Authors:	Sandeep Nair <sandeep_n@ti.com> | ||
|  |  *		Sandeep Paulraj <s-paulraj@ti.com> | ||
|  |  *		Cyril Chemparathy <cyril@ti.com> | ||
|  |  *		Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
|  |  *		Wingman Kwok <w-kwok2@ti.com> | ||
|  |  *		Murali Karicheri <m-karicheri2@ti.com> | ||
|  |  * | ||
|  |  * This program is free software; you can redistribute it and/or | ||
|  |  * modify it under the terms of the GNU General Public License as | ||
|  |  * published by the Free Software Foundation version 2. | ||
|  |  * | ||
|  |  * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
|  |  * kind, whether express or implied; without even the implied warranty | ||
|  |  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||
|  |  * GNU General Public License for more details. | ||
|  |  */ | ||
|  | #ifndef __NETCP_H__
 | ||
|  | #define __NETCP_H__
 | ||
|  | 
 | ||
|  | #include <linux/netdevice.h>
 | ||
|  | #include <linux/soc/ti/knav_dma.h>
 | ||
|  | 
 | ||
|  | /* Maximum Ethernet frame size supported by Keystone switch */ | ||
|  | #define NETCP_MAX_FRAME_SIZE		9504
 | ||
|  | 
 | ||
|  | #define SGMII_LINK_MAC_MAC_AUTONEG	0
 | ||
|  | #define SGMII_LINK_MAC_PHY		1
 | ||
|  | #define SGMII_LINK_MAC_MAC_FORCED	2
 | ||
|  | #define SGMII_LINK_MAC_FIBER		3
 | ||
|  | #define SGMII_LINK_MAC_PHY_NO_MDIO	4
 | ||
|  | #define XGMII_LINK_MAC_PHY		10
 | ||
|  | #define XGMII_LINK_MAC_MAC_FORCED	11
 | ||
|  | 
 | ||
|  | struct netcp_device; | ||
|  | 
 | ||
|  | struct netcp_tx_pipe { | ||
|  | 	struct netcp_device	*netcp_device; | ||
|  | 	void			*dma_queue; | ||
|  | 	unsigned int		dma_queue_id; | ||
|  | 	u8			dma_psflags; | ||
|  | 	void			*dma_channel; | ||
|  | 	const char		*dma_chan_name; | ||
|  | }; | ||
|  | 
 | ||
|  | #define ADDR_NEW			BIT(0)
 | ||
|  | #define ADDR_VALID			BIT(1)
 | ||
|  | 
 | ||
|  | enum netcp_addr_type { | ||
|  | 	ADDR_ANY, | ||
|  | 	ADDR_DEV, | ||
|  | 	ADDR_UCAST, | ||
|  | 	ADDR_MCAST, | ||
|  | 	ADDR_BCAST | ||
|  | }; | ||
|  | 
 | ||
|  | struct netcp_addr { | ||
|  | 	struct netcp_intf	*netcp; | ||
|  | 	unsigned char		addr[ETH_ALEN]; | ||
|  | 	enum netcp_addr_type	type; | ||
|  | 	unsigned int		flags; | ||
|  | 	struct list_head	node; | ||
|  | }; | ||
|  | 
 | ||
|  | struct netcp_intf { | ||
|  | 	struct device		*dev; | ||
|  | 	struct device		*ndev_dev; | ||
|  | 	struct net_device	*ndev; | ||
|  | 	bool			big_endian; | ||
|  | 	unsigned int		tx_compl_qid; | ||
|  | 	void			*tx_pool; | ||
|  | 	struct list_head	txhook_list_head; | ||
|  | 	unsigned int		tx_pause_threshold; | ||
|  | 	void			*tx_compl_q; | ||
|  | 
 | ||
|  | 	unsigned int		tx_resume_threshold; | ||
|  | 	void			*rx_queue; | ||
|  | 	void			*rx_pool; | ||
|  | 	struct list_head	rxhook_list_head; | ||
|  | 	unsigned int		rx_queue_id; | ||
|  | 	void			*rx_fdq[KNAV_DMA_FDQ_PER_CHAN]; | ||
|  | 	u32			rx_buffer_sizes[KNAV_DMA_FDQ_PER_CHAN]; | ||
|  | 	struct napi_struct	rx_napi; | ||
|  | 	struct napi_struct	tx_napi; | ||
|  | 
 | ||
|  | 	void			*rx_channel; | ||
|  | 	const char		*dma_chan_name; | ||
|  | 	u32			rx_pool_size; | ||
|  | 	u32			rx_pool_region_id; | ||
|  | 	u32			tx_pool_size; | ||
|  | 	u32			tx_pool_region_id; | ||
|  | 	struct list_head	module_head; | ||
|  | 	struct list_head	interface_list; | ||
|  | 	struct list_head	addr_list; | ||
|  | 	bool			netdev_registered; | ||
|  | 	bool			primary_module_attached; | ||
|  | 
 | ||
|  | 	/* Lock used for protecting Rx/Tx hook list management */ | ||
|  | 	spinlock_t		lock; | ||
|  | 	struct netcp_device	*netcp_device; | ||
|  | 	struct device_node	*node_interface; | ||
|  | 
 | ||
|  | 	/* DMA configuration data */ | ||
|  | 	u32			msg_enable; | ||
|  | 	u32			rx_queue_depths[KNAV_DMA_FDQ_PER_CHAN]; | ||
|  | }; | ||
|  | 
 | ||
|  | #define	NETCP_PSDATA_LEN		KNAV_DMA_NUM_PS_WORDS
 | ||
|  | struct netcp_packet { | ||
|  | 	struct sk_buff		*skb; | ||
|  | 	u32			*epib; | ||
|  | 	u32			*psdata; | ||
|  | 	unsigned int		psdata_len; | ||
|  | 	struct netcp_intf	*netcp; | ||
|  | 	struct netcp_tx_pipe	*tx_pipe; | ||
|  | 	bool			rxtstamp_complete; | ||
|  | 	void			*ts_context; | ||
|  | 
 | ||
|  | 	int	(*txtstamp_complete)(void *ctx, struct netcp_packet *pkt); | ||
|  | }; | ||
|  | 
 | ||
|  | static inline u32 *netcp_push_psdata(struct netcp_packet *p_info, | ||
|  | 				     unsigned int bytes) | ||
|  | { | ||
|  | 	u32 *buf; | ||
|  | 	unsigned int words; | ||
|  | 
 | ||
|  | 	if ((bytes & 0x03) != 0) | ||
|  | 		return NULL; | ||
|  | 	words = bytes >> 2; | ||
|  | 
 | ||
|  | 	if ((p_info->psdata_len + words) > NETCP_PSDATA_LEN) | ||
|  | 		return NULL; | ||
|  | 
 | ||
|  | 	p_info->psdata_len += words; | ||
|  | 	buf = &p_info->psdata[NETCP_PSDATA_LEN - p_info->psdata_len]; | ||
|  | 	return buf; | ||
|  | } | ||
|  | 
 | ||
|  | static inline int netcp_align_psdata(struct netcp_packet *p_info, | ||
|  | 				     unsigned int byte_align) | ||
|  | { | ||
|  | 	int padding; | ||
|  | 
 | ||
|  | 	switch (byte_align) { | ||
|  | 	case 0: | ||
|  | 		padding = -EINVAL; | ||
|  | 		break; | ||
|  | 	case 1: | ||
|  | 	case 2: | ||
|  | 	case 4: | ||
|  | 		padding = 0; | ||
|  | 		break; | ||
|  | 	case 8: | ||
|  | 		padding = (p_info->psdata_len << 2) % 8; | ||
|  | 		break; | ||
|  | 	case 16: | ||
|  | 		padding = (p_info->psdata_len << 2) % 16; | ||
|  | 		break; | ||
|  | 	default: | ||
|  | 		padding = (p_info->psdata_len << 2) % byte_align; | ||
|  | 		break; | ||
|  | 	} | ||
|  | 	return padding; | ||
|  | } | ||
|  | 
 | ||
|  | struct netcp_module { | ||
|  | 	const char		*name; | ||
|  | 	struct module		*owner; | ||
|  | 	bool			primary; | ||
|  | 
 | ||
|  | 	/* probe/remove: called once per NETCP instance */ | ||
|  | 	int	(*probe)(struct netcp_device *netcp_device, | ||
|  | 			 struct device *device, struct device_node *node, | ||
|  | 			 void **inst_priv); | ||
|  | 	int	(*remove)(struct netcp_device *netcp_device, void *inst_priv); | ||
|  | 
 | ||
|  | 	/* attach/release: called once per network interface */ | ||
|  | 	int	(*attach)(void *inst_priv, struct net_device *ndev, | ||
|  | 			  struct device_node *node, void **intf_priv); | ||
|  | 	int	(*release)(void *intf_priv); | ||
|  | 	int	(*open)(void *intf_priv, struct net_device *ndev); | ||
|  | 	int	(*close)(void *intf_priv, struct net_device *ndev); | ||
|  | 	int	(*add_addr)(void *intf_priv, struct netcp_addr *naddr); | ||
|  | 	int	(*del_addr)(void *intf_priv, struct netcp_addr *naddr); | ||
|  | 	int	(*add_vid)(void *intf_priv, int vid); | ||
|  | 	int	(*del_vid)(void *intf_priv, int vid); | ||
|  | 	int	(*ioctl)(void *intf_priv, struct ifreq *req, int cmd); | ||
|  | 
 | ||
|  | 	/* used internally */ | ||
|  | 	struct list_head	module_list; | ||
|  | 	struct list_head	interface_list; | ||
|  | }; | ||
|  | 
 | ||
|  | int netcp_register_module(struct netcp_module *module); | ||
|  | void netcp_unregister_module(struct netcp_module *module); | ||
|  | void *netcp_module_get_intf_data(struct netcp_module *module, | ||
|  | 				 struct netcp_intf *intf); | ||
|  | 
 | ||
|  | int netcp_txpipe_init(struct netcp_tx_pipe *tx_pipe, | ||
|  | 		      struct netcp_device *netcp_device, | ||
|  | 		      const char *dma_chan_name, unsigned int dma_queue_id); | ||
|  | int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe); | ||
|  | int netcp_txpipe_close(struct netcp_tx_pipe *tx_pipe); | ||
|  | 
 | ||
|  | typedef int netcp_hook_rtn(int order, void *data, struct netcp_packet *packet); | ||
|  | int netcp_register_txhook(struct netcp_intf *netcp_priv, int order, | ||
|  | 			  netcp_hook_rtn *hook_rtn, void *hook_data); | ||
|  | int netcp_unregister_txhook(struct netcp_intf *netcp_priv, int order, | ||
|  | 			    netcp_hook_rtn *hook_rtn, void *hook_data); | ||
|  | int netcp_register_rxhook(struct netcp_intf *netcp_priv, int order, | ||
|  | 			  netcp_hook_rtn *hook_rtn, void *hook_data); | ||
|  | int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order, | ||
|  | 			    netcp_hook_rtn *hook_rtn, void *hook_data); | ||
|  | void *netcp_device_find_module(struct netcp_device *netcp_device, | ||
|  | 			       const char *name); | ||
|  | 
 | ||
|  | /* SGMII functions */ | ||
|  | int netcp_sgmii_reset(void __iomem *sgmii_ofs, int port); | ||
|  | int netcp_sgmii_get_port_link(void __iomem *sgmii_ofs, int port); | ||
|  | int netcp_sgmii_config(void __iomem *sgmii_ofs, int port, u32 interface); | ||
|  | 
 | ||
|  | /* XGBE SERDES init functions */ | ||
|  | int netcp_xgbe_serdes_init(void __iomem *serdes_regs, void __iomem *xgbe_regs); | ||
|  | 
 | ||
|  | #endif	/* __NETCP_H__ */
 |