184640e27SKaricheri, Muralidharan /* 284640e27SKaricheri, Muralidharan * NetCP driver local header 384640e27SKaricheri, Muralidharan * 484640e27SKaricheri, Muralidharan * Copyright (C) 2014 Texas Instruments Incorporated 584640e27SKaricheri, Muralidharan * Authors: Sandeep Nair <sandeep_n@ti.com> 684640e27SKaricheri, Muralidharan * Sandeep Paulraj <s-paulraj@ti.com> 784640e27SKaricheri, Muralidharan * Cyril Chemparathy <cyril@ti.com> 884640e27SKaricheri, Muralidharan * Santosh Shilimkar <santosh.shilimkar@ti.com> 984640e27SKaricheri, Muralidharan * Wingman Kwok <w-kwok2@ti.com> 1084640e27SKaricheri, Muralidharan * Murali Karicheri <m-karicheri2@ti.com> 1184640e27SKaricheri, Muralidharan * 1284640e27SKaricheri, Muralidharan * This program is free software; you can redistribute it and/or 1384640e27SKaricheri, Muralidharan * modify it under the terms of the GNU General Public License as 1484640e27SKaricheri, Muralidharan * published by the Free Software Foundation version 2. 1584640e27SKaricheri, Muralidharan * 1684640e27SKaricheri, Muralidharan * This program is distributed "as is" WITHOUT ANY WARRANTY of any 1784640e27SKaricheri, Muralidharan * kind, whether express or implied; without even the implied warranty 1884640e27SKaricheri, Muralidharan * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1984640e27SKaricheri, Muralidharan * GNU General Public License for more details. 2084640e27SKaricheri, Muralidharan */ 2184640e27SKaricheri, Muralidharan #ifndef __NETCP_H__ 2284640e27SKaricheri, Muralidharan #define __NETCP_H__ 2384640e27SKaricheri, Muralidharan 2484640e27SKaricheri, Muralidharan #include <linux/netdevice.h> 2584640e27SKaricheri, Muralidharan #include <linux/soc/ti/knav_dma.h> 266a8162e9SMichael Scherban #include <linux/u64_stats_sync.h> 2784640e27SKaricheri, Muralidharan 2884640e27SKaricheri, Muralidharan /* Maximum Ethernet frame size supported by Keystone switch */ 2984640e27SKaricheri, Muralidharan #define NETCP_MAX_FRAME_SIZE 9504 3084640e27SKaricheri, Muralidharan 3184640e27SKaricheri, Muralidharan #define SGMII_LINK_MAC_MAC_AUTONEG 0 3284640e27SKaricheri, Muralidharan #define SGMII_LINK_MAC_PHY 1 3384640e27SKaricheri, Muralidharan #define SGMII_LINK_MAC_MAC_FORCED 2 3484640e27SKaricheri, Muralidharan #define SGMII_LINK_MAC_FIBER 3 3584640e27SKaricheri, Muralidharan #define SGMII_LINK_MAC_PHY_NO_MDIO 4 3684640e27SKaricheri, Muralidharan #define XGMII_LINK_MAC_PHY 10 3784640e27SKaricheri, Muralidharan #define XGMII_LINK_MAC_MAC_FORCED 11 3884640e27SKaricheri, Muralidharan 3984640e27SKaricheri, Muralidharan struct netcp_device; 4084640e27SKaricheri, Muralidharan 4184640e27SKaricheri, Muralidharan struct netcp_tx_pipe { 4284640e27SKaricheri, Muralidharan struct netcp_device *netcp_device; 4384640e27SKaricheri, Muralidharan void *dma_queue; 4484640e27SKaricheri, Muralidharan unsigned int dma_queue_id; 45e170f409SKaricheri, Muralidharan /* To port for packet forwarded to switch. Used only by ethss */ 46e170f409SKaricheri, Muralidharan u8 switch_to_port; 47e170f409SKaricheri, Muralidharan #define SWITCH_TO_PORT_IN_TAGINFO BIT(0) 48e170f409SKaricheri, Muralidharan u8 flags; 4984640e27SKaricheri, Muralidharan void *dma_channel; 5084640e27SKaricheri, Muralidharan const char *dma_chan_name; 5184640e27SKaricheri, Muralidharan }; 5284640e27SKaricheri, Muralidharan 5384640e27SKaricheri, Muralidharan #define ADDR_NEW BIT(0) 5484640e27SKaricheri, Muralidharan #define ADDR_VALID BIT(1) 5584640e27SKaricheri, Muralidharan 5684640e27SKaricheri, Muralidharan enum netcp_addr_type { 5784640e27SKaricheri, Muralidharan ADDR_ANY, 5884640e27SKaricheri, Muralidharan ADDR_DEV, 5984640e27SKaricheri, Muralidharan ADDR_UCAST, 6084640e27SKaricheri, Muralidharan ADDR_MCAST, 6184640e27SKaricheri, Muralidharan ADDR_BCAST 6284640e27SKaricheri, Muralidharan }; 6384640e27SKaricheri, Muralidharan 6484640e27SKaricheri, Muralidharan struct netcp_addr { 6584640e27SKaricheri, Muralidharan struct netcp_intf *netcp; 6684640e27SKaricheri, Muralidharan unsigned char addr[ETH_ALEN]; 6784640e27SKaricheri, Muralidharan enum netcp_addr_type type; 6884640e27SKaricheri, Muralidharan unsigned int flags; 6984640e27SKaricheri, Muralidharan struct list_head node; 7084640e27SKaricheri, Muralidharan }; 7184640e27SKaricheri, Muralidharan 726a8162e9SMichael Scherban struct netcp_stats { 736a8162e9SMichael Scherban struct u64_stats_sync syncp_rx ____cacheline_aligned_in_smp; 746a8162e9SMichael Scherban u64 rx_packets; 756a8162e9SMichael Scherban u64 rx_bytes; 766a8162e9SMichael Scherban u32 rx_errors; 776a8162e9SMichael Scherban u32 rx_dropped; 786a8162e9SMichael Scherban 796a8162e9SMichael Scherban struct u64_stats_sync syncp_tx ____cacheline_aligned_in_smp; 806a8162e9SMichael Scherban u64 tx_packets; 816a8162e9SMichael Scherban u64 tx_bytes; 826a8162e9SMichael Scherban u32 tx_errors; 836a8162e9SMichael Scherban u32 tx_dropped; 846a8162e9SMichael Scherban }; 856a8162e9SMichael Scherban 8684640e27SKaricheri, Muralidharan struct netcp_intf { 8784640e27SKaricheri, Muralidharan struct device *dev; 8884640e27SKaricheri, Muralidharan struct device *ndev_dev; 8984640e27SKaricheri, Muralidharan struct net_device *ndev; 9084640e27SKaricheri, Muralidharan bool big_endian; 9184640e27SKaricheri, Muralidharan unsigned int tx_compl_qid; 9284640e27SKaricheri, Muralidharan void *tx_pool; 9384640e27SKaricheri, Muralidharan struct list_head txhook_list_head; 9484640e27SKaricheri, Muralidharan unsigned int tx_pause_threshold; 9584640e27SKaricheri, Muralidharan void *tx_compl_q; 9684640e27SKaricheri, Muralidharan 9784640e27SKaricheri, Muralidharan unsigned int tx_resume_threshold; 9884640e27SKaricheri, Muralidharan void *rx_queue; 9984640e27SKaricheri, Muralidharan void *rx_pool; 10084640e27SKaricheri, Muralidharan struct list_head rxhook_list_head; 10184640e27SKaricheri, Muralidharan unsigned int rx_queue_id; 10284640e27SKaricheri, Muralidharan void *rx_fdq[KNAV_DMA_FDQ_PER_CHAN]; 10384640e27SKaricheri, Muralidharan struct napi_struct rx_napi; 10484640e27SKaricheri, Muralidharan struct napi_struct tx_napi; 1054cd85a61SKaricheri, Muralidharan #define ETH_SW_CAN_REMOVE_ETH_FCS BIT(0) 1064cd85a61SKaricheri, Muralidharan u32 hw_cap; 10784640e27SKaricheri, Muralidharan 1086a8162e9SMichael Scherban /* 64-bit netcp stats */ 1096a8162e9SMichael Scherban struct netcp_stats stats; 1106a8162e9SMichael Scherban 11184640e27SKaricheri, Muralidharan void *rx_channel; 11284640e27SKaricheri, Muralidharan const char *dma_chan_name; 11384640e27SKaricheri, Muralidharan u32 rx_pool_size; 11484640e27SKaricheri, Muralidharan u32 rx_pool_region_id; 11584640e27SKaricheri, Muralidharan u32 tx_pool_size; 11684640e27SKaricheri, Muralidharan u32 tx_pool_region_id; 11784640e27SKaricheri, Muralidharan struct list_head module_head; 11884640e27SKaricheri, Muralidharan struct list_head interface_list; 11984640e27SKaricheri, Muralidharan struct list_head addr_list; 12084640e27SKaricheri, Muralidharan bool netdev_registered; 12184640e27SKaricheri, Muralidharan bool primary_module_attached; 12284640e27SKaricheri, Muralidharan 12384640e27SKaricheri, Muralidharan /* Lock used for protecting Rx/Tx hook list management */ 12484640e27SKaricheri, Muralidharan spinlock_t lock; 12584640e27SKaricheri, Muralidharan struct netcp_device *netcp_device; 12684640e27SKaricheri, Muralidharan struct device_node *node_interface; 12784640e27SKaricheri, Muralidharan 12884640e27SKaricheri, Muralidharan /* DMA configuration data */ 12984640e27SKaricheri, Muralidharan u32 msg_enable; 13084640e27SKaricheri, Muralidharan u32 rx_queue_depths[KNAV_DMA_FDQ_PER_CHAN]; 13184640e27SKaricheri, Muralidharan }; 13284640e27SKaricheri, Muralidharan 13384640e27SKaricheri, Muralidharan #define NETCP_PSDATA_LEN KNAV_DMA_NUM_PS_WORDS 13484640e27SKaricheri, Muralidharan struct netcp_packet { 13584640e27SKaricheri, Muralidharan struct sk_buff *skb; 1369dd2d6c5SArnd Bergmann __le32 *epib; 13784640e27SKaricheri, Muralidharan u32 *psdata; 13869d707d0SKaricheri, Muralidharan u32 eflags; 13984640e27SKaricheri, Muralidharan unsigned int psdata_len; 14084640e27SKaricheri, Muralidharan struct netcp_intf *netcp; 14184640e27SKaricheri, Muralidharan struct netcp_tx_pipe *tx_pipe; 14284640e27SKaricheri, Muralidharan bool rxtstamp_complete; 14384640e27SKaricheri, Muralidharan void *ts_context; 14484640e27SKaricheri, Muralidharan 1456246168bSWingMan Kwok void (*txtstamp)(void *ctx, struct sk_buff *skb); 14684640e27SKaricheri, Muralidharan }; 14784640e27SKaricheri, Muralidharan 14884640e27SKaricheri, Muralidharan static inline u32 *netcp_push_psdata(struct netcp_packet *p_info, 14984640e27SKaricheri, Muralidharan unsigned int bytes) 15084640e27SKaricheri, Muralidharan { 15184640e27SKaricheri, Muralidharan u32 *buf; 15284640e27SKaricheri, Muralidharan unsigned int words; 15384640e27SKaricheri, Muralidharan 15484640e27SKaricheri, Muralidharan if ((bytes & 0x03) != 0) 15584640e27SKaricheri, Muralidharan return NULL; 15684640e27SKaricheri, Muralidharan words = bytes >> 2; 15784640e27SKaricheri, Muralidharan 15884640e27SKaricheri, Muralidharan if ((p_info->psdata_len + words) > NETCP_PSDATA_LEN) 15984640e27SKaricheri, Muralidharan return NULL; 16084640e27SKaricheri, Muralidharan 16184640e27SKaricheri, Muralidharan p_info->psdata_len += words; 16284640e27SKaricheri, Muralidharan buf = &p_info->psdata[NETCP_PSDATA_LEN - p_info->psdata_len]; 16384640e27SKaricheri, Muralidharan return buf; 16484640e27SKaricheri, Muralidharan } 16584640e27SKaricheri, Muralidharan 16684640e27SKaricheri, Muralidharan static inline int netcp_align_psdata(struct netcp_packet *p_info, 16784640e27SKaricheri, Muralidharan unsigned int byte_align) 16884640e27SKaricheri, Muralidharan { 16984640e27SKaricheri, Muralidharan int padding; 17084640e27SKaricheri, Muralidharan 17184640e27SKaricheri, Muralidharan switch (byte_align) { 17284640e27SKaricheri, Muralidharan case 0: 17384640e27SKaricheri, Muralidharan padding = -EINVAL; 17484640e27SKaricheri, Muralidharan break; 17584640e27SKaricheri, Muralidharan case 1: 17684640e27SKaricheri, Muralidharan case 2: 17784640e27SKaricheri, Muralidharan case 4: 17884640e27SKaricheri, Muralidharan padding = 0; 17984640e27SKaricheri, Muralidharan break; 18084640e27SKaricheri, Muralidharan case 8: 18184640e27SKaricheri, Muralidharan padding = (p_info->psdata_len << 2) % 8; 18284640e27SKaricheri, Muralidharan break; 18384640e27SKaricheri, Muralidharan case 16: 18484640e27SKaricheri, Muralidharan padding = (p_info->psdata_len << 2) % 16; 18584640e27SKaricheri, Muralidharan break; 18684640e27SKaricheri, Muralidharan default: 18784640e27SKaricheri, Muralidharan padding = (p_info->psdata_len << 2) % byte_align; 18884640e27SKaricheri, Muralidharan break; 18984640e27SKaricheri, Muralidharan } 19084640e27SKaricheri, Muralidharan return padding; 19184640e27SKaricheri, Muralidharan } 19284640e27SKaricheri, Muralidharan 19384640e27SKaricheri, Muralidharan struct netcp_module { 19484640e27SKaricheri, Muralidharan const char *name; 19584640e27SKaricheri, Muralidharan struct module *owner; 19684640e27SKaricheri, Muralidharan bool primary; 19784640e27SKaricheri, Muralidharan 19884640e27SKaricheri, Muralidharan /* probe/remove: called once per NETCP instance */ 19984640e27SKaricheri, Muralidharan int (*probe)(struct netcp_device *netcp_device, 20084640e27SKaricheri, Muralidharan struct device *device, struct device_node *node, 20184640e27SKaricheri, Muralidharan void **inst_priv); 20284640e27SKaricheri, Muralidharan int (*remove)(struct netcp_device *netcp_device, void *inst_priv); 20384640e27SKaricheri, Muralidharan 20484640e27SKaricheri, Muralidharan /* attach/release: called once per network interface */ 20584640e27SKaricheri, Muralidharan int (*attach)(void *inst_priv, struct net_device *ndev, 20684640e27SKaricheri, Muralidharan struct device_node *node, void **intf_priv); 20784640e27SKaricheri, Muralidharan int (*release)(void *intf_priv); 20884640e27SKaricheri, Muralidharan int (*open)(void *intf_priv, struct net_device *ndev); 20984640e27SKaricheri, Muralidharan int (*close)(void *intf_priv, struct net_device *ndev); 21084640e27SKaricheri, Muralidharan int (*add_addr)(void *intf_priv, struct netcp_addr *naddr); 21184640e27SKaricheri, Muralidharan int (*del_addr)(void *intf_priv, struct netcp_addr *naddr); 21284640e27SKaricheri, Muralidharan int (*add_vid)(void *intf_priv, int vid); 21384640e27SKaricheri, Muralidharan int (*del_vid)(void *intf_priv, int vid); 21484640e27SKaricheri, Muralidharan int (*ioctl)(void *intf_priv, struct ifreq *req, int cmd); 21584640e27SKaricheri, Muralidharan 21684640e27SKaricheri, Muralidharan /* used internally */ 21784640e27SKaricheri, Muralidharan struct list_head module_list; 21884640e27SKaricheri, Muralidharan struct list_head interface_list; 21984640e27SKaricheri, Muralidharan }; 22084640e27SKaricheri, Muralidharan 22184640e27SKaricheri, Muralidharan int netcp_register_module(struct netcp_module *module); 22284640e27SKaricheri, Muralidharan void netcp_unregister_module(struct netcp_module *module); 22384640e27SKaricheri, Muralidharan void *netcp_module_get_intf_data(struct netcp_module *module, 22484640e27SKaricheri, Muralidharan struct netcp_intf *intf); 22584640e27SKaricheri, Muralidharan 22684640e27SKaricheri, Muralidharan int netcp_txpipe_init(struct netcp_tx_pipe *tx_pipe, 22784640e27SKaricheri, Muralidharan struct netcp_device *netcp_device, 22884640e27SKaricheri, Muralidharan const char *dma_chan_name, unsigned int dma_queue_id); 22984640e27SKaricheri, Muralidharan int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe); 23084640e27SKaricheri, Muralidharan int netcp_txpipe_close(struct netcp_tx_pipe *tx_pipe); 23184640e27SKaricheri, Muralidharan 23284640e27SKaricheri, Muralidharan typedef int netcp_hook_rtn(int order, void *data, struct netcp_packet *packet); 23384640e27SKaricheri, Muralidharan int netcp_register_txhook(struct netcp_intf *netcp_priv, int order, 23484640e27SKaricheri, Muralidharan netcp_hook_rtn *hook_rtn, void *hook_data); 23584640e27SKaricheri, Muralidharan int netcp_unregister_txhook(struct netcp_intf *netcp_priv, int order, 23684640e27SKaricheri, Muralidharan netcp_hook_rtn *hook_rtn, void *hook_data); 23784640e27SKaricheri, Muralidharan int netcp_register_rxhook(struct netcp_intf *netcp_priv, int order, 23884640e27SKaricheri, Muralidharan netcp_hook_rtn *hook_rtn, void *hook_data); 23984640e27SKaricheri, Muralidharan int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order, 24084640e27SKaricheri, Muralidharan netcp_hook_rtn *hook_rtn, void *hook_data); 24184640e27SKaricheri, Muralidharan void *netcp_device_find_module(struct netcp_device *netcp_device, 24284640e27SKaricheri, Muralidharan const char *name); 24384640e27SKaricheri, Muralidharan 24484640e27SKaricheri, Muralidharan /* SGMII functions */ 24584640e27SKaricheri, Muralidharan int netcp_sgmii_reset(void __iomem *sgmii_ofs, int port); 2467025e88aSWingMan Kwok bool netcp_sgmii_rtreset(void __iomem *sgmii_ofs, int port, bool set); 24784640e27SKaricheri, Muralidharan int netcp_sgmii_get_port_link(void __iomem *sgmii_ofs, int port); 24884640e27SKaricheri, Muralidharan int netcp_sgmii_config(void __iomem *sgmii_ofs, int port, u32 interface); 24984640e27SKaricheri, Muralidharan 25084640e27SKaricheri, Muralidharan /* XGBE SERDES init functions */ 25184640e27SKaricheri, Muralidharan int netcp_xgbe_serdes_init(void __iomem *serdes_regs, void __iomem *xgbe_regs); 25284640e27SKaricheri, Muralidharan 25384640e27SKaricheri, Muralidharan #endif /* __NETCP_H__ */ 254