]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Kieran Mansley <kmansley@solarflare.com> |
2 | Subject: sync Solarflare accelerator headers | |
3 | References: bnc#489105 | |
4 | ||
5 | Sync the headers used by sfc_netback and sfc_netutil with those in the | |
6 | sfc_resource driver to give a consistent view of cross-module APIs. | |
7 | ||
8 | Update sfc_netback to use efx_vi_alloc() as defined by the version of | |
9 | sfc_resource module in SLES11. It now takes a net driver interface | |
10 | index rather than a NIC index. | |
11 | ||
12 | efx_vi_hw_resource_get_phys() no longer returns a version. | |
13 | ||
14 | Set efhw_arch field of device type. | |
15 | ||
16 | Acked-by: jbeulich@novell.com | |
17 | ||
18 | --- sle11-2009-03-24.orig/drivers/net/sfc/sfc_resource/ci/efhw/common.h 2009-03-30 16:16:28.000000000 +0200 | |
19 | +++ sle11-2009-03-24/drivers/net/sfc/sfc_resource/ci/efhw/common.h 2009-03-30 16:21:54.000000000 +0200 | |
20 | @@ -41,6 +41,10 @@ | |
21 | ||
22 | #include <ci/efhw/common_sysdep.h> | |
23 | ||
24 | +enum efhw_arch { | |
25 | + EFHW_ARCH_FALCON, | |
26 | +}; | |
27 | + | |
28 | typedef uint32_t efhw_buffer_addr_t; | |
29 | #define EFHW_BUFFER_ADDR_FMT "[ba:%"PRIx32"]" | |
30 | ||
31 | --- sle11-2009-03-24.orig/drivers/net/sfc/sfc_resource/nic.c 2009-03-30 16:16:28.000000000 +0200 | |
32 | +++ sle11-2009-03-24/drivers/net/sfc/sfc_resource/nic.c 2009-03-30 16:21:54.000000000 +0200 | |
33 | @@ -47,6 +47,7 @@ int efhw_device_type_init(struct efhw_de | |
34 | switch (device_id) { | |
35 | case 0x0703: | |
36 | case 0x6703: | |
37 | + dt->arch = EFHW_ARCH_FALCON; | |
38 | dt->variant = 'A'; | |
39 | switch (class_revision) { | |
40 | case 0: | |
41 | @@ -60,6 +61,7 @@ int efhw_device_type_init(struct efhw_de | |
42 | } | |
43 | break; | |
44 | case 0x0710: | |
45 | + dt->arch = EFHW_ARCH_FALCON; | |
46 | dt->variant = 'B'; | |
47 | switch (class_revision) { | |
48 | case 2: | |
49 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/accel.h 2009-03-30 16:16:28.000000000 +0200 | |
50 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/accel.h 2009-03-30 16:00:09.000000000 +0200 | |
51 | @@ -123,8 +123,6 @@ struct netback_accel { | |
52 | enum net_accel_hw_type hw_type; | |
53 | /*! State of allocation */ | |
54 | int hw_state; | |
55 | - /*! Index into ci_driver.nics[] for this interface */ | |
56 | - int nic_index; | |
57 | /*! How to set up the acceleration for this hardware */ | |
58 | int (*accel_setup)(struct netback_accel *); | |
59 | /*! And how to stop it. */ | |
60 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/accel_solarflare.c 2009-03-30 16:16:28.000000000 +0200 | |
61 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/accel_solarflare.c 2009-03-30 16:10:59.000000000 +0200 | |
62 | @@ -87,7 +87,6 @@ struct driverlink_port { | |
63 | enum net_accel_hw_type type; | |
64 | struct net_device *net_dev; | |
65 | struct efx_dl_device *efx_dl_dev; | |
66 | - int nic_index; | |
67 | void *fwd_priv; | |
68 | }; | |
69 | ||
70 | @@ -164,34 +163,6 @@ static struct netback_accel_hooks accel_ | |
71 | }; | |
72 | ||
73 | ||
74 | -/* | |
75 | - * Handy helper which given an efx_dl_device works out which | |
76 | - * efab_nic_t index into efrm_nic_table.nics[] it corresponds to | |
77 | - */ | |
78 | -static int efx_device_to_efab_nic_index(struct efx_dl_device *efx_dl_dev) | |
79 | -{ | |
80 | - int i; | |
81 | - | |
82 | - for (i = 0; i < EFHW_MAX_NR_DEVS; i++) { | |
83 | - struct efhw_nic *nic = efrm_nic_table.nic[i]; | |
84 | - | |
85 | - /* | |
86 | - * It's possible for the nic structure to have not | |
87 | - * been initialised if the resource driver failed its | |
88 | - * driverlink probe | |
89 | - */ | |
90 | - if (nic == NULL || nic->net_driver_dev == NULL) | |
91 | - continue; | |
92 | - | |
93 | - /* Work out if these are talking about the same NIC */ | |
94 | - if (nic->net_driver_dev->pci_dev == efx_dl_dev->pci_dev) | |
95 | - return i; | |
96 | - } | |
97 | - | |
98 | - return -1; | |
99 | -} | |
100 | - | |
101 | - | |
102 | /* Driver link probe - register our callbacks */ | |
103 | static int bend_dl_probe(struct efx_dl_device *efx_dl_dev, | |
104 | const struct net_device *net_dev, | |
105 | @@ -225,17 +196,6 @@ static int bend_dl_probe(struct efx_dl_d | |
106 | port->efx_dl_dev = efx_dl_dev; | |
107 | efx_dl_dev->priv = port; | |
108 | ||
109 | - port->nic_index = efx_device_to_efab_nic_index(efx_dl_dev); | |
110 | - if (port->nic_index < 0) { | |
111 | - /* | |
112 | - * This can happen in theory if the resource driver | |
113 | - * failed to initialise properly | |
114 | - */ | |
115 | - EPRINTK("%s: nic structure not found\n", __FUNCTION__); | |
116 | - rc = -EINVAL; | |
117 | - goto fail2; | |
118 | - } | |
119 | - | |
120 | port->fwd_priv = netback_accel_init_fwd_port(); | |
121 | if (port->fwd_priv == NULL) { | |
122 | EPRINTK("%s: failed to set up forwarding for port\n", | |
123 | @@ -377,8 +337,6 @@ int netback_accel_sf_hwtype(struct netba | |
124 | bend->accel_setup = netback_accel_setup_vnic_hw; | |
125 | bend->accel_shutdown = netback_accel_shutdown_vnic_hw; | |
126 | bend->fwd_priv = port->fwd_priv; | |
127 | - /* This is just needed to pass to efx_vi_alloc */ | |
128 | - bend->nic_index = port->nic_index; | |
129 | bend->net_dev = port->net_dev; | |
130 | mutex_unlock(&accel_mutex); | |
131 | return 0; | |
132 | @@ -505,7 +463,7 @@ static int ef_get_vnic(struct netback_ac | |
133 | ||
134 | accel_hw_priv = bend->accel_hw_priv; | |
135 | ||
136 | - rc = efx_vi_alloc(&accel_hw_priv->efx_vih, bend->nic_index); | |
137 | + rc = efx_vi_alloc(&accel_hw_priv->efx_vih, bend->net_dev->ifindex); | |
138 | if (rc != 0) { | |
139 | EPRINTK("%s: efx_vi_alloc failed %d\n", __FUNCTION__, rc); | |
140 | free_page_state(bend); | |
141 | @@ -600,9 +558,6 @@ static int ef_bend_hwinfo_falcon_common( | |
142 | return rc; | |
143 | } | |
144 | ||
145 | - if (res_mdata.version != 0) | |
146 | - return -EPROTO; | |
147 | - | |
148 | hwinfo->nic_arch = res_mdata.nic_arch; | |
149 | hwinfo->nic_variant = res_mdata.nic_variant; | |
150 | hwinfo->nic_revision = res_mdata.nic_revision; | |
151 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/ci/driver/resource/efx_vi.h 2009-03-30 16:16:28.000000000 +0200 | |
152 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/ci/driver/resource/efx_vi.h 2009-03-30 16:00:09.000000000 +0200 | |
153 | @@ -49,11 +49,11 @@ struct efx_vi_state; | |
154 | * Allocate an efx_vi, including event queue and pt_endpoint | |
155 | * | |
156 | * \param vih_out Pointer to a handle that is set on success | |
157 | - * \param nic_index Index of NIC to apply this resource to | |
158 | + * \param ifindex Index of the network interface desired | |
159 | * \return Zero on success (and vih_out set), non-zero on failure. | |
160 | */ | |
161 | extern int | |
162 | -efx_vi_alloc(struct efx_vi_state **vih_out, int nic_index); | |
163 | +efx_vi_alloc(struct efx_vi_state **vih_out, int ifindex); | |
164 | ||
165 | /*! | |
166 | * Free a previously allocated efx_vi | |
167 | @@ -190,8 +190,6 @@ efx_vi_filter_stop(struct efx_vi_state * | |
168 | /*! Constants for the type field in efx_vi_hw_resource */ | |
169 | #define EFX_VI_HW_RESOURCE_TXDMAQ 0x0 /* PFN of TX DMA Q */ | |
170 | #define EFX_VI_HW_RESOURCE_RXDMAQ 0x1 /* PFN of RX DMA Q */ | |
171 | -#define EFX_VI_HW_RESOURCE_TXBELL 0x2 /* PFN of TX Doorbell (EF1) */ | |
172 | -#define EFX_VI_HW_RESOURCE_RXBELL 0x3 /* PFN of RX Doorbell (EF1) */ | |
173 | #define EFX_VI_HW_RESOURCE_EVQTIMER 0x4 /* Address of event q timer */ | |
174 | ||
175 | /* Address of event q pointer (EF1) */ | |
176 | @@ -229,7 +227,6 @@ struct efx_vi_hw_resource { | |
177 | * Metadata concerning the list of hardware resource mappings | |
178 | */ | |
179 | struct efx_vi_hw_resource_metadata { | |
180 | - int version; | |
181 | int evq_order; | |
182 | int evq_offs; | |
183 | int evq_capacity; | |
184 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/ci/efhw/common.h 2009-03-30 16:16:28.000000000 +0200 | |
185 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/ci/efhw/common.h 2009-03-30 16:21:54.000000000 +0200 | |
186 | @@ -43,7 +43,6 @@ | |
187 | ||
188 | enum efhw_arch { | |
189 | EFHW_ARCH_FALCON, | |
190 | - EFHW_ARCH_SIENA, | |
191 | }; | |
192 | ||
193 | typedef uint32_t efhw_buffer_addr_t; | |
194 | @@ -56,25 +55,21 @@ typedef union { | |
195 | uint32_t a; | |
196 | uint32_t b; | |
197 | } opaque; | |
198 | - struct { | |
199 | - uint32_t code; | |
200 | - uint32_t status; | |
201 | - } ev1002; | |
202 | } efhw_event_t; | |
203 | ||
204 | /* Flags for TX/RX queues */ | |
205 | -#define EFHW_VI_JUMBO_EN 0x01 /*! scatter RX over multiple desc */ | |
206 | -#define EFHW_VI_ISCSI_RX_HDIG_EN 0x02 /*! iscsi rx header digest */ | |
207 | -#define EFHW_VI_ISCSI_TX_HDIG_EN 0x04 /*! iscsi tx header digest */ | |
208 | -#define EFHW_VI_ISCSI_RX_DDIG_EN 0x08 /*! iscsi rx data digest */ | |
209 | -#define EFHW_VI_ISCSI_TX_DDIG_EN 0x10 /*! iscsi tx data digest */ | |
210 | -#define EFHW_VI_TX_PHYS_ADDR_EN 0x20 /*! TX physical address mode */ | |
211 | -#define EFHW_VI_RX_PHYS_ADDR_EN 0x40 /*! RX physical address mode */ | |
212 | -#define EFHW_VI_RM_WITH_INTERRUPT 0x80 /*! VI with an interrupt */ | |
213 | -#define EFHW_VI_TX_IP_CSUM_DIS 0x100 /*! enable ip checksum generation */ | |
214 | -#define EFHW_VI_TX_TCPUDP_CSUM_DIS 0x200 /*! enable tcp/udp checksum | |
215 | - generation */ | |
216 | -#define EFHW_VI_TX_TCPUDP_ONLY 0x400 /*! drop non-tcp/udp packets */ | |
217 | +#define EFHW_VI_JUMBO_EN 0x01 /*! scatter RX over multiple desc */ | |
218 | +#define EFHW_VI_ISCSI_RX_HDIG_EN 0x02 /*! iscsi rx header digest */ | |
219 | +#define EFHW_VI_ISCSI_TX_HDIG_EN 0x04 /*! iscsi tx header digest */ | |
220 | +#define EFHW_VI_ISCSI_RX_DDIG_EN 0x08 /*! iscsi rx data digest */ | |
221 | +#define EFHW_VI_ISCSI_TX_DDIG_EN 0x10 /*! iscsi tx data digest */ | |
222 | +#define EFHW_VI_TX_PHYS_ADDR_EN 0x20 /*! TX physical address mode */ | |
223 | +#define EFHW_VI_RX_PHYS_ADDR_EN 0x40 /*! RX physical address mode */ | |
224 | +#define EFHW_VI_RM_WITH_INTERRUPT 0x80 /*! VI with an interrupt */ | |
225 | +#define EFHW_VI_TX_IP_CSUM_DIS 0x100 /*! enable ip checksum generation */ | |
226 | +#define EFHW_VI_TX_TCPUDP_CSUM_DIS 0x200 /*! enable tcp/udp checksum | |
227 | + generation */ | |
228 | +#define EFHW_VI_TX_TCPUDP_ONLY 0x400 /*! drop non-tcp/udp packets */ | |
229 | ||
230 | /* Types of hardware filter */ | |
231 | /* Each of these values implicitly selects scatter filters on B0 - or in | |
232 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/ci/efhw/common_sysdep.h 2009-03-30 16:16:28.000000000 +0200 | |
233 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/ci/efhw/common_sysdep.h 2009-03-30 16:00:09.000000000 +0200 | |
234 | @@ -41,7 +41,6 @@ | |
235 | #define __CI_EFHW_COMMON_LINUX_H__ | |
236 | ||
237 | #include <linux/types.h> | |
238 | -#include <linux/version.h> | |
239 | ||
240 | /* Dirty hack, but Linux kernel does not provide DMA_ADDR_T_FMT */ | |
241 | #if BITS_PER_LONG == 64 || defined(CONFIG_HIGHMEM64G) | |
242 | @@ -52,16 +51,11 @@ | |
243 | ||
244 | /* Linux kernel also does not provide PRIx32... Sigh. */ | |
245 | #define PRIx32 "x" | |
246 | -#define PRIx64 "llx" | |
247 | ||
248 | - | |
249 | -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) | |
250 | -enum { | |
251 | - false = 0, | |
252 | - true = 1 | |
253 | -}; | |
254 | - | |
255 | -typedef _Bool bool; | |
256 | -#endif /* LINUX_VERSION_CODE < 2.6.19 */ | |
257 | +#ifdef __ia64__ | |
258 | +# define PRIx64 "lx" | |
259 | +#else | |
260 | +# define PRIx64 "llx" | |
261 | +#endif | |
262 | ||
263 | #endif /* __CI_EFHW_COMMON_LINUX_H__ */ | |
264 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/ci/efhw/efhw_types.h 2009-03-30 16:16:28.000000000 +0200 | |
265 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/ci/efhw/efhw_types.h 2009-03-30 16:00:09.000000000 +0200 | |
266 | @@ -45,14 +45,6 @@ | |
267 | ||
268 | /*-------------------------------------------------------------------- | |
269 | * | |
270 | - * hardware limits used in the types | |
271 | - * | |
272 | - *--------------------------------------------------------------------*/ | |
273 | - | |
274 | -#define EFHW_KEVENTQ_MAX 8 | |
275 | - | |
276 | -/*-------------------------------------------------------------------- | |
277 | - * | |
278 | * forward type declarations | |
279 | * | |
280 | *--------------------------------------------------------------------*/ | |
281 | @@ -72,7 +64,7 @@ struct efhw_buffer_table_allocation{ | |
282 | ||
283 | struct eventq_resource_hardware { | |
284 | /*!iobuffer allocated for eventq - can be larger than eventq */ | |
285 | - efhw_iopages_t iobuff; | |
286 | + struct efhw_iopages iobuff; | |
287 | unsigned iobuff_off; | |
288 | struct efhw_buffer_table_allocation buf_tbl_alloc; | |
289 | int capacity; /*!< capacity of event queue */ | |
290 | @@ -85,7 +77,7 @@ struct eventq_resource_hardware { | |
291 | *--------------------------------------------------------------------*/ | |
292 | ||
293 | struct efhw_keventq { | |
294 | - volatile int lock; | |
295 | + int lock; | |
296 | caddr_t evq_base; | |
297 | int32_t evq_ptr; | |
298 | uint32_t evq_mask; | |
299 | @@ -94,6 +86,37 @@ struct efhw_keventq { | |
300 | struct efhw_ev_handler *ev_handlers; | |
301 | }; | |
302 | ||
303 | +/*-------------------------------------------------------------------- | |
304 | + * | |
305 | + * filters | |
306 | + * | |
307 | + *--------------------------------------------------------------------*/ | |
308 | + | |
309 | +struct efhw_filter_spec { | |
310 | + uint dmaq_id; | |
311 | + uint32_t saddr_le32; | |
312 | + uint32_t daddr_le32; | |
313 | + uint16_t sport_le16; | |
314 | + uint16_t dport_le16; | |
315 | + unsigned tcp : 1; | |
316 | + unsigned full : 1; | |
317 | + unsigned rss : 1; /* not supported on A1 */ | |
318 | + unsigned scatter : 1; /* not supported on A1 */ | |
319 | +}; | |
320 | + | |
321 | +struct efhw_filter_depth { | |
322 | + unsigned needed; | |
323 | + unsigned max; | |
324 | +}; | |
325 | + | |
326 | +struct efhw_filter_search_limits { | |
327 | + unsigned tcp_full; | |
328 | + unsigned tcp_wild; | |
329 | + unsigned udp_full; | |
330 | + unsigned udp_wild; | |
331 | +}; | |
332 | + | |
333 | + | |
334 | /********************************************************************** | |
335 | * Portable HW interface. *************************************** | |
336 | **********************************************************************/ | |
337 | @@ -115,7 +138,7 @@ struct efhw_func_ops { | |
338 | /*! initialise all hardware functional units */ | |
339 | int (*init_hardware) (struct efhw_nic *nic, | |
340 | struct efhw_ev_handler *, | |
341 | - const uint8_t *mac_addr); | |
342 | + const uint8_t *mac_addr, int non_irq_evq); | |
343 | ||
344 | /*-------------- Interrupt support ------------ */ | |
345 | ||
346 | @@ -130,17 +153,17 @@ struct efhw_func_ops { | |
347 | */ | |
348 | int (*interrupt) (struct efhw_nic *nic); | |
349 | ||
350 | - /*! Enable given interrupt mask for the given IRQ unit */ | |
351 | - void (*interrupt_enable) (struct efhw_nic *nic, uint idx); | |
352 | + /*! Enable the interrupt */ | |
353 | + void (*interrupt_enable) (struct efhw_nic *nic); | |
354 | ||
355 | - /*! Disable given interrupt mask for the given IRQ unit */ | |
356 | - void (*interrupt_disable) (struct efhw_nic *nic, uint idx); | |
357 | + /*! Disable the interrupt */ | |
358 | + void (*interrupt_disable) (struct efhw_nic *nic); | |
359 | ||
360 | /*! Set interrupt moderation strategy for the given IRQ unit | |
361 | ** val is in usec | |
362 | */ | |
363 | - void (*set_interrupt_moderation)(struct efhw_nic *nic, | |
364 | - uint idx, uint val); | |
365 | + void (*set_interrupt_moderation)(struct efhw_nic *nic, int evq, | |
366 | + uint val); | |
367 | ||
368 | /*-------------- Event support ------------ */ | |
369 | ||
370 | @@ -152,7 +175,8 @@ struct efhw_func_ops { | |
371 | void (*event_queue_enable) (struct efhw_nic *nic, | |
372 | uint evq, /* evnt queue index */ | |
373 | uint evq_size, /* units of #entries */ | |
374 | - dma_addr_t q_base_addr, uint buf_base_id); | |
375 | + dma_addr_t q_base_addr, uint buf_base_id, | |
376 | + int interrupting); | |
377 | ||
378 | /*! Disable the given event queue (and any associated timer) */ | |
379 | void (*event_queue_disable) (struct efhw_nic *nic, uint evq, | |
380 | @@ -165,7 +189,7 @@ struct efhw_func_ops { | |
381 | /*! Push a SW event on a given eventQ */ | |
382 | void (*sw_event) (struct efhw_nic *nic, int data, int evq); | |
383 | ||
384 | - /*-------------- Filter support ------------ */ | |
385 | + /*-------------- IP Filter API ------------ */ | |
386 | ||
387 | /*! Setup a given filter - The software can request a filter_i, | |
388 | * but some EtherFabric implementations will override with | |
389 | @@ -176,13 +200,6 @@ struct efhw_func_ops { | |
390 | unsigned saddr_be32, unsigned sport_be16, | |
391 | unsigned daddr_be32, unsigned dport_be16); | |
392 | ||
393 | - /*! Attach a given filter to a DMAQ */ | |
394 | - void (*ipfilter_attach) (struct efhw_nic *nic, int filter_idx, | |
395 | - int dmaq_idx); | |
396 | - | |
397 | - /*! Detach a filter from its DMAQ */ | |
398 | - void (*ipfilter_detach) (struct efhw_nic *nic, int filter_idx); | |
399 | - | |
400 | /*! Clear down a given filter */ | |
401 | void (*ipfilter_clear) (struct efhw_nic *nic, int filter_idx); | |
402 | ||
403 | @@ -231,6 +248,14 @@ struct efhw_func_ops { | |
404 | /*! Commit a buffer table update */ | |
405 | void (*buffer_table_commit) (struct efhw_nic *nic); | |
406 | ||
407 | + /*-------------- New filter API ------------ */ | |
408 | + | |
409 | + /*! Set a given filter */ | |
410 | + int (*filter_set) (struct efhw_nic *nic, struct efhw_filter_spec *spec, | |
411 | + int *filter_idx_out); | |
412 | + | |
413 | + /*! Clear a given filter */ | |
414 | + void (*filter_clear) (struct efhw_nic *nic, int filter_idx); | |
415 | }; | |
416 | ||
417 | ||
418 | @@ -255,12 +280,10 @@ struct efhw_device_type { | |
419 | ||
420 | /*! */ | |
421 | struct efhw_nic { | |
422 | - /*! zero base index in efrm_nic_table.nic array */ | |
423 | - volatile int index; | |
424 | + /*! zero base index in efrm_nic_tablep->nic array */ | |
425 | + int index; | |
426 | int ifindex; /*!< OS level nic index */ | |
427 | -#ifdef HAS_NET_NAMESPACE | |
428 | struct net *nd_net; | |
429 | -#endif | |
430 | ||
431 | struct efhw_device_type devtype; | |
432 | ||
433 | @@ -276,14 +299,13 @@ struct efhw_nic { | |
434 | # define NIC_FLAG_TRY_MSI 0x02 | |
435 | # define NIC_FLAG_MSI 0x04 | |
436 | # define NIC_FLAG_OS_IRQ_EN 0x08 | |
437 | -# define NIC_FLAG_10G 0x10 | |
438 | ||
439 | unsigned mtu; /*!< MAC MTU (includes MAC hdr) */ | |
440 | ||
441 | /* hardware resources */ | |
442 | ||
443 | /*! I/O address of the start of the bar */ | |
444 | - efhw_ioaddr_t bar_ioaddr; | |
445 | + volatile char __iomem *bar_ioaddr; | |
446 | ||
447 | /*! Bar number of control aperture. */ | |
448 | unsigned ctr_ap_bar; | |
449 | @@ -295,9 +317,6 @@ struct efhw_nic { | |
450 | /*! EtherFabric Functional Units -- functions */ | |
451 | const struct efhw_func_ops *efhw_func; | |
452 | ||
453 | - /* Value read from FPGA version register. Zero for asic. */ | |
454 | - unsigned fpga_version; | |
455 | - | |
456 | /*! This lock protects a number of misc NIC resources. It should | |
457 | * only be used for things that can be at the bottom of the lock | |
458 | * order. ie. You mustn't attempt to grab any other lock while | |
459 | @@ -312,14 +331,17 @@ struct efhw_nic { | |
460 | void (*irq_handler) (struct efhw_nic *, int unit); | |
461 | ||
462 | /*! event queues per driver */ | |
463 | - struct efhw_keventq evq[EFHW_KEVENTQ_MAX]; | |
464 | + struct efhw_keventq interrupting_evq; | |
465 | ||
466 | /* for marking when we are not using an IRQ unit | |
467 | - 0 is a valid offset to an IRQ unit on EF1! */ | |
468 | #define EFHW_IRQ_UNIT_UNUSED 0xffff | |
469 | - /*! interrupt unit in use */ | |
470 | - unsigned int irq_unit[EFHW_KEVENTQ_MAX]; | |
471 | - efhw_iopage_t irq_iobuff; /*!< Falcon SYSERR interrupt */ | |
472 | + /*! interrupt unit in use for the interrupting event queue */ | |
473 | + unsigned int irq_unit; | |
474 | + | |
475 | + struct efhw_keventq non_interrupting_evq; | |
476 | + | |
477 | + struct efhw_iopage irq_iobuff; /*!< Falcon SYSERR interrupt */ | |
478 | ||
479 | /* The new driverlink infrastructure. */ | |
480 | struct efx_dl_device *net_driver_dev; | |
481 | @@ -331,8 +353,26 @@ struct efhw_nic { | |
482 | unsigned rxq_sizes; | |
483 | unsigned txq_sizes; | |
484 | ||
485 | - /* Size of filter table (including odd and even banks). */ | |
486 | - unsigned filter_tbl_size; | |
487 | + /* Size of filter table. */ | |
488 | + unsigned ip_filter_tbl_size; | |
489 | + | |
490 | + /* Number of filters currently used */ | |
491 | + unsigned ip_filter_tbl_used; | |
492 | + | |
493 | + /* Dynamically allocated filter state. */ | |
494 | + uint8_t *filter_in_use; | |
495 | + struct efhw_filter_spec *filter_spec_cache; | |
496 | + | |
497 | + /* Currently required and maximum filter table search depths. */ | |
498 | + struct efhw_filter_depth tcp_full_srch; | |
499 | + struct efhw_filter_depth tcp_wild_srch; | |
500 | + struct efhw_filter_depth udp_full_srch; | |
501 | + struct efhw_filter_depth udp_wild_srch; | |
502 | + | |
503 | + /* Number of event queues, DMA queues and timers. */ | |
504 | + unsigned num_evqs; | |
505 | + unsigned num_dmaqs; | |
506 | + unsigned num_timers; | |
507 | }; | |
508 | ||
509 | ||
510 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/ci/efhw/hardware_sysdep.h 2009-03-30 16:16:28.000000000 +0200 | |
511 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/ci/efhw/hardware_sysdep.h 2009-03-30 16:00:09.000000000 +0200 | |
512 | @@ -40,7 +40,7 @@ | |
513 | #ifndef __CI_EFHW_HARDWARE_LINUX_H__ | |
514 | #define __CI_EFHW_HARDWARE_LINUX_H__ | |
515 | ||
516 | -#include <asm/io.h> | |
517 | +#include <linux/io.h> | |
518 | ||
519 | #ifdef __LITTLE_ENDIAN | |
520 | #define EFHW_IS_LITTLE_ENDIAN | |
521 | @@ -50,23 +50,8 @@ | |
522 | #error Unknown endianness | |
523 | #endif | |
524 | ||
525 | -#ifndef mmiowb | |
526 | - #if defined(__i386__) || defined(__x86_64__) | |
527 | - #define mmiowb() | |
528 | - #elif defined(__ia64__) | |
529 | - #ifndef ia64_mfa | |
530 | - #define ia64_mfa() asm volatile ("mf.a" ::: "memory") | |
531 | - #endif | |
532 | - #define mmiowb ia64_mfa | |
533 | - #else | |
534 | - #error "Need definition for mmiowb()" | |
535 | - #endif | |
536 | -#endif | |
537 | - | |
538 | -typedef char *efhw_ioaddr_t; | |
539 | - | |
540 | #ifndef readq | |
541 | -static inline uint64_t __readq(void __iomem *addr) | |
542 | +static inline uint64_t __readq(volatile void __iomem *addr) | |
543 | { | |
544 | return *(volatile uint64_t *)addr; | |
545 | } | |
546 | @@ -74,7 +59,7 @@ static inline uint64_t __readq(void __io | |
547 | #endif | |
548 | ||
549 | #ifndef writeq | |
550 | -static inline void __writeq(uint64_t v, void __iomem *addr) | |
551 | +static inline void __writeq(uint64_t v, volatile void __iomem *addr) | |
552 | { | |
553 | *(volatile uint64_t *)addr = v; | |
554 | } | |
555 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/ci/efhw/iopage_types.h 2009-03-30 16:16:28.000000000 +0200 | |
556 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/ci/efhw/iopage_types.h 2009-03-30 16:00:09.000000000 +0200 | |
557 | @@ -3,7 +3,8 @@ | |
558 | * resource management for Xen backend, OpenOnload, etc | |
559 | * (including support for SFE4001 10GBT NIC) | |
560 | * | |
561 | - * This file provides efhw_page_t and efhw_iopage_t for Linux kernel. | |
562 | + * This file provides struct efhw_page and struct efhw_iopage for Linux | |
563 | + * kernel. | |
564 | * | |
565 | * Copyright 2005-2007: Solarflare Communications Inc, | |
566 | * 9501 Jeronimo Road, Suite 250, | |
567 | @@ -40,75 +41,76 @@ | |
568 | ||
569 | #include <linux/gfp.h> | |
570 | #include <linux/hardirq.h> | |
571 | +#include <linux/errno.h> | |
572 | #include <ci/efhw/debug.h> | |
573 | ||
574 | /*-------------------------------------------------------------------- | |
575 | * | |
576 | - * efhw_page_t: A single page of memory. Directly mapped in the driver, | |
577 | - * and can be mapped to userlevel. | |
578 | + * struct efhw_page: A single page of memory. Directly mapped in the | |
579 | + * driver, and can be mapped to userlevel. | |
580 | * | |
581 | *--------------------------------------------------------------------*/ | |
582 | ||
583 | -typedef struct { | |
584 | +struct efhw_page { | |
585 | unsigned long kva; | |
586 | -} efhw_page_t; | |
587 | +}; | |
588 | ||
589 | -static inline int efhw_page_alloc(efhw_page_t *p) | |
590 | +static inline int efhw_page_alloc(struct efhw_page *p) | |
591 | { | |
592 | p->kva = __get_free_page(in_interrupt()? GFP_ATOMIC : GFP_KERNEL); | |
593 | return p->kva ? 0 : -ENOMEM; | |
594 | } | |
595 | ||
596 | -static inline int efhw_page_alloc_zeroed(efhw_page_t *p) | |
597 | +static inline int efhw_page_alloc_zeroed(struct efhw_page *p) | |
598 | { | |
599 | p->kva = get_zeroed_page(in_interrupt()? GFP_ATOMIC : GFP_KERNEL); | |
600 | return p->kva ? 0 : -ENOMEM; | |
601 | } | |
602 | ||
603 | -static inline void efhw_page_free(efhw_page_t *p) | |
604 | +static inline void efhw_page_free(struct efhw_page *p) | |
605 | { | |
606 | free_page(p->kva); | |
607 | EFHW_DO_DEBUG(memset(p, 0, sizeof(*p))); | |
608 | } | |
609 | ||
610 | -static inline char *efhw_page_ptr(efhw_page_t *p) | |
611 | +static inline char *efhw_page_ptr(struct efhw_page *p) | |
612 | { | |
613 | return (char *)p->kva; | |
614 | } | |
615 | ||
616 | -static inline unsigned efhw_page_pfn(efhw_page_t *p) | |
617 | +static inline unsigned efhw_page_pfn(struct efhw_page *p) | |
618 | { | |
619 | return (unsigned)(__pa(p->kva) >> PAGE_SHIFT); | |
620 | } | |
621 | ||
622 | -static inline void efhw_page_mark_invalid(efhw_page_t *p) | |
623 | +static inline void efhw_page_mark_invalid(struct efhw_page *p) | |
624 | { | |
625 | p->kva = 0; | |
626 | } | |
627 | ||
628 | -static inline int efhw_page_is_valid(efhw_page_t *p) | |
629 | +static inline int efhw_page_is_valid(struct efhw_page *p) | |
630 | { | |
631 | return p->kva != 0; | |
632 | } | |
633 | ||
634 | -static inline void efhw_page_init_from_va(efhw_page_t *p, void *va) | |
635 | +static inline void efhw_page_init_from_va(struct efhw_page *p, void *va) | |
636 | { | |
637 | p->kva = (unsigned long)va; | |
638 | } | |
639 | ||
640 | /*-------------------------------------------------------------------- | |
641 | * | |
642 | - * efhw_iopage_t: A single page of memory. Directly mapped in the driver, | |
643 | + * struct efhw_iopage: A single page of memory. Directly mapped in the driver, | |
644 | * and can be mapped to userlevel. Can also be accessed by the NIC. | |
645 | * | |
646 | *--------------------------------------------------------------------*/ | |
647 | ||
648 | -typedef struct { | |
649 | - efhw_page_t p; | |
650 | +struct efhw_iopage { | |
651 | + struct efhw_page p; | |
652 | dma_addr_t dma_addr; | |
653 | -} efhw_iopage_t; | |
654 | +}; | |
655 | ||
656 | -static inline dma_addr_t efhw_iopage_dma_addr(efhw_iopage_t *p) | |
657 | +static inline dma_addr_t efhw_iopage_dma_addr(struct efhw_iopage *p) | |
658 | { | |
659 | return p->dma_addr; | |
660 | } | |
661 | @@ -120,9 +122,9 @@ static inline dma_addr_t efhw_iopage_dma | |
662 | ||
663 | /*-------------------------------------------------------------------- | |
664 | * | |
665 | - * efhw_iopages_t: A set of pages that are contiguous in physical memory. | |
666 | - * Directly mapped in the driver, and can be mapped to userlevel. Can also | |
667 | - * be accessed by the NIC. | |
668 | + * struct efhw_iopages: A set of pages that are contiguous in physical | |
669 | + * memory. Directly mapped in the driver, and can be mapped to userlevel. | |
670 | + * Can also be accessed by the NIC. | |
671 | * | |
672 | * NB. The O/S may be unwilling to allocate many, or even any of these. So | |
673 | * only use this type where the NIC really needs a physically contiguous | |
674 | @@ -130,44 +132,44 @@ static inline dma_addr_t efhw_iopage_dma | |
675 | * | |
676 | *--------------------------------------------------------------------*/ | |
677 | ||
678 | -typedef struct { | |
679 | +struct efhw_iopages { | |
680 | caddr_t kva; | |
681 | unsigned order; | |
682 | dma_addr_t dma_addr; | |
683 | -} efhw_iopages_t; | |
684 | +}; | |
685 | ||
686 | -static inline caddr_t efhw_iopages_ptr(efhw_iopages_t *p) | |
687 | +static inline caddr_t efhw_iopages_ptr(struct efhw_iopages *p) | |
688 | { | |
689 | return p->kva; | |
690 | } | |
691 | ||
692 | -static inline unsigned efhw_iopages_pfn(efhw_iopages_t *p) | |
693 | +static inline unsigned efhw_iopages_pfn(struct efhw_iopages *p) | |
694 | { | |
695 | return (unsigned)(__pa(p->kva) >> PAGE_SHIFT); | |
696 | } | |
697 | ||
698 | -static inline dma_addr_t efhw_iopages_dma_addr(efhw_iopages_t *p) | |
699 | +static inline dma_addr_t efhw_iopages_dma_addr(struct efhw_iopages *p) | |
700 | { | |
701 | return p->dma_addr; | |
702 | } | |
703 | ||
704 | -static inline unsigned efhw_iopages_size(efhw_iopages_t *p) | |
705 | +static inline unsigned efhw_iopages_size(struct efhw_iopages *p) | |
706 | { | |
707 | return 1u << (p->order + PAGE_SHIFT); | |
708 | } | |
709 | ||
710 | -/* efhw_iopage_t <-> efhw_iopages_t conversions for handling physically | |
711 | - * contiguous allocations in iobufsets for iSCSI. This allows the | |
712 | - * essential information about contiguous allocations from | |
713 | - * efhw_iopages_alloc() to be saved away in the efhw_iopage_t array in an | |
714 | - * iobufset. (Changing the iobufset resource to use a union type would | |
715 | +/* struct efhw_iopage <-> struct efhw_iopages conversions for handling | |
716 | + * physically contiguous allocations in iobufsets for iSCSI. This allows | |
717 | + * the essential information about contiguous allocations from | |
718 | + * efhw_iopages_alloc() to be saved away in the struct efhw_iopage array in | |
719 | + * an iobufset. (Changing the iobufset resource to use a union type would | |
720 | * involve a lot of code changes, and make the iobufset's metadata larger | |
721 | * which could be bad as it's supposed to fit into a single page on some | |
722 | * platforms.) | |
723 | */ | |
724 | static inline void | |
725 | -efhw_iopage_init_from_iopages(efhw_iopage_t *iopage, | |
726 | - efhw_iopages_t *iopages, unsigned pageno) | |
727 | +efhw_iopage_init_from_iopages(struct efhw_iopage *iopage, | |
728 | + struct efhw_iopages *iopages, unsigned pageno) | |
729 | { | |
730 | iopage->p.kva = ((unsigned long)efhw_iopages_ptr(iopages)) | |
731 | + (pageno * PAGE_SIZE); | |
732 | @@ -176,8 +178,8 @@ efhw_iopage_init_from_iopages(efhw_iopag | |
733 | } | |
734 | ||
735 | static inline void | |
736 | -efhw_iopages_init_from_iopage(efhw_iopages_t *iopages, | |
737 | - efhw_iopage_t *iopage, unsigned order) | |
738 | +efhw_iopages_init_from_iopage(struct efhw_iopages *iopages, | |
739 | + struct efhw_iopage *iopage, unsigned order) | |
740 | { | |
741 | iopages->kva = (caddr_t) efhw_iopage_ptr(iopage); | |
742 | EFHW_ASSERT(iopages->kva); | |
743 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/ci/efhw/public.h 2009-03-30 16:16:28.000000000 +0200 | |
744 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/ci/efhw/public.h 2009-03-30 16:00:09.000000000 +0200 | |
745 | @@ -70,11 +70,32 @@ int efhw_nic_event_queue_alloc_iobuffer( | |
746 | extern void falcon_nic_set_rx_usr_buf_size(struct efhw_nic *, | |
747 | int rx_usr_buf_size); | |
748 | ||
749 | +/*! Get RX filter search limits from RX_FILTER_CTL_REG. | |
750 | + * use_raw_values = 0 to get actual depth of search, or 1 to get raw values | |
751 | + * from register. | |
752 | + */ | |
753 | +extern void | |
754 | +falcon_nic_get_rx_filter_search_limits(struct efhw_nic *nic, | |
755 | + struct efhw_filter_search_limits *lim, | |
756 | + int use_raw_values); | |
757 | + | |
758 | +/*! Set RX filter search limits in RX_FILTER_CTL_REG. | |
759 | + * use_raw_values = 0 if specifying actual depth of search, or 1 if specifying | |
760 | + * raw values to write to the register. | |
761 | + */ | |
762 | +extern void | |
763 | +falcon_nic_set_rx_filter_search_limits(struct efhw_nic *nic, | |
764 | + struct efhw_filter_search_limits *lim, | |
765 | + int use_raw_values); | |
766 | + | |
767 | + | |
768 | +/*! Legacy RX IP filter search depth control interface */ | |
769 | extern void | |
770 | falcon_nic_rx_filter_ctl_set(struct efhw_nic *nic, uint32_t tcp_full, | |
771 | uint32_t tcp_wild, | |
772 | uint32_t udp_full, uint32_t udp_wild); | |
773 | ||
774 | +/*! Legacy RX IP filter search depth control interface */ | |
775 | extern void | |
776 | falcon_nic_rx_filter_ctl_get(struct efhw_nic *nic, uint32_t *tcp_full, | |
777 | uint32_t *tcp_wild, | |
778 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/ci/efhw/sysdep.h 2009-03-30 16:16:28.000000000 +0200 | |
779 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/ci/efhw/sysdep.h 2009-03-30 16:00:09.000000000 +0200 | |
780 | @@ -39,34 +39,17 @@ | |
781 | #ifndef __CI_EFHW_SYSDEP_LINUX_H__ | |
782 | #define __CI_EFHW_SYSDEP_LINUX_H__ | |
783 | ||
784 | -#include <linux/version.h> | |
785 | #include <linux/module.h> | |
786 | #include <linux/spinlock.h> | |
787 | #include <linux/delay.h> | |
788 | +#include <linux/vmalloc.h> | |
789 | #include <linux/if_ether.h> | |
790 | ||
791 | #include <linux/netdevice.h> /* necessary for etherdevice.h on some kernels */ | |
792 | #include <linux/etherdevice.h> | |
793 | ||
794 | -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,21) | |
795 | -static inline int is_local_ether_addr(const u8 *addr) | |
796 | -{ | |
797 | - return (0x02 & addr[0]); | |
798 | -} | |
799 | -#endif | |
800 | - | |
801 | typedef unsigned long irq_flags_t; | |
802 | ||
803 | #define spin_lock_destroy(l_) do {} while (0) | |
804 | ||
805 | -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) | |
806 | -#define HAS_NET_NAMESPACE | |
807 | -#endif | |
808 | - | |
809 | -/* Funny, but linux has round_up for x86 only, defined in | |
810 | - * x86-specific header */ | |
811 | -#ifndef round_up | |
812 | -#define round_up(x, y) (((x) + (y) - 1) & ~((y)-1)) | |
813 | -#endif | |
814 | - | |
815 | #endif /* __CI_EFHW_SYSDEP_LINUX_H__ */ | |
816 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/ci/efrm/nic_table.h 2009-03-30 16:16:28.000000000 +0200 | |
817 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/ci/efrm/nic_table.h 2009-03-30 16:09:06.000000000 +0200 | |
818 | @@ -62,21 +62,21 @@ struct efrm_nic_table { | |
819 | }; | |
820 | ||
821 | /* Resource driver structures used by other drivers as well */ | |
822 | -extern struct efrm_nic_table efrm_nic_table; | |
823 | +extern struct efrm_nic_table *efrm_nic_tablep; | |
824 | ||
825 | static inline void efrm_nic_table_hold(void) | |
826 | { | |
827 | - atomic_inc(&efrm_nic_table.ref_count); | |
828 | + atomic_inc(&efrm_nic_tablep->ref_count); | |
829 | } | |
830 | ||
831 | static inline void efrm_nic_table_rele(void) | |
832 | { | |
833 | - atomic_dec(&efrm_nic_table.ref_count); | |
834 | + atomic_dec(&efrm_nic_tablep->ref_count); | |
835 | } | |
836 | ||
837 | static inline int efrm_nic_table_held(void) | |
838 | { | |
839 | - return (atomic_read(&efrm_nic_table.ref_count) != 0); | |
840 | + return atomic_read(&efrm_nic_tablep->ref_count) != 0; | |
841 | } | |
842 | ||
843 | /* Run code block _x multiple times with variable nic set to each | |
844 | @@ -86,13 +86,13 @@ static inline int efrm_nic_table_held(vo | |
845 | for ((_nic_i) = (efrm_nic_table_hold(), 0); \ | |
846 | (_nic_i) < EFHW_MAX_NR_DEVS || (efrm_nic_table_rele(), 0); \ | |
847 | (_nic_i)++) \ | |
848 | - if (((_nic) = efrm_nic_table.nic[_nic_i])) | |
849 | + if (((_nic) = efrm_nic_tablep->nic[_nic_i])) | |
850 | ||
851 | #define EFRM_FOR_EACH_NIC_IN_SET(_set, _i, _nic) \ | |
852 | for ((_i) = (efrm_nic_table_hold(), 0); \ | |
853 | (_i) < EFHW_MAX_NR_DEVS || (efrm_nic_table_rele(), 0); \ | |
854 | ++(_i)) \ | |
855 | - if (((_nic) = efrm_nic_table.nic[_i]) && \ | |
856 | + if (((_nic) = efrm_nic_tablep->nic[_i]) && \ | |
857 | efrm_nic_set_read((_set), (_i))) | |
858 | ||
859 | #endif /* __CI_EFRM_NIC_TABLE_H__ */ | |
860 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/ci/efrm/sysdep.h 2009-03-30 16:16:28.000000000 +0200 | |
861 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/ci/efrm/sysdep.h 2009-03-30 16:00:09.000000000 +0200 | |
862 | @@ -41,14 +41,6 @@ | |
863 | /* Spinlocks are defined in efhw/sysdep.h */ | |
864 | #include <ci/efhw/sysdep.h> | |
865 | ||
866 | -#if defined(__linux__) && defined(__KERNEL__) | |
867 | - | |
868 | -# include <ci/efrm/sysdep_linux.h> | |
869 | - | |
870 | -#else | |
871 | - | |
872 | -# include <ci/efrm/sysdep_ci2linux.h> | |
873 | - | |
874 | -#endif | |
875 | +#include <ci/efrm/sysdep_linux.h> | |
876 | ||
877 | #endif /* __CI_EFRM_SYSDEP_H__ */ | |
878 | --- sle11-2009-03-24.orig/drivers/xen/sfc_netback/ci/efrm/sysdep_linux.h 2009-03-30 16:16:28.000000000 +0200 | |
879 | +++ sle11-2009-03-24/drivers/xen/sfc_netback/ci/efrm/sysdep_linux.h 2009-03-30 16:00:09.000000000 +0200 | |
880 | @@ -42,7 +42,6 @@ | |
881 | #ifndef __CI_EFRM_SYSDEP_LINUX_H__ | |
882 | #define __CI_EFRM_SYSDEP_LINUX_H__ | |
883 | ||
884 | -#include <linux/version.h> | |
885 | #include <linux/list.h> | |
886 | #include <linux/vmalloc.h> | |
887 | #include <linux/errno.h> | |
888 | @@ -55,28 +54,15 @@ | |
889 | #include <linux/if_ether.h> | |
890 | #include <linux/completion.h> | |
891 | #include <linux/in.h> | |
892 | - | |
893 | -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) | |
894 | -/* get roundup_pow_of_two(), which was in kernel.h in early kernel versions */ | |
895 | #include <linux/log2.h> | |
896 | -#endif | |
897 | +#include <linux/kfifo.h> | |
898 | + | |
899 | ||
900 | /******************************************************************** | |
901 | * | |
902 | * List API | |
903 | * | |
904 | ********************************************************************/ | |
905 | -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) | |
906 | -static inline void | |
907 | -list_replace_init(struct list_head *old, struct list_head *new) | |
908 | -{ | |
909 | - new->next = old->next; | |
910 | - new->next->prev = new; | |
911 | - new->prev = old->prev; | |
912 | - new->prev->next = new; | |
913 | - INIT_LIST_HEAD(old); | |
914 | -} | |
915 | -#endif | |
916 | ||
917 | static inline struct list_head *list_pop(struct list_head *list) | |
918 | { | |
919 | @@ -94,151 +80,10 @@ static inline struct list_head *list_pop | |
920 | ||
921 | /******************************************************************** | |
922 | * | |
923 | - * Workqueue API | |
924 | - * | |
925 | - ********************************************************************/ | |
926 | - | |
927 | -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) | |
928 | -#define NEED_OLD_WORK_API | |
929 | - | |
930 | -/** | |
931 | - * The old and new work function prototypes just change | |
932 | - * the type of the pointer in the only argument, so it's | |
933 | - * safe to cast one function type to the other | |
934 | - */ | |
935 | -typedef void (*efrm_old_work_func_t) (void *p); | |
936 | - | |
937 | -#undef INIT_WORK | |
938 | -#define INIT_WORK(_work, _func) \ | |
939 | - do { \ | |
940 | - INIT_LIST_HEAD(&(_work)->entry); \ | |
941 | - (_work)->pending = 0; \ | |
942 | - PREPARE_WORK((_work), \ | |
943 | - (efrm_old_work_func_t) (_func), \ | |
944 | - (_work)); \ | |
945 | - } while (0) | |
946 | - | |
947 | -#endif | |
948 | - | |
949 | -/******************************************************************** | |
950 | - * | |
951 | * Kfifo API | |
952 | * | |
953 | ********************************************************************/ | |
954 | ||
955 | -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) | |
956 | - | |
957 | -#if !defined(RHEL_RELEASE_CODE) || (RHEL_RELEASE_CODE < 1029) | |
958 | -typedef unsigned gfp_t; | |
959 | -#endif | |
960 | - | |
961 | -#define HAS_NO_KFIFO | |
962 | - | |
963 | -struct kfifo { | |
964 | - unsigned char *buffer; /* the buffer holding the data */ | |
965 | - unsigned int size; /* the size of the allocated buffer */ | |
966 | - unsigned int in; /* data is added at offset (in % size) */ | |
967 | - unsigned int out; /* data is extracted from off. (out % size) */ | |
968 | - spinlock_t *lock; /* protects concurrent modifications */ | |
969 | -}; | |
970 | - | |
971 | -extern struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size, | |
972 | - gfp_t gfp_mask, spinlock_t *lock); | |
973 | -extern struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, | |
974 | - spinlock_t *lock); | |
975 | -extern void kfifo_free(struct kfifo *fifo); | |
976 | -extern unsigned int __kfifo_put(struct kfifo *fifo, | |
977 | - unsigned char *buffer, unsigned int len); | |
978 | -extern unsigned int __kfifo_get(struct kfifo *fifo, | |
979 | - unsigned char *buffer, unsigned int len); | |
980 | - | |
981 | -/** | |
982 | - * kfifo_put - puts some data into the FIFO | |
983 | - * @fifo: the fifo to be used. | |
984 | - * @buffer: the data to be added. | |
985 | - * @len: the length of the data to be added. | |
986 | - * | |
987 | - * This function copies at most @len bytes from the @buffer into | |
988 | - * the FIFO depending on the free space, and returns the number of | |
989 | - * bytes copied. | |
990 | - */ | |
991 | -static inline unsigned int | |
992 | -kfifo_put(struct kfifo *fifo, unsigned char *buffer, unsigned int len) | |
993 | -{ | |
994 | - unsigned long flags; | |
995 | - unsigned int ret; | |
996 | - | |
997 | - spin_lock_irqsave(fifo->lock, flags); | |
998 | - | |
999 | - ret = __kfifo_put(fifo, buffer, len); | |
1000 | - | |
1001 | - spin_unlock_irqrestore(fifo->lock, flags); | |
1002 | - | |
1003 | - return ret; | |
1004 | -} | |
1005 | - | |
1006 | -/** | |
1007 | - * kfifo_get - gets some data from the FIFO | |
1008 | - * @fifo: the fifo to be used. | |
1009 | - * @buffer: where the data must be copied. | |
1010 | - * @len: the size of the destination buffer. | |
1011 | - * | |
1012 | - * This function copies at most @len bytes from the FIFO into the | |
1013 | - * @buffer and returns the number of copied bytes. | |
1014 | - */ | |
1015 | -static inline unsigned int | |
1016 | -kfifo_get(struct kfifo *fifo, unsigned char *buffer, unsigned int len) | |
1017 | -{ | |
1018 | - unsigned long flags; | |
1019 | - unsigned int ret; | |
1020 | - | |
1021 | - spin_lock_irqsave(fifo->lock, flags); | |
1022 | - | |
1023 | - ret = __kfifo_get(fifo, buffer, len); | |
1024 | - | |
1025 | - /* | |
1026 | - * optimization: if the FIFO is empty, set the indices to 0 | |
1027 | - * so we don't wrap the next time | |
1028 | - */ | |
1029 | - if (fifo->in == fifo->out) | |
1030 | - fifo->in = fifo->out = 0; | |
1031 | - | |
1032 | - spin_unlock_irqrestore(fifo->lock, flags); | |
1033 | - | |
1034 | - return ret; | |
1035 | -} | |
1036 | - | |
1037 | -/** | |
1038 | - * __kfifo_len - returns the number of bytes available in the FIFO, no locking version | |
1039 | - * @fifo: the fifo to be used. | |
1040 | - */ | |
1041 | -static inline unsigned int __kfifo_len(struct kfifo *fifo) | |
1042 | -{ | |
1043 | - return fifo->in - fifo->out; | |
1044 | -} | |
1045 | - | |
1046 | -/** | |
1047 | - * kfifo_len - returns the number of bytes available in the FIFO | |
1048 | - * @fifo: the fifo to be used. | |
1049 | - */ | |
1050 | -static inline unsigned int kfifo_len(struct kfifo *fifo) | |
1051 | -{ | |
1052 | - unsigned long flags; | |
1053 | - unsigned int ret; | |
1054 | - | |
1055 | - spin_lock_irqsave(fifo->lock, flags); | |
1056 | - | |
1057 | - ret = __kfifo_len(fifo); | |
1058 | - | |
1059 | - spin_unlock_irqrestore(fifo->lock, flags); | |
1060 | - | |
1061 | - return ret; | |
1062 | -} | |
1063 | - | |
1064 | -#else | |
1065 | -#include <linux/kfifo.h> | |
1066 | -#endif | |
1067 | - | |
1068 | static inline void kfifo_vfree(struct kfifo *fifo) | |
1069 | { | |
1070 | vfree(fifo->buffer); |