1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
|
/* SPDX-License-Identifier: GPL-2.0 */
/*
* 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>
*/
#ifndef __NETCP_H__
#define __NETCP_H__
#include <linux/netdevice.h>
#include <linux/soc/ti/knav_dma.h>
#include <linux/u64_stats_sync.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 RGMII_LINK_MAC_PHY 5
#define RGMII_LINK_MAC_PHY_NO_MDIO 7
#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;
/* To port for packet forwarded to switch. Used only by ethss */
u8 switch_to_port;
#define SWITCH_TO_PORT_IN_TAGINFO BIT(0)
u8 flags;
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_stats {
struct u64_stats_sync syncp_rx ____cacheline_aligned_in_smp;
u64 rx_packets;
u64 rx_bytes;
u32 rx_errors;
u32 rx_dropped;
struct u64_stats_sync syncp_tx ____cacheline_aligned_in_smp;
u64 tx_packets;
u64 tx_bytes;
u32 tx_errors;
u32 tx_dropped;
};
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];
struct napi_struct rx_napi;
struct napi_struct tx_napi;
#define ETH_SW_CAN_REMOVE_ETH_FCS BIT(0)
u32 hw_cap;
/* 64-bit netcp stats */
struct netcp_stats stats;
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;
__le32 *epib;
u32 *psdata;
u32 eflags;
unsigned int psdata_len;
struct netcp_intf *netcp;
struct netcp_tx_pipe *tx_pipe;
bool rxtstamp_complete;
void *ts_context;
void (*txtstamp)(void *ctx, struct sk_buff *skb);
};
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);
int (*set_rx_mode)(void *intf_priv, bool promisc);
/* 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);
bool netcp_sgmii_rtreset(void __iomem *sgmii_ofs, int port, bool set);
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__ */
|