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