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 36478e9a5fSMurali Karicheri #define RGMII_LINK_MAC_PHY 5 37478e9a5fSMurali Karicheri #define RGMII_LINK_MAC_PHY_NO_MDIO 7 3884640e27SKaricheri, Muralidharan #define XGMII_LINK_MAC_PHY 10 3984640e27SKaricheri, Muralidharan #define XGMII_LINK_MAC_MAC_FORCED 11 4084640e27SKaricheri, Muralidharan 4184640e27SKaricheri, Muralidharan struct netcp_device; 4284640e27SKaricheri, Muralidharan 4384640e27SKaricheri, Muralidharan struct netcp_tx_pipe { 4484640e27SKaricheri, Muralidharan struct netcp_device *netcp_device; 4584640e27SKaricheri, Muralidharan void *dma_queue; 4684640e27SKaricheri, Muralidharan unsigned int dma_queue_id; 47e170f409SKaricheri, Muralidharan /* To port for packet forwarded to switch. Used only by ethss */ 48e170f409SKaricheri, Muralidharan u8 switch_to_port; 49e170f409SKaricheri, Muralidharan #define SWITCH_TO_PORT_IN_TAGINFO BIT(0) 50e170f409SKaricheri, Muralidharan u8 flags; 5184640e27SKaricheri, Muralidharan void *dma_channel; 5284640e27SKaricheri, Muralidharan const char *dma_chan_name; 5384640e27SKaricheri, Muralidharan }; 5484640e27SKaricheri, Muralidharan 5584640e27SKaricheri, Muralidharan #define ADDR_NEW BIT(0) 5684640e27SKaricheri, Muralidharan #define ADDR_VALID BIT(1) 5784640e27SKaricheri, Muralidharan 5884640e27SKaricheri, Muralidharan enum netcp_addr_type { 5984640e27SKaricheri, Muralidharan ADDR_ANY, 6084640e27SKaricheri, Muralidharan ADDR_DEV, 6184640e27SKaricheri, Muralidharan ADDR_UCAST, 6284640e27SKaricheri, Muralidharan ADDR_MCAST, 6384640e27SKaricheri, Muralidharan ADDR_BCAST 6484640e27SKaricheri, Muralidharan }; 6584640e27SKaricheri, Muralidharan 6684640e27SKaricheri, Muralidharan struct netcp_addr { 6784640e27SKaricheri, Muralidharan struct netcp_intf *netcp; 6884640e27SKaricheri, Muralidharan unsigned char addr[ETH_ALEN]; 6984640e27SKaricheri, Muralidharan enum netcp_addr_type type; 7084640e27SKaricheri, Muralidharan unsigned int flags; 7184640e27SKaricheri, Muralidharan struct list_head node; 7284640e27SKaricheri, Muralidharan }; 7384640e27SKaricheri, Muralidharan 746a8162e9SMichael Scherban struct netcp_stats { 756a8162e9SMichael Scherban struct u64_stats_sync syncp_rx ____cacheline_aligned_in_smp; 766a8162e9SMichael Scherban u64 rx_packets; 776a8162e9SMichael Scherban u64 rx_bytes; 786a8162e9SMichael Scherban u32 rx_errors; 796a8162e9SMichael Scherban u32 rx_dropped; 806a8162e9SMichael Scherban 816a8162e9SMichael Scherban struct u64_stats_sync syncp_tx ____cacheline_aligned_in_smp; 826a8162e9SMichael Scherban u64 tx_packets; 836a8162e9SMichael Scherban u64 tx_bytes; 846a8162e9SMichael Scherban u32 tx_errors; 856a8162e9SMichael Scherban u32 tx_dropped; 866a8162e9SMichael Scherban }; 876a8162e9SMichael Scherban 8884640e27SKaricheri, Muralidharan struct netcp_intf { 8984640e27SKaricheri, Muralidharan struct device *dev; 9084640e27SKaricheri, Muralidharan struct device *ndev_dev; 9184640e27SKaricheri, Muralidharan struct net_device *ndev; 9284640e27SKaricheri, Muralidharan bool big_endian; 9384640e27SKaricheri, Muralidharan unsigned int tx_compl_qid; 9484640e27SKaricheri, Muralidharan void *tx_pool; 9584640e27SKaricheri, Muralidharan struct list_head txhook_list_head; 9684640e27SKaricheri, Muralidharan unsigned int tx_pause_threshold; 9784640e27SKaricheri, Muralidharan void *tx_compl_q; 9884640e27SKaricheri, Muralidharan 9984640e27SKaricheri, Muralidharan unsigned int tx_resume_threshold; 10084640e27SKaricheri, Muralidharan void *rx_queue; 10184640e27SKaricheri, Muralidharan void *rx_pool; 10284640e27SKaricheri, Muralidharan struct list_head rxhook_list_head; 10384640e27SKaricheri, Muralidharan unsigned int rx_queue_id; 10484640e27SKaricheri, Muralidharan void *rx_fdq[KNAV_DMA_FDQ_PER_CHAN]; 10584640e27SKaricheri, Muralidharan struct napi_struct rx_napi; 10684640e27SKaricheri, Muralidharan struct napi_struct tx_napi; 1074cd85a61SKaricheri, Muralidharan #define ETH_SW_CAN_REMOVE_ETH_FCS BIT(0) 1084cd85a61SKaricheri, Muralidharan u32 hw_cap; 10984640e27SKaricheri, Muralidharan 1106a8162e9SMichael Scherban /* 64-bit netcp stats */ 1116a8162e9SMichael Scherban struct netcp_stats stats; 1126a8162e9SMichael Scherban 11384640e27SKaricheri, Muralidharan void *rx_channel; 11484640e27SKaricheri, Muralidharan const char *dma_chan_name; 11584640e27SKaricheri, Muralidharan u32 rx_pool_size; 11684640e27SKaricheri, Muralidharan u32 rx_pool_region_id; 11784640e27SKaricheri, Muralidharan u32 tx_pool_size; 11884640e27SKaricheri, Muralidharan u32 tx_pool_region_id; 11984640e27SKaricheri, Muralidharan struct list_head module_head; 12084640e27SKaricheri, Muralidharan struct list_head interface_list; 12184640e27SKaricheri, Muralidharan struct list_head addr_list; 12284640e27SKaricheri, Muralidharan bool netdev_registered; 12384640e27SKaricheri, Muralidharan bool primary_module_attached; 12484640e27SKaricheri, Muralidharan 12584640e27SKaricheri, Muralidharan /* Lock used for protecting Rx/Tx hook list management */ 12684640e27SKaricheri, Muralidharan spinlock_t lock; 12784640e27SKaricheri, Muralidharan struct netcp_device *netcp_device; 12884640e27SKaricheri, Muralidharan struct device_node *node_interface; 12984640e27SKaricheri, Muralidharan 13084640e27SKaricheri, Muralidharan /* DMA configuration data */ 13184640e27SKaricheri, Muralidharan u32 msg_enable; 13284640e27SKaricheri, Muralidharan u32 rx_queue_depths[KNAV_DMA_FDQ_PER_CHAN]; 13384640e27SKaricheri, Muralidharan }; 13484640e27SKaricheri, Muralidharan 13584640e27SKaricheri, Muralidharan #define NETCP_PSDATA_LEN KNAV_DMA_NUM_PS_WORDS 13684640e27SKaricheri, Muralidharan struct netcp_packet { 13784640e27SKaricheri, Muralidharan struct sk_buff *skb; 1389dd2d6c5SArnd Bergmann __le32 *epib; 13984640e27SKaricheri, Muralidharan u32 *psdata; 14069d707d0SKaricheri, Muralidharan u32 eflags; 14184640e27SKaricheri, Muralidharan unsigned int psdata_len; 14284640e27SKaricheri, Muralidharan struct netcp_intf *netcp; 14384640e27SKaricheri, Muralidharan struct netcp_tx_pipe *tx_pipe; 14484640e27SKaricheri, Muralidharan bool rxtstamp_complete; 14584640e27SKaricheri, Muralidharan void *ts_context; 14684640e27SKaricheri, Muralidharan 1476246168bSWingMan Kwok void (*txtstamp)(void *ctx, struct sk_buff *skb); 14884640e27SKaricheri, Muralidharan }; 14984640e27SKaricheri, Muralidharan 15084640e27SKaricheri, Muralidharan static inline u32 *netcp_push_psdata(struct netcp_packet *p_info, 15184640e27SKaricheri, Muralidharan unsigned int bytes) 15284640e27SKaricheri, Muralidharan { 15384640e27SKaricheri, Muralidharan u32 *buf; 15484640e27SKaricheri, Muralidharan unsigned int words; 15584640e27SKaricheri, Muralidharan 15684640e27SKaricheri, Muralidharan if ((bytes & 0x03) != 0) 15784640e27SKaricheri, Muralidharan return NULL; 15884640e27SKaricheri, Muralidharan words = bytes >> 2; 15984640e27SKaricheri, Muralidharan 16084640e27SKaricheri, Muralidharan if ((p_info->psdata_len + words) > NETCP_PSDATA_LEN) 16184640e27SKaricheri, Muralidharan return NULL; 16284640e27SKaricheri, Muralidharan 16384640e27SKaricheri, Muralidharan p_info->psdata_len += words; 16484640e27SKaricheri, Muralidharan buf = &p_info->psdata[NETCP_PSDATA_LEN - p_info->psdata_len]; 16584640e27SKaricheri, Muralidharan return buf; 16684640e27SKaricheri, Muralidharan } 16784640e27SKaricheri, Muralidharan 16884640e27SKaricheri, Muralidharan static inline int netcp_align_psdata(struct netcp_packet *p_info, 16984640e27SKaricheri, Muralidharan unsigned int byte_align) 17084640e27SKaricheri, Muralidharan { 17184640e27SKaricheri, Muralidharan int padding; 17284640e27SKaricheri, Muralidharan 17384640e27SKaricheri, Muralidharan switch (byte_align) { 17484640e27SKaricheri, Muralidharan case 0: 17584640e27SKaricheri, Muralidharan padding = -EINVAL; 17684640e27SKaricheri, Muralidharan break; 17784640e27SKaricheri, Muralidharan case 1: 17884640e27SKaricheri, Muralidharan case 2: 17984640e27SKaricheri, Muralidharan case 4: 18084640e27SKaricheri, Muralidharan padding = 0; 18184640e27SKaricheri, Muralidharan break; 18284640e27SKaricheri, Muralidharan case 8: 18384640e27SKaricheri, Muralidharan padding = (p_info->psdata_len << 2) % 8; 18484640e27SKaricheri, Muralidharan break; 18584640e27SKaricheri, Muralidharan case 16: 18684640e27SKaricheri, Muralidharan padding = (p_info->psdata_len << 2) % 16; 18784640e27SKaricheri, Muralidharan break; 18884640e27SKaricheri, Muralidharan default: 18984640e27SKaricheri, Muralidharan padding = (p_info->psdata_len << 2) % byte_align; 19084640e27SKaricheri, Muralidharan break; 19184640e27SKaricheri, Muralidharan } 19284640e27SKaricheri, Muralidharan return padding; 19384640e27SKaricheri, Muralidharan } 19484640e27SKaricheri, Muralidharan 19584640e27SKaricheri, Muralidharan struct netcp_module { 19684640e27SKaricheri, Muralidharan const char *name; 19784640e27SKaricheri, Muralidharan struct module *owner; 19884640e27SKaricheri, Muralidharan bool primary; 19984640e27SKaricheri, Muralidharan 20084640e27SKaricheri, Muralidharan /* probe/remove: called once per NETCP instance */ 20184640e27SKaricheri, Muralidharan int (*probe)(struct netcp_device *netcp_device, 20284640e27SKaricheri, Muralidharan struct device *device, struct device_node *node, 20384640e27SKaricheri, Muralidharan void **inst_priv); 20484640e27SKaricheri, Muralidharan int (*remove)(struct netcp_device *netcp_device, void *inst_priv); 20584640e27SKaricheri, Muralidharan 20684640e27SKaricheri, Muralidharan /* attach/release: called once per network interface */ 20784640e27SKaricheri, Muralidharan int (*attach)(void *inst_priv, struct net_device *ndev, 20884640e27SKaricheri, Muralidharan struct device_node *node, void **intf_priv); 20984640e27SKaricheri, Muralidharan int (*release)(void *intf_priv); 21084640e27SKaricheri, Muralidharan int (*open)(void *intf_priv, struct net_device *ndev); 21184640e27SKaricheri, Muralidharan int (*close)(void *intf_priv, struct net_device *ndev); 21284640e27SKaricheri, Muralidharan int (*add_addr)(void *intf_priv, struct netcp_addr *naddr); 21384640e27SKaricheri, Muralidharan int (*del_addr)(void *intf_priv, struct netcp_addr *naddr); 21484640e27SKaricheri, Muralidharan int (*add_vid)(void *intf_priv, int vid); 21584640e27SKaricheri, Muralidharan int (*del_vid)(void *intf_priv, int vid); 21684640e27SKaricheri, Muralidharan int (*ioctl)(void *intf_priv, struct ifreq *req, int cmd); 21784640e27SKaricheri, Muralidharan 21884640e27SKaricheri, Muralidharan /* used internally */ 21984640e27SKaricheri, Muralidharan struct list_head module_list; 22084640e27SKaricheri, Muralidharan struct list_head interface_list; 22184640e27SKaricheri, Muralidharan }; 22284640e27SKaricheri, Muralidharan 22384640e27SKaricheri, Muralidharan int netcp_register_module(struct netcp_module *module); 22484640e27SKaricheri, Muralidharan void netcp_unregister_module(struct netcp_module *module); 22584640e27SKaricheri, Muralidharan void *netcp_module_get_intf_data(struct netcp_module *module, 22684640e27SKaricheri, Muralidharan struct netcp_intf *intf); 22784640e27SKaricheri, Muralidharan 22884640e27SKaricheri, Muralidharan int netcp_txpipe_init(struct netcp_tx_pipe *tx_pipe, 22984640e27SKaricheri, Muralidharan struct netcp_device *netcp_device, 23084640e27SKaricheri, Muralidharan const char *dma_chan_name, unsigned int dma_queue_id); 23184640e27SKaricheri, Muralidharan int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe); 23284640e27SKaricheri, Muralidharan int netcp_txpipe_close(struct netcp_tx_pipe *tx_pipe); 23384640e27SKaricheri, Muralidharan 23484640e27SKaricheri, Muralidharan typedef int netcp_hook_rtn(int order, void *data, struct netcp_packet *packet); 23584640e27SKaricheri, Muralidharan int netcp_register_txhook(struct netcp_intf *netcp_priv, int order, 23684640e27SKaricheri, Muralidharan netcp_hook_rtn *hook_rtn, void *hook_data); 23784640e27SKaricheri, Muralidharan int netcp_unregister_txhook(struct netcp_intf *netcp_priv, int order, 23884640e27SKaricheri, Muralidharan netcp_hook_rtn *hook_rtn, void *hook_data); 23984640e27SKaricheri, Muralidharan int netcp_register_rxhook(struct netcp_intf *netcp_priv, int order, 24084640e27SKaricheri, Muralidharan netcp_hook_rtn *hook_rtn, void *hook_data); 24184640e27SKaricheri, Muralidharan int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order, 24284640e27SKaricheri, Muralidharan netcp_hook_rtn *hook_rtn, void *hook_data); 24384640e27SKaricheri, Muralidharan void *netcp_device_find_module(struct netcp_device *netcp_device, 24484640e27SKaricheri, Muralidharan const char *name); 24584640e27SKaricheri, Muralidharan 24684640e27SKaricheri, Muralidharan /* SGMII functions */ 24784640e27SKaricheri, Muralidharan int netcp_sgmii_reset(void __iomem *sgmii_ofs, int port); 2487025e88aSWingMan Kwok bool netcp_sgmii_rtreset(void __iomem *sgmii_ofs, int port, bool set); 24984640e27SKaricheri, Muralidharan int netcp_sgmii_get_port_link(void __iomem *sgmii_ofs, int port); 25084640e27SKaricheri, Muralidharan int netcp_sgmii_config(void __iomem *sgmii_ofs, int port, u32 interface); 25184640e27SKaricheri, Muralidharan 25284640e27SKaricheri, Muralidharan /* XGBE SERDES init functions */ 25384640e27SKaricheri, Muralidharan int netcp_xgbe_serdes_init(void __iomem *serdes_regs, void __iomem *xgbe_regs); 25484640e27SKaricheri, Muralidharan 25584640e27SKaricheri, Muralidharan #endif /* __NETCP_H__ */ 256