Blame view

kernel/linux-rt-4.4.41/drivers/net/ethernet/ti/netcp.h 7.64 KB
5113f6f70   김현기   kernel add
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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
  /*
   * 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>
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License as
   * published by the Free Software Foundation version 2.
   *
   * This program is distributed "as is" WITHOUT ANY WARRANTY of any
   * kind, whether express or implied; without even the implied warranty
   * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   */
  #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
  /* to indicate netcp core should drop the packet */
  #define NETCP_TX_DROP			1
  
  #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_MAC_FORCED	6
  #define RGMII_LINK_MAC_PHY_NO_MDIO	7
  #define XGMII_LINK_MAC_PHY		10
  #define XGMII_LINK_MAC_MAC_FORCED	11
  
  #define NETCP_MAX_SUBQUEUES		32
  
  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_pool_info {
  	u32			num_descs;
  	u32			region_id;
  	unsigned int		pause_threshold;
  	unsigned int		resume_threshold;
  	void			*pool;
  };
  
  struct netcp_intf {
  	struct device		*dev;
  	struct device		*ndev_dev;
  	struct net_device	*ndev;
  	bool			big_endian;
  	bool			bridged;
  
  	u32			tx_subqueues;
  	unsigned int		tx_compl_qid;
  	u32			tx_compl_budget;
  	void			*tx_compl_q;
  	struct list_head	txhook_list_head;
  
  	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;
  	u32			rx_queue_depths[KNAV_DMA_FDQ_PER_CHAN];
  
  	/* Non Data path related stuffs below. In future, move any variable
  	 * if used on data path to above this for better cache line use
  	 */
  	void			*rx_channel;
  	const char		*dma_chan_name;
  	u32			rx_pool_size;
  	u32			rx_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;
  
  	struct netcp_pool_info	tx_pool[1];
  	/* NB: tx-pools (#tx-subqueues) are allocated dynamically */
  };
  
  #define	NETCP_EPIB_LEN			KNAV_DMA_NUM_EPIB_WORDS
  #define	NETCP_PSDATA_LEN		KNAV_DMA_NUM_PS_WORDS
  struct netcp_packet {
  	struct sk_buff		*skb;
  	u32			*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__ */