David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame^] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 2 | /* |
| 3 | * NetCP driver local header |
| 4 | * |
| 5 | * Copyright (C) 2014 Texas Instruments Incorporated |
| 6 | * Authors: Sandeep Nair <sandeep_n@ti.com> |
| 7 | * Sandeep Paulraj <s-paulraj@ti.com> |
| 8 | * Cyril Chemparathy <cyril@ti.com> |
| 9 | * Santosh Shilimkar <santosh.shilimkar@ti.com> |
| 10 | * Wingman Kwok <w-kwok2@ti.com> |
| 11 | * Murali Karicheri <m-karicheri2@ti.com> |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 12 | */ |
| 13 | #ifndef __NETCP_H__ |
| 14 | #define __NETCP_H__ |
| 15 | |
| 16 | #include <linux/netdevice.h> |
| 17 | #include <linux/soc/ti/knav_dma.h> |
| 18 | #include <linux/u64_stats_sync.h> |
| 19 | |
| 20 | /* Maximum Ethernet frame size supported by Keystone switch */ |
| 21 | #define NETCP_MAX_FRAME_SIZE 9504 |
| 22 | |
| 23 | #define SGMII_LINK_MAC_MAC_AUTONEG 0 |
| 24 | #define SGMII_LINK_MAC_PHY 1 |
| 25 | #define SGMII_LINK_MAC_MAC_FORCED 2 |
| 26 | #define SGMII_LINK_MAC_FIBER 3 |
| 27 | #define SGMII_LINK_MAC_PHY_NO_MDIO 4 |
| 28 | #define RGMII_LINK_MAC_PHY 5 |
| 29 | #define RGMII_LINK_MAC_PHY_NO_MDIO 7 |
| 30 | #define XGMII_LINK_MAC_PHY 10 |
| 31 | #define XGMII_LINK_MAC_MAC_FORCED 11 |
| 32 | |
| 33 | struct netcp_device; |
| 34 | |
| 35 | struct netcp_tx_pipe { |
| 36 | struct netcp_device *netcp_device; |
| 37 | void *dma_queue; |
| 38 | unsigned int dma_queue_id; |
| 39 | /* To port for packet forwarded to switch. Used only by ethss */ |
| 40 | u8 switch_to_port; |
| 41 | #define SWITCH_TO_PORT_IN_TAGINFO BIT(0) |
| 42 | u8 flags; |
| 43 | void *dma_channel; |
| 44 | const char *dma_chan_name; |
| 45 | }; |
| 46 | |
| 47 | #define ADDR_NEW BIT(0) |
| 48 | #define ADDR_VALID BIT(1) |
| 49 | |
| 50 | enum netcp_addr_type { |
| 51 | ADDR_ANY, |
| 52 | ADDR_DEV, |
| 53 | ADDR_UCAST, |
| 54 | ADDR_MCAST, |
| 55 | ADDR_BCAST |
| 56 | }; |
| 57 | |
| 58 | struct netcp_addr { |
| 59 | struct netcp_intf *netcp; |
| 60 | unsigned char addr[ETH_ALEN]; |
| 61 | enum netcp_addr_type type; |
| 62 | unsigned int flags; |
| 63 | struct list_head node; |
| 64 | }; |
| 65 | |
| 66 | struct netcp_stats { |
| 67 | struct u64_stats_sync syncp_rx ____cacheline_aligned_in_smp; |
| 68 | u64 rx_packets; |
| 69 | u64 rx_bytes; |
| 70 | u32 rx_errors; |
| 71 | u32 rx_dropped; |
| 72 | |
| 73 | struct u64_stats_sync syncp_tx ____cacheline_aligned_in_smp; |
| 74 | u64 tx_packets; |
| 75 | u64 tx_bytes; |
| 76 | u32 tx_errors; |
| 77 | u32 tx_dropped; |
| 78 | }; |
| 79 | |
| 80 | struct netcp_intf { |
| 81 | struct device *dev; |
| 82 | struct device *ndev_dev; |
| 83 | struct net_device *ndev; |
| 84 | bool big_endian; |
| 85 | unsigned int tx_compl_qid; |
| 86 | void *tx_pool; |
| 87 | struct list_head txhook_list_head; |
| 88 | unsigned int tx_pause_threshold; |
| 89 | void *tx_compl_q; |
| 90 | |
| 91 | unsigned int tx_resume_threshold; |
| 92 | void *rx_queue; |
| 93 | void *rx_pool; |
| 94 | struct list_head rxhook_list_head; |
| 95 | unsigned int rx_queue_id; |
| 96 | void *rx_fdq[KNAV_DMA_FDQ_PER_CHAN]; |
| 97 | struct napi_struct rx_napi; |
| 98 | struct napi_struct tx_napi; |
| 99 | #define ETH_SW_CAN_REMOVE_ETH_FCS BIT(0) |
| 100 | u32 hw_cap; |
| 101 | |
| 102 | /* 64-bit netcp stats */ |
| 103 | struct netcp_stats stats; |
| 104 | |
| 105 | void *rx_channel; |
| 106 | const char *dma_chan_name; |
| 107 | u32 rx_pool_size; |
| 108 | u32 rx_pool_region_id; |
| 109 | u32 tx_pool_size; |
| 110 | u32 tx_pool_region_id; |
| 111 | struct list_head module_head; |
| 112 | struct list_head interface_list; |
| 113 | struct list_head addr_list; |
| 114 | bool netdev_registered; |
| 115 | bool primary_module_attached; |
| 116 | |
| 117 | /* Lock used for protecting Rx/Tx hook list management */ |
| 118 | spinlock_t lock; |
| 119 | struct netcp_device *netcp_device; |
| 120 | struct device_node *node_interface; |
| 121 | |
| 122 | /* DMA configuration data */ |
| 123 | u32 msg_enable; |
| 124 | u32 rx_queue_depths[KNAV_DMA_FDQ_PER_CHAN]; |
| 125 | }; |
| 126 | |
| 127 | #define NETCP_PSDATA_LEN KNAV_DMA_NUM_PS_WORDS |
| 128 | struct netcp_packet { |
| 129 | struct sk_buff *skb; |
| 130 | __le32 *epib; |
| 131 | u32 *psdata; |
| 132 | u32 eflags; |
| 133 | unsigned int psdata_len; |
| 134 | struct netcp_intf *netcp; |
| 135 | struct netcp_tx_pipe *tx_pipe; |
| 136 | bool rxtstamp_complete; |
| 137 | void *ts_context; |
| 138 | |
| 139 | void (*txtstamp)(void *ctx, struct sk_buff *skb); |
| 140 | }; |
| 141 | |
| 142 | static inline u32 *netcp_push_psdata(struct netcp_packet *p_info, |
| 143 | unsigned int bytes) |
| 144 | { |
| 145 | u32 *buf; |
| 146 | unsigned int words; |
| 147 | |
| 148 | if ((bytes & 0x03) != 0) |
| 149 | return NULL; |
| 150 | words = bytes >> 2; |
| 151 | |
| 152 | if ((p_info->psdata_len + words) > NETCP_PSDATA_LEN) |
| 153 | return NULL; |
| 154 | |
| 155 | p_info->psdata_len += words; |
| 156 | buf = &p_info->psdata[NETCP_PSDATA_LEN - p_info->psdata_len]; |
| 157 | return buf; |
| 158 | } |
| 159 | |
| 160 | static inline int netcp_align_psdata(struct netcp_packet *p_info, |
| 161 | unsigned int byte_align) |
| 162 | { |
| 163 | int padding; |
| 164 | |
| 165 | switch (byte_align) { |
| 166 | case 0: |
| 167 | padding = -EINVAL; |
| 168 | break; |
| 169 | case 1: |
| 170 | case 2: |
| 171 | case 4: |
| 172 | padding = 0; |
| 173 | break; |
| 174 | case 8: |
| 175 | padding = (p_info->psdata_len << 2) % 8; |
| 176 | break; |
| 177 | case 16: |
| 178 | padding = (p_info->psdata_len << 2) % 16; |
| 179 | break; |
| 180 | default: |
| 181 | padding = (p_info->psdata_len << 2) % byte_align; |
| 182 | break; |
| 183 | } |
| 184 | return padding; |
| 185 | } |
| 186 | |
| 187 | struct netcp_module { |
| 188 | const char *name; |
| 189 | struct module *owner; |
| 190 | bool primary; |
| 191 | |
| 192 | /* probe/remove: called once per NETCP instance */ |
| 193 | int (*probe)(struct netcp_device *netcp_device, |
| 194 | struct device *device, struct device_node *node, |
| 195 | void **inst_priv); |
| 196 | int (*remove)(struct netcp_device *netcp_device, void *inst_priv); |
| 197 | |
| 198 | /* attach/release: called once per network interface */ |
| 199 | int (*attach)(void *inst_priv, struct net_device *ndev, |
| 200 | struct device_node *node, void **intf_priv); |
| 201 | int (*release)(void *intf_priv); |
| 202 | int (*open)(void *intf_priv, struct net_device *ndev); |
| 203 | int (*close)(void *intf_priv, struct net_device *ndev); |
| 204 | int (*add_addr)(void *intf_priv, struct netcp_addr *naddr); |
| 205 | int (*del_addr)(void *intf_priv, struct netcp_addr *naddr); |
| 206 | int (*add_vid)(void *intf_priv, int vid); |
| 207 | int (*del_vid)(void *intf_priv, int vid); |
| 208 | int (*ioctl)(void *intf_priv, struct ifreq *req, int cmd); |
| 209 | int (*set_rx_mode)(void *intf_priv, bool promisc); |
| 210 | |
| 211 | /* used internally */ |
| 212 | struct list_head module_list; |
| 213 | struct list_head interface_list; |
| 214 | }; |
| 215 | |
| 216 | int netcp_register_module(struct netcp_module *module); |
| 217 | void netcp_unregister_module(struct netcp_module *module); |
| 218 | void *netcp_module_get_intf_data(struct netcp_module *module, |
| 219 | struct netcp_intf *intf); |
| 220 | |
| 221 | int netcp_txpipe_init(struct netcp_tx_pipe *tx_pipe, |
| 222 | struct netcp_device *netcp_device, |
| 223 | const char *dma_chan_name, unsigned int dma_queue_id); |
| 224 | int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe); |
| 225 | int netcp_txpipe_close(struct netcp_tx_pipe *tx_pipe); |
| 226 | |
| 227 | typedef int netcp_hook_rtn(int order, void *data, struct netcp_packet *packet); |
| 228 | int netcp_register_txhook(struct netcp_intf *netcp_priv, int order, |
| 229 | netcp_hook_rtn *hook_rtn, void *hook_data); |
| 230 | int netcp_unregister_txhook(struct netcp_intf *netcp_priv, int order, |
| 231 | netcp_hook_rtn *hook_rtn, void *hook_data); |
| 232 | int netcp_register_rxhook(struct netcp_intf *netcp_priv, int order, |
| 233 | netcp_hook_rtn *hook_rtn, void *hook_data); |
| 234 | int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order, |
| 235 | netcp_hook_rtn *hook_rtn, void *hook_data); |
| 236 | void *netcp_device_find_module(struct netcp_device *netcp_device, |
| 237 | const char *name); |
| 238 | |
| 239 | /* SGMII functions */ |
| 240 | int netcp_sgmii_reset(void __iomem *sgmii_ofs, int port); |
| 241 | bool netcp_sgmii_rtreset(void __iomem *sgmii_ofs, int port, bool set); |
| 242 | int netcp_sgmii_get_port_link(void __iomem *sgmii_ofs, int port); |
| 243 | int netcp_sgmii_config(void __iomem *sgmii_ofs, int port, u32 interface); |
| 244 | |
| 245 | /* XGBE SERDES init functions */ |
| 246 | int netcp_xgbe_serdes_init(void __iomem *serdes_regs, void __iomem *xgbe_regs); |
| 247 | |
| 248 | #endif /* __NETCP_H__ */ |