1 /****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2005-2006 Fen Systems Ltd.
4 * Copyright 2005-2008 Solarflare Communications Inc.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation, incorporated herein by reference.
11 #ifndef EFX_DRIVERLINK_API_H
12 #define EFX_DRIVERLINK_API_H
14 #include <linux/list.h>
16 /* Forward declarations */
21 struct efx_dl_device_info;
23 /* An extra safeguard in addition to symbol versioning */
24 #define EFX_DRIVERLINK_API_VERSION 2
27 * struct efx_dl_driver - An Efx driverlink device driver
29 * A driverlink client defines and initializes as many instances of
30 * efx_dl_driver as required, registering each one with
31 * efx_dl_register_driver().
33 * @name: Name of the driver
34 * @probe: Called when device added
35 * The client should use the @def_info linked list and @silicon_rev
36 * to determine if they wish to attach to this device.
37 * Context: process, driverlink semaphore held
38 * @remove: Called when device removed
39 * The client must ensure the finish all operations with this
40 * device before returning from this method.
41 * Context: process, driverlink semaphore held
42 * @reset_suspend: Called before device is reset
43 * Called immediately before a hardware reset. The client must stop all
44 * hardware processing before returning from this method. Callbacks will
45 * be inactive when this method is called.
46 * Context: process, driverlink semaphore held. rtnl_lock may be held
47 * @reset_resume: Called after device is reset
48 * Called after a hardware reset. If @ok is true, the client should
49 * state and resume normal operations. If @ok is false, the client should
50 * abandon use of the hardware resources. remove() will still be called.
51 * Context: process, driverlink semaphore held. rtnl_lock may be held
53 struct efx_dl_driver {
56 int (*probe) (struct efx_dl_device *efx_dl_dev,
57 const struct net_device *net_dev,
58 const struct efx_dl_device_info *dev_info,
59 const char *silicon_rev);
60 void (*remove) (struct efx_dl_device *efx_dev);
61 void (*reset_suspend) (struct efx_dl_device *efx_dev);
62 void (*reset_resume) (struct efx_dl_device *efx_dev, int ok);
65 struct list_head node;
66 struct list_head device_list;
70 * enum efx_dl_device_info_type - Device information identifier.
72 * Used to identify each item in the &struct efx_dl_device_info linked list
73 * provided to each driverlink client in the probe() @dev_info member.
75 * @EFX_DL_FALCON_RESOURCES: Information type is &struct efx_dl_falcon_resources
77 enum efx_dl_device_info_type {
78 /** Falcon resources available for export */
79 EFX_DL_FALCON_RESOURCES = 0,
83 * struct efx_dl_device_info - device information structure
85 * @next: Link to next structure, if any
86 * @type: Type code for this structure
88 struct efx_dl_device_info {
89 struct efx_dl_device_info *next;
90 enum efx_dl_device_info_type type;
94 * enum efx_dl_falcon_resource_flags - Falcon resource information flags.
96 * Flags that describe hardware variations for the current Falcon device.
98 * @EFX_DL_FALCON_DUAL_FUNC: Port is dual-function.
99 * Certain silicon revisions have two pci functions, and require
100 * certain hardware resources to be accessed via the secondary
102 * @EFX_DL_FALCON_USE_MSI: Port is initialised to use MSI/MSI-X interrupts.
103 * Falcon supports traditional legacy interrupts and MSI/MSI-X
104 * interrupts. The choice is made at run time by the sfc driver, and
105 * notified to the clients by this enumeration
107 enum efx_dl_falcon_resource_flags {
108 EFX_DL_FALCON_DUAL_FUNC = 0x1,
109 EFX_DL_FALCON_USE_MSI = 0x2,
113 * struct efx_dl_falcon_resources - Falcon resource information.
115 * This structure describes Falcon hardware resources available for
116 * use by a driverlink driver.
118 * @hdr: Resource linked list header
119 * @biu_lock: Register access lock.
120 * Some Falcon revisions require register access for configuration
121 * registers to be serialised between ports and PCI functions.
122 * The sfc driver will provide the appropriate lock semantics for
123 * the underlying hardware.
124 * @buffer_table_min: First available buffer table entry
125 * @buffer_table_lim: Last available buffer table entry + 1
126 * @evq_timer_min: First available event queue with timer
127 * @evq_timer_lim: Last available event queue with timer + 1
128 * @evq_int_min: First available event queue with interrupt
129 * @evq_int_lim: Last available event queue with interrupt + 1
130 * @rxq_min: First available RX queue
131 * @rxq_lim: Last available RX queue + 1
132 * @txq_min: First available TX queue
133 * @txq_lim: Last available TX queue + 1
134 * @flags: Hardware variation flags
136 struct efx_dl_falcon_resources {
137 struct efx_dl_device_info hdr;
138 spinlock_t *biu_lock;
139 unsigned buffer_table_min;
140 unsigned buffer_table_lim;
141 unsigned evq_timer_min;
142 unsigned evq_timer_lim;
143 unsigned evq_int_min;
144 unsigned evq_int_lim;
149 enum efx_dl_falcon_resource_flags flags;
153 * struct efx_dl_device - An Efx driverlink device.
155 * @pci_dev: PCI device used by the sfc driver.
156 * @priv: Driver private data
157 * Driverlink clients can use this to store a pointer to their
158 * internal per-device data structure. Each (driver, device)
159 * tuple has a separate &struct efx_dl_device, so clients can use
160 * this @priv field independently.
161 * @driver: Efx driverlink driver for this device
163 struct efx_dl_device {
164 struct pci_dev *pci_dev;
166 struct efx_dl_driver *driver;
170 * enum efx_veto - Packet veto request flag.
172 * This is the return type for the rx_packet() and tx_packet() methods
173 * in &struct efx_dl_callbacks.
175 * @EFX_ALLOW_PACKET: Packet may be transmitted/received
176 * @EFX_VETO_PACKET: Packet must not be transmitted/received
179 EFX_ALLOW_PACKET = 0,
184 * struct efx_dl_callbacks - Efx callbacks
186 * This is a tighly controlled set of simple callbacks, that are attached
187 * to the sfc driver via efx_dl_register_callbacks(). They export just enough
188 * state to allow clients to make use of the available hardware resources.
190 * For efficiency, only one client can hook each callback. Since these
191 * callbacks are called on packet transmit and reception paths, and the
192 * sfc driver may have multiple tx and rx queues per port, clients should
193 * avoid acquiring locks or allocating memory.
195 * @tx_packet: Called when packet is about to be transmitted
196 * Called for every packet about to be transmitted, providing means
197 * for the client to snoop traffic, and veto transmission by returning
198 * %EFX_VETO_PACKET (the sfc driver will subsequently free the skb).
199 * Context: tasklet, netif_tx_lock held
200 * @rx_packet: Called when packet is received
201 * Called for every received packet (after LRO), allowing the client
202 * to snoop every received packet (on every rx queue), and veto
203 * reception by returning %EFX_VETO_PACKET.
205 * @request_mtu: Called to request MTU change.
206 * Called whenever the user requests the net_dev mtu to be changed.
207 * If the client returns an error, the mtu change is aborted. The sfc
208 * driver guarantees that no other callbacks are running.
209 * Context: process, rtnl_lock held.
210 * @mtu_changed: Called when MTU has been changed.
211 * Called after the mtu has been successfully changed, always after
212 * a previous call to request_mtu(). The sfc driver guarantees that no
213 * other callbacks are running.
214 * Context: process, rtnl_lock held.
215 * @event: Called when a hardware NIC event is not understood by the sfc driver.
218 struct efx_dl_callbacks {
219 enum efx_veto (*tx_packet) (struct efx_dl_device *efx_dev,
220 struct sk_buff *skb);
221 enum efx_veto (*rx_packet) (struct efx_dl_device *efx_dev,
222 const char *pkt_hdr, int pkt_len);
223 int (*request_mtu) (struct efx_dl_device *efx_dev, int new_mtu);
224 void (*mtu_changed) (struct efx_dl_device *efx_dev, int mtu);
225 void (*event) (struct efx_dl_device *efx_dev, void *p_event);
228 /* Include API version number in symbol used for efx_dl_register_driver */
229 #define efx_dl_stringify_1(x, y) x ## y
230 #define efx_dl_stringify_2(x, y) efx_dl_stringify_1(x, y)
231 #define efx_dl_register_driver \
232 efx_dl_stringify_2(efx_dl_register_driver_api_ver_, \
233 EFX_DRIVERLINK_API_VERSION)
235 /* Exported driverlink api used to register and unregister the client driver
236 * and any callbacks [only one per port allowed], and to allow a client driver
237 * to request reset to recover from an error condition.
239 * All of these functions acquire the driverlink semaphore, so must not be
240 * called from an efx_dl_driver or efx_dl_callbacks member, and must be called
241 * from process context.
243 extern int efx_dl_register_driver(struct efx_dl_driver *driver);
245 extern void efx_dl_unregister_driver(struct efx_dl_driver *driver);
247 extern int efx_dl_register_callbacks(struct efx_dl_device *efx_dev,
248 struct efx_dl_callbacks *callbacks);
250 extern void efx_dl_unregister_callbacks(struct efx_dl_device *efx_dev,
251 struct efx_dl_callbacks *callbacks);
253 /* Schedule a reset without grabbing any locks */
254 extern void efx_dl_schedule_reset(struct efx_dl_device *efx_dev);
257 * efx_dl_for_each_device_info_matching - iterate an efx_dl_device_info list
258 * @_dev_info: Pointer to first &struct efx_dl_device_info
259 * @_type: Type code to look for
260 * @_info_type: Structure type corresponding to type code
261 * @_field: Name of &struct efx_dl_device_info field in the type
262 * @_p: Iterator variable
265 * struct efx_dl_falcon_resources *res;
266 * efx_dl_for_each_device_info_matching(dev_info, EFX_DL_FALCON_RESOURCES,
267 * struct efx_dl_falcon_resources,
269 * if (res->flags & EFX_DL_FALCON_DUAL_FUNC)
273 #define efx_dl_for_each_device_info_matching(_dev_info, _type, \
274 _info_type, _field, _p) \
275 for ((_p) = container_of((_dev_info), _info_type, _field); \
277 (_p) = container_of((_p)->_field.next, _info_type, _field))\
278 if ((_p)->_field.type != _type) \
283 * efx_dl_search_device_info - search an efx_dl_device_info list
284 * @_dev_info: Pointer to first &struct efx_dl_device_info
285 * @_type: Type code to look for
286 * @_info_type: Structure type corresponding to type code
287 * @_field: Name of &struct efx_dl_device_info member in this type
288 * @_p: Result variable
291 * struct efx_dl_falcon_resources *res;
292 * efx_dl_search_device_info(dev_info, EFX_DL_FALCON_RESOURCES,
293 * struct efx_dl_falcon_resources, hdr, res);
297 #define efx_dl_search_device_info(_dev_info, _type, _info_type, \
299 efx_dl_for_each_device_info_matching((_dev_info), (_type), \
300 _info_type, _field, (_p)) \
303 #endif /* EFX_DRIVERLINK_API_H */