1 /****************************************************************************
2 * Solarflare driver for Xen network acceleration
4 * Copyright 2006-2008: Solarflare Communications Inc,
5 * 9501 Jeronimo Road, Suite 250,
6 * Irvine, CA 92618, USA
8 * Maintained by Solarflare Communications <linux-xen-drivers@solarflare.com>
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.
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.
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 ****************************************************************************
25 #ifndef NETBACK_ACCEL_H
26 #define NETBACK_ACCEL_H
28 #include <linux/version.h>
29 #include <linux/slab.h>
31 #include <linux/tcp.h>
32 #include <linux/udp.h>
34 #include <linux/netdevice.h>
35 #include <linux/etherdevice.h>
36 #include <linux/mutex.h>
37 #include <linux/wait.h>
39 #include <xen/xenbus.h>
41 #include "accel_shared_fifo.h"
42 #include "accel_msg_iface.h"
43 #include "accel_util.h"
45 /**************************************************************************
47 **************************************************************************/
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;
55 #define NETBACK_ACCEL_STATS 1
57 #if NETBACK_ACCEL_STATS
58 #define NETBACK_ACCEL_STATS_OP(x) x
60 #define NETBACK_ACCEL_STATS_OP(x)
63 /*! Statistics for a given backend */
64 struct netback_accel_stats {
65 /*! Number of eventq wakeup events */
67 /*! Number of eventq timeout events */
69 /*! Number of filters used */
71 /*! Number of buffer pages registered */
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;
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 */
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;
98 /*! Watches on xenstore */
99 struct xenbus_watch domu_accel_watch;
100 struct xenbus_watch config_accel_watch;
102 /*! Pointer to whatever device cookie ties us in to the hypervisor */
105 /*! FIFO indices. Next page is msg FIFOs */
106 struct net_accel_shared_page *shared_page;
108 /*! Defer control message processing */
109 struct work_struct handle_msg;
111 /*! Identifies other end VM and interface.*/
115 /*!< To unmap the shared pages */
116 void *sh_pages_unmap;
118 /* Resource tracking */
119 /*! Limits on H/W & Dom0 resources */
120 struct netback_accel_limits quotas;
122 /* Hardware resources */
123 /*! The H/W type of associated NIC */
124 enum net_accel_hw_type hw_type;
125 /*! State of allocation */
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 *);
132 /*! The physical/real net_dev for this interface */
133 struct net_device *net_dev;
135 /*! Magic pointer to locate state in fowarding table */
139 sh_msg_fifo2 to_domU;
141 sh_msg_fifo2 from_domU;
143 /*! General notification channel id */
145 /*! General notification channel irq */
148 /*! Event channel id dedicated to network packet interrupts. */
150 /*! Event channel irq dedicated to network packets interrupts */
153 /*! The MAC address the frontend goes by. */
155 /*! Driver name of associated NIC */
158 /*! Array of pointers to buffer pages mapped */
159 grant_handle_t *buffer_maps;
161 /*! Index into buffer_maps */
162 int buffer_maps_index;
163 /*! Max number of pages that domU is allowed/will request to map */
166 /*! Pointer to hardware specific private area */
169 /*! Wait queue for changes in accelstate. */
170 wait_queue_head_t state_wait_queue;
172 /*! Current state of the frontend according to the xenbus
174 XenbusState frontend_state;
176 /*! Current state of this backend. */
177 XenbusState backend_state;
179 /*! Non-zero if the backend is being removed. */
182 /*! Non-zero if the setup_vnic has been called. */
185 #if NETBACK_ACCEL_STATS
186 struct netback_accel_stats stats;
188 #if defined(CONFIG_DEBUG_FS)
190 struct dentry *dbfs_dir;
191 struct netback_accel_dbfs dbfs;
195 struct netback_accel *next_bend;
200 * Values for netback_accel.hw_state. States of resource allocation
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)
210 /*! Filtering specification. This assumes that for VNIC support we
211 * will always want wildcard entries, so only specifies the
212 * destination IP/port
214 struct netback_accel_filter_spec {
215 /*! Internal, used to access efx_vi API */
218 /*! Destination IP in network order */
220 /*! Destination port in network order */
229 /**************************************************************************
231 **************************************************************************/
233 /*! \brief Start up all the acceleration plugins
235 * \return 0 on success, an errno on failure
237 extern int netback_accel_init_accel(void);
239 /*! \brief Shut down all the acceleration plugins
241 extern void netback_accel_shutdown_accel(void);
244 /**************************************************************************
246 **************************************************************************/
248 /*! \brief Init the forwarding infrastructure
249 * \return 0 on success, or -ENOMEM if it couldn't get memory for the
252 extern int netback_accel_init_fwd(void);
254 /*! \brief Shut down the forwarding and free memory. */
255 extern void netback_accel_shutdown_fwd(void);
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);
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
267 extern int netback_accel_fwd_add(const __u8 *mac, void *context,
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
274 extern void netback_accel_fwd_remove(const __u8 *mac, void *fwd_priv);
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.
281 extern int netback_accel_fwd_set_context(const __u8 *mac, void *context,
284 /**************************************************************************
286 **************************************************************************/
289 /*! \brief Send the start-of-day message that handshakes with the VNIC
290 * and tells it its MAC address.
292 * \param bend The back end driver data structure
293 * \param version The version of communication to use, e.g. NET_ACCEL_MSG_VERSION
295 extern void netback_accel_msg_tx_hello(struct netback_accel *bend,
298 /*! \brief Send a "there's a new local mac address" message
300 * \param bend The back end driver data structure for the vnic to send
302 * \param mac Pointer to the new mac address
304 extern void netback_accel_msg_tx_new_localmac(struct netback_accel *bend,
307 /*! \brief Send a "a mac address that was local has gone away" message
309 * \param bend The back end driver data structure for the vnic to send
311 * \param mac Pointer to the old mac address
313 extern void netback_accel_msg_tx_old_localmac(struct netback_accel *bend,
316 extern void netback_accel_set_interface_state(struct netback_accel *bend,
319 /*! \brief Process the message queue for a bend that has just
322 * Demultiplexs an interrupt from the front end driver, taking
323 * messages from the fifo and taking appropriate action.
325 * \param bend The back end driver data structure
327 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
328 extern void netback_accel_msg_rx_handler(struct work_struct *arg);
330 extern void netback_accel_msg_rx_handler(void *bend_void);
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;
340 /*! \brief Probe a new network interface. */
341 extern int netback_accel_probe(struct xenbus_device *dev);
343 /*! \brief Remove a network interface. */
344 extern int netback_accel_remove(struct xenbus_device *dev);
346 /*! \brief Shutdown all accelerator backends */
347 extern void netback_accel_shutdown_bends(void);
349 /*! \brief Initiate the xenbus state teardown handshake */
350 extern void netback_accel_set_closing(struct netback_accel *bend);
352 /**************************************************************************
353 * From accel_debugfs.c
354 **************************************************************************/
355 /*! Global statistics */
356 struct netback_accel_global_stats {
357 /*! Number of TX packets seen through driverlink */
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 */
363 /*! Number of mac addresses we are forwarding to */
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;
375 #if NETBACK_ACCEL_STATS
376 extern struct netback_accel_global_stats global_stats;
379 /*! \brief Initialise the debugfs root and populate with global stats */
380 extern void netback_accel_debugfs_init(void);
382 /*! \brief Remove our debugfs root directory */
383 extern void netback_accel_debugfs_fini(void);
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);
390 #endif /* NETBACK_ACCEL_H */