- Update Xen patches to 3.3-rc5 and c/s 1157.
[linux-flexiantxendom0-3.2.10.git] / drivers / xen / sfc_netback / accel.h
1 /****************************************************************************
2  * Solarflare driver for Xen network acceleration
3  *
4  * Copyright 2006-2008: Solarflare Communications Inc,
5  *                      9501 Jeronimo Road, Suite 250,
6  *                      Irvine, CA 92618, USA
7  *
8  * Maintained by Solarflare Communications <linux-xen-drivers@solarflare.com>
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License version 2 as published
12  * by the Free Software Foundation, incorporated herein by reference.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  ****************************************************************************
23  */
24
25 #ifndef NETBACK_ACCEL_H
26 #define NETBACK_ACCEL_H
27
28 #include <linux/version.h>
29 #include <linux/slab.h>
30 #include <linux/ip.h>
31 #include <linux/tcp.h>
32 #include <linux/udp.h>
33 #include <linux/in.h>
34 #include <linux/netdevice.h>
35 #include <linux/etherdevice.h>
36 #include <linux/mutex.h>
37 #include <linux/wait.h>
38
39 #include <xen/xenbus.h>
40
41 #include "accel_shared_fifo.h"
42 #include "accel_msg_iface.h"
43 #include "accel_util.h"
44
45 /**************************************************************************
46  * Datatypes
47  **************************************************************************/
48
49 #define NETBACK_ACCEL_DEFAULT_MAX_FILTERS (8)
50 #define NETBACK_ACCEL_DEFAULT_MAX_MCASTS (8)
51 #define NETBACK_ACCEL_DEFAULT_MAX_BUF_PAGES (384)
52 /* Variable to store module parameter for max_buf_pages */
53 extern unsigned sfc_netback_max_pages;
54
55 #define NETBACK_ACCEL_STATS 1
56
57 #if NETBACK_ACCEL_STATS
58 #define NETBACK_ACCEL_STATS_OP(x) x
59 #else
60 #define NETBACK_ACCEL_STATS_OP(x)
61 #endif
62
63 /*! Statistics for a given backend */
64 struct netback_accel_stats {
65         /*! Number of eventq wakeup events */
66         u64 evq_wakeups;
67         /*! Number of eventq timeout events */
68         u64 evq_timeouts;
69         /*! Number of filters used */
70         u32 num_filters;
71         /*! Number of buffer pages registered */
72         u32 num_buffer_pages;
73 };
74
75
76 /* Debug fs nodes for each of the above stats */
77 struct netback_accel_dbfs {
78         struct dentry *evq_wakeups;
79         struct dentry *evq_timeouts;
80         struct dentry *num_filters;
81         struct dentry *num_buffer_pages;
82 };
83
84
85 /*! Resource limits for a given NIC */
86 struct netback_accel_limits {
87         int max_filters;            /*!< Max. number of filters to use. */
88         int max_mcasts;      /*!< Max. number  of mcast subscriptions */
89         int max_buf_pages;        /*!< Max. number of pages of NIC buffers */
90 };
91
92
93 /*! The state for an instance of the back end driver. */
94 struct netback_accel {
95         /*! mutex to protect this state */
96         struct mutex bend_mutex;
97
98         /*! Watches on xenstore */
99         struct xenbus_watch domu_accel_watch;
100         struct xenbus_watch config_accel_watch;
101
102         /*! Pointer to whatever device cookie ties us in to the hypervisor */
103         void *hdev_data;
104
105         /*! FIFO indices. Next page is msg FIFOs */
106         struct net_accel_shared_page *shared_page;
107
108         /*! Defer control message processing */
109         struct work_struct handle_msg;
110
111         /*! Identifies other end VM and interface.*/
112         int far_end;
113         int vif_num;
114
115         /*!< To unmap the shared pages */
116         void *sh_pages_unmap;
117
118         /* Resource tracking */
119         /*! Limits on H/W & Dom0 resources */
120         struct netback_accel_limits quotas;
121
122         /* Hardware resources */
123         /*! The H/W type of associated NIC */
124         enum net_accel_hw_type hw_type;
125         /*! State of allocation */             
126         int hw_state;
127         /*! How to set up the acceleration for this hardware */
128         int (*accel_setup)(struct netback_accel *); 
129         /*! And how to stop it. */
130         void (*accel_shutdown)(struct netback_accel *);
131
132         /*! The physical/real net_dev for this interface */
133         struct net_device *net_dev;
134
135         /*! Magic pointer to locate state in fowarding table */
136         void *fwd_priv;
137
138         /*! Message FIFO */
139         sh_msg_fifo2 to_domU;
140         /*! Message FIFO */
141         sh_msg_fifo2 from_domU;
142
143         /*! General notification channel id */
144         int msg_channel;
145         /*! General notification channel irq */
146         int msg_channel_irq;
147
148         /*! Event channel id dedicated to network packet interrupts. */
149         int net_channel; 
150         /*! Event channel irq dedicated to network packets interrupts */
151         int net_channel_irq; 
152
153         /*! The MAC address the frontend goes by. */
154         u8 mac[ETH_ALEN];
155         /*! Driver name of associated NIC */
156         char *nicname;    
157
158         /*! Array of pointers to buffer pages mapped */
159         grant_handle_t *buffer_maps; 
160         u64 *buffer_addrs;
161         /*! Index into buffer_maps */
162         int buffer_maps_index; 
163         /*! Max number of pages that domU is allowed/will request to map */
164         int max_pages; 
165
166         /*! Pointer to hardware specific private area */
167         void *accel_hw_priv; 
168
169         /*! Wait queue for changes in accelstate. */
170         wait_queue_head_t state_wait_queue;
171
172         /*! Current state of the frontend according to the xenbus
173          *  watch. */
174         XenbusState frontend_state;
175
176         /*! Current state of this backend. */
177         XenbusState backend_state;
178
179         /*! Non-zero if the backend is being removed. */
180         int removing;
181
182         /*! Non-zero if the setup_vnic has been called. */
183         int vnic_is_setup;
184
185 #if NETBACK_ACCEL_STATS
186         struct netback_accel_stats stats;
187 #endif  
188 #if defined(CONFIG_DEBUG_FS)
189         char *dbfs_dir_name;
190         struct dentry *dbfs_dir;
191         struct netback_accel_dbfs dbfs;
192 #endif
193
194         /*! List */
195         struct netback_accel *next_bend;
196 };
197
198
199 /*
200  * Values for netback_accel.hw_state.  States of resource allocation
201  * we can go through
202  */
203 /*! No hardware has yet been allocated. */
204 #define NETBACK_ACCEL_RES_NONE  (0)
205 /*! Hardware has been allocated. */
206 #define NETBACK_ACCEL_RES_ALLOC (1)
207 #define NETBACK_ACCEL_RES_FILTER (2)
208 #define NETBACK_ACCEL_RES_HWINFO (3)
209
210 /*! Filtering specification. This assumes that for VNIC support we
211  *  will always want wildcard entries, so only specifies the
212  *  destination IP/port
213  */
214 struct netback_accel_filter_spec {
215         /*! Internal, used to access efx_vi API */
216         void *filter_handle; 
217
218         /*! Destination IP in network order */
219         u32 destip_be;
220         /*! Destination port in network order */
221         u16 destport_be;
222         /*! Mac address */
223         u8  mac[ETH_ALEN];
224         /*! TCP or UDP */
225         u8  proto;      
226 };
227
228
229 /**************************************************************************
230  * From accel.c
231  **************************************************************************/
232
233 /*! \brief Start up all the acceleration plugins 
234  *
235  * \return 0 on success, an errno on failure
236  */
237 extern int netback_accel_init_accel(void);
238
239 /*! \brief Shut down all the acceleration plugins 
240  */
241 extern void netback_accel_shutdown_accel(void);
242
243
244 /**************************************************************************
245  * From accel_fwd.c
246  **************************************************************************/
247
248 /*! \brief Init the forwarding infrastructure
249  * \return 0 on success, or -ENOMEM if it couldn't get memory for the
250  * forward table 
251  */
252 extern int netback_accel_init_fwd(void);
253
254 /*! \brief Shut down the forwarding and free memory. */
255 extern void netback_accel_shutdown_fwd(void);
256
257 /*! Initialise each nic port's fowarding table */
258 extern void *netback_accel_init_fwd_port(void);
259 extern void netback_accel_shutdown_fwd_port(void *fwd_priv);
260
261 /*! \brief Add an entry to the forwarding table. 
262  * \param mac : MAC address, used as hash key
263  * \param ctxt : value to associate with key (can be NULL, see
264  * netback_accel_fwd_set_context)
265  * \return 0 on success, -ENOMEM if table was full and could no grow it
266  */
267 extern int netback_accel_fwd_add(const __u8 *mac, void *context,
268                                  void *fwd_priv);
269
270 /*! \brief Remove an entry from the forwarding table. 
271  * \param mac : the MAC address to remove
272  * \return nothing: it is not an error if the mac was not in the table
273  */
274 extern void netback_accel_fwd_remove(const __u8 *mac, void *fwd_priv);
275
276 /*! \brief Set the context pointer for an existing fwd table entry.
277  * \param mac : key that is already present in the table
278  * \param context : new value to associate with key
279  * \return 0 on success, -ENOENT if mac not present in table.
280  */
281 extern int netback_accel_fwd_set_context(const __u8 *mac, void *context,
282                                          void *fwd_priv);
283
284 /**************************************************************************
285  * From accel_msg.c
286  **************************************************************************/
287
288
289 /*! \brief Send the start-of-day message that handshakes with the VNIC
290  *  and tells it its MAC address.
291  *
292  * \param bend The back end driver data structure
293  * \param version The version of communication to use, e.g. NET_ACCEL_MSG_VERSION
294  */
295 extern void netback_accel_msg_tx_hello(struct netback_accel *bend,
296                                        unsigned version);
297
298 /*! \brief Send a "there's a new local mac address" message 
299  *
300  * \param bend The back end driver data structure for the vnic to send
301  * the message to 
302  * \param mac Pointer to the new mac address
303  */
304 extern void netback_accel_msg_tx_new_localmac(struct netback_accel *bend,
305                                               const void *mac);
306
307 /*! \brief Send a "a mac address that was local has gone away" message 
308  *
309  * \param bend The back end driver data structure for the vnic to send
310  * the message to 
311  * \param mac Pointer to the old mac address
312  */
313 extern void netback_accel_msg_tx_old_localmac(struct netback_accel *bend,
314                                               const void *mac);
315
316 extern void netback_accel_set_interface_state(struct netback_accel *bend,
317                                               int up);
318
319 /*! \brief Process the message queue for a bend that has just
320  * interrupted.
321  * 
322  * Demultiplexs an interrupt from the front end driver, taking
323  * messages from the fifo and taking appropriate action.
324  * 
325  * \param bend The back end driver data structure
326  */
327 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
328 extern void netback_accel_msg_rx_handler(struct work_struct *arg);
329 #else
330 extern void netback_accel_msg_rx_handler(void *bend_void);
331 #endif
332
333 /**************************************************************************
334  * From accel_xenbus.c
335  **************************************************************************/
336 /*! List of all the bends currently in existence. */
337 extern struct netback_accel *bend_list;
338 extern struct mutex bend_list_mutex;
339
340 /*! \brief Probe a new network interface. */
341 extern int netback_accel_probe(struct xenbus_device *dev);
342
343 /*! \brief Remove a network interface. */
344 extern int netback_accel_remove(struct xenbus_device *dev);
345
346 /*! \brief Shutdown all accelerator backends */
347 extern void netback_accel_shutdown_bends(void);
348
349 /*! \brief Initiate the xenbus state teardown handshake */
350 extern void netback_accel_set_closing(struct netback_accel *bend);
351
352 /**************************************************************************
353  * From accel_debugfs.c
354  **************************************************************************/
355 /*! Global statistics */
356 struct netback_accel_global_stats {
357         /*! Number of TX packets seen through driverlink */
358         u64 dl_tx_packets;
359         /*! Number of TX packets seen through driverlink we didn't like */
360         u64 dl_tx_bad_packets;
361         /*! Number of RX packets seen through driverlink */
362         u64 dl_rx_packets;
363         /*! Number of mac addresses we are forwarding to */
364         u32 num_fwds;
365 };
366
367 /*! Debug fs entries for each of the above stats */
368 struct netback_accel_global_dbfs {
369         struct dentry *dl_tx_packets;
370         struct dentry *dl_tx_bad_packets;
371         struct dentry *dl_rx_packets;
372         struct dentry *num_fwds;
373 };
374
375 #if NETBACK_ACCEL_STATS
376 extern struct netback_accel_global_stats global_stats;
377 #endif
378
379 /*! \brief Initialise the debugfs root and populate with global stats */
380 extern void netback_accel_debugfs_init(void);
381
382 /*! \brief Remove our debugfs root directory */
383 extern void netback_accel_debugfs_fini(void);
384
385 /*! \brief Add per-bend statistics to debug fs */
386 extern int netback_accel_debugfs_create(struct netback_accel *bend);
387 /*! \brief Remove per-bend statistics from debug fs */
388 extern int netback_accel_debugfs_remove(struct netback_accel *bend);
389
390 #endif /* NETBACK_ACCEL_H */
391
392