Added patch headers.
[linux-flexiantxendom0-3.2.10.git] / drivers / xen / sfc_netfront / etherfabric / ef_vi.h
1 /****************************************************************************
2  * Copyright 2002-2005: Level 5 Networks Inc.
3  * Copyright 2005-2008: Solarflare Communications Inc,
4  *                      9501 Jeronimo Road, Suite 250,
5  *                      Irvine, CA 92618, USA
6  *
7  * Maintained by Solarflare Communications
8  *  <linux-xen-drivers@solarflare.com>
9  *  <onload-dev@solarflare.com>
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License version 2 as published
13  * by the Free Software Foundation, incorporated herein by reference.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23  ****************************************************************************
24  */
25
26 /*
27  *  \brief  Virtual Interface
28  *   \date  2007/05/16
29  */
30
31 #ifndef __EFAB_EF_VI_H__
32 #define __EFAB_EF_VI_H__
33
34
35 /**********************************************************************
36  * Primitive types ****************************************************
37  **********************************************************************/
38
39 /* We standardise on the types from stdint.h and synthesise these types
40  * for compilers/platforms that don't provide them */
41
42 #  include <linux/types.h>
43 # define EF_VI_ALIGN(x) __attribute__ ((aligned (x)))
44 # define ef_vi_inline static inline
45
46
47
48 /**********************************************************************
49  * Types **************************************************************
50  **********************************************************************/
51
52 typedef uint32_t                ef_eventq_ptr;
53
54 typedef uint64_t                ef_addr;
55 typedef char*                   ef_vi_ioaddr_t;
56
57 /**********************************************************************
58  * ef_event ***********************************************************
59  **********************************************************************/
60
61 /*! \i_ef_vi A DMA request identifier.
62 **
63 ** This is an integer token specified by the transport and associated
64 ** with a DMA request.  It is returned to the VI user with DMA completion
65 ** events.  It is typically used to identify the buffer associated with
66 ** the transfer.
67 */
68 typedef int                     ef_request_id;
69
70 typedef union {
71         uint64_t  u64[1];
72         uint32_t  u32[2];
73 } ef_vi_qword;
74
75 typedef ef_vi_qword             ef_hw_event;
76
77 #define EF_REQUEST_ID_BITS      16u
78 #define EF_REQUEST_ID_MASK      ((1u << EF_REQUEST_ID_BITS) - 1u)
79
80 /*! \i_ef_event An [ef_event] is a token that identifies something that
81 ** has happened.  Examples include packets received, packets transmitted
82 ** and errors.
83 */
84 typedef union {
85         struct {
86                 ef_hw_event    ev;
87                 unsigned       type       :16;
88         } generic;
89         struct {
90                 ef_hw_event    ev;
91                 unsigned       type       :16;
92                 /*ef_request_id  request_id :EF_REQUEST_ID_BITS;*/
93                 unsigned       q_id       :16;
94                 unsigned       len        :16;
95                 unsigned       flags      :16;
96         } rx;
97         struct {  /* This *must* have same layout as [rx]. */
98                 ef_hw_event    ev;
99                 unsigned       type       :16;
100                 /*ef_request_id  request_id :EF_REQUEST_ID_BITS;*/
101                 unsigned       q_id       :16;
102                 unsigned       len        :16;
103                 unsigned       flags      :16;
104                 unsigned       subtype    :16;
105         } rx_discard;
106         struct {
107                 ef_hw_event    ev;
108                 unsigned       type       :16;
109                 /*ef_request_id  request_id :EF_REQUEST_ID_BITS;*/
110                 unsigned       q_id       :16;
111         } tx;
112         struct {
113                 ef_hw_event    ev;
114                 unsigned       type       :16;
115                 /*ef_request_id  request_id :EF_REQUEST_ID_BITS;*/
116                 unsigned       q_id       :16;
117                 unsigned       subtype    :16;
118         } tx_error;
119         struct {
120                 ef_hw_event    ev;
121                 unsigned       type       :16;
122                 unsigned       q_id       :16;
123         } rx_no_desc_trunc;
124         struct {
125                 ef_hw_event    ev;
126                 unsigned       type       :16;
127                 unsigned       data;
128         } sw;
129 } ef_event;
130
131
132 #define EF_EVENT_TYPE(e)        ((e).generic.type)
133 enum {
134         /** Good data was received. */
135         EF_EVENT_TYPE_RX,
136         /** Packets have been sent. */
137         EF_EVENT_TYPE_TX,
138         /** Data received and buffer consumed, but something is wrong. */
139         EF_EVENT_TYPE_RX_DISCARD,
140         /** Transmit of packet failed. */
141         EF_EVENT_TYPE_TX_ERROR,
142         /** Received packet was truncated due to lack of descriptors. */
143         EF_EVENT_TYPE_RX_NO_DESC_TRUNC,
144         /** Software generated event. */
145         EF_EVENT_TYPE_SW,
146         /** Event queue overflow. */
147         EF_EVENT_TYPE_OFLOW,
148 };
149
150 #define EF_EVENT_RX_BYTES(e)    ((e).rx.len)
151 #define EF_EVENT_RX_Q_ID(e)     ((e).rx.q_id)
152 #define EF_EVENT_RX_CONT(e)     ((e).rx.flags & EF_EVENT_FLAG_CONT)
153 #define EF_EVENT_RX_SOP(e)      ((e).rx.flags & EF_EVENT_FLAG_SOP)
154 #define EF_EVENT_RX_ISCSI_OKAY(e) ((e).rx.flags & EF_EVENT_FLAG_ISCSI_OK)
155 #define EF_EVENT_FLAG_SOP       0x1
156 #define EF_EVENT_FLAG_CONT      0x2
157 #define EF_EVENT_FLAG_ISCSI_OK  0x4
158
159 #define EF_EVENT_TX_Q_ID(e)     ((e).tx.q_id)
160
161 #define EF_EVENT_RX_DISCARD_Q_ID(e)  ((e).rx_discard.q_id)
162 #define EF_EVENT_RX_DISCARD_LEN(e)   ((e).rx_discard.len)
163 #define EF_EVENT_RX_DISCARD_TYPE(e)  ((e).rx_discard.subtype)
164 enum {
165         EF_EVENT_RX_DISCARD_CSUM_BAD,
166         EF_EVENT_RX_DISCARD_CRC_BAD,
167         EF_EVENT_RX_DISCARD_TRUNC,
168         EF_EVENT_RX_DISCARD_RIGHTS,
169         EF_EVENT_RX_DISCARD_OTHER,
170 };
171
172 #define EF_EVENT_TX_ERROR_Q_ID(e)    ((e).tx_error.q_id)
173 #define EF_EVENT_TX_ERROR_TYPE(e)    ((e).tx_error.subtype)
174 enum {
175         EF_EVENT_TX_ERROR_RIGHTS,
176         EF_EVENT_TX_ERROR_OFLOW,
177         EF_EVENT_TX_ERROR_2BIG,
178         EF_EVENT_TX_ERROR_BUS,
179 };
180
181 #define EF_EVENT_RX_NO_DESC_TRUNC_Q_ID(e)  ((e).rx_no_desc_trunc.q_id)
182
183 #define EF_EVENT_SW_DATA_MASK   0xffff
184 #define EF_EVENT_SW_DATA(e)     ((e).sw.data)
185
186 #define EF_EVENT_FMT            "[ev:%x:%08x:%08x]"
187 #define EF_EVENT_PRI_ARG(e)     (unsigned) (e).generic.type,    \
188                 (unsigned) (e).generic.ev.u32[1],               \
189                 (unsigned) (e).generic.ev.u32[0]
190
191 #define EF_GET_HW_EV(e)         ((e).generic.ev)
192 #define EF_GET_HW_EV_PTR(e)     (&(e).generic.ev)
193 #define EF_GET_HW_EV_U64(e)     ((e).generic.ev.u64[0])
194
195
196 /* ***************** */
197
198 /*! Used by netif shared state. Must use types of explicit size. */
199 typedef struct {
200         uint16_t              rx_last_desc_ptr;   /* for RX duplicates       */
201         uint8_t               bad_sop;            /* bad SOP detected        */
202         uint8_t               frag_num;           /* next fragment #, 0=>SOP */
203 } ef_rx_dup_state_t;
204
205
206 /* Max number of ports on any SF NIC. */
207 #define EFAB_DMAQS_PER_EVQ_MAX 32
208
209 typedef struct {
210         ef_eventq_ptr           evq_ptr;
211         int32_t               trashed;
212         ef_rx_dup_state_t     rx_dup_state[EFAB_DMAQS_PER_EVQ_MAX];
213 } ef_eventq_state;
214
215
216 /*! \i_ef_base [ef_iovec] is similar the standard [struct iovec].  An
217 ** array of these is used to designate a scatter/gather list of I/O
218 ** buffers.
219 */
220 typedef struct {
221         ef_addr                       iov_base EF_VI_ALIGN(8);
222         unsigned                      iov_len;
223 } ef_iovec;
224
225 /* Falcon constants */
226 #define TX_EV_DESC_PTR_LBN 0
227
228
229 /**********************************************************************
230  * ef_vi **************************************************************
231  **********************************************************************/
232
233 enum ef_vi_flags {
234         EF_VI_RX_SCATTER        = 0x1,
235         EF_VI_ISCSI_RX_HDIG     = 0x2,
236         EF_VI_ISCSI_TX_HDIG     = 0x4,
237         EF_VI_ISCSI_RX_DDIG     = 0x8,
238         EF_VI_ISCSI_TX_DDIG     = 0x10,
239         EF_VI_TX_PHYS_ADDR      = 0x20,
240         EF_VI_RX_PHYS_ADDR      = 0x40,
241         EF_VI_TX_IP_CSUM_DIS    = 0x80,
242         EF_VI_TX_TCPUDP_CSUM_DIS= 0x100,
243         EF_VI_TX_TCPUDP_ONLY    = 0x200,
244         /* Flags in range 0xXXXX0000 are for internal use. */
245 };
246
247 typedef struct {
248         uint32_t  added;
249         uint32_t  removed;
250 } ef_vi_txq_state;
251
252 typedef struct {
253         uint32_t  added;
254         uint32_t  removed;
255 } ef_vi_rxq_state;
256
257 typedef struct {
258         uint32_t         mask;
259         void*            doorbell;
260         void*            descriptors;
261         uint16_t*        ids;
262         unsigned         misalign_mask;
263 } ef_vi_txq;
264
265 typedef struct {
266         uint32_t         mask;
267         void*            doorbell;
268         void*            descriptors;
269         uint16_t*        ids;
270 } ef_vi_rxq;
271
272 typedef struct {
273         ef_eventq_state  evq;
274         ef_vi_txq_state  txq;
275         ef_vi_rxq_state  rxq;
276         /* Followed by request id fifos. */
277 } ef_vi_state;
278
279 /*! \i_ef_vi  A virtual interface.
280 **
281 ** An [ef_vi] represents a virtual interface on a specific NIC.  A
282 ** virtual interface is a collection of an event queue and two DMA queues
283 ** used to pass Ethernet frames between the transport implementation and
284 ** the network.
285 */
286 typedef struct ef_vi {
287         unsigned                        magic;
288
289         unsigned                      vi_resource_id;
290         unsigned                      vi_resource_handle_hack;
291         unsigned                      vi_i;
292
293         char*                           vi_mem_mmap_ptr;
294         int                           vi_mem_mmap_bytes;
295         char*                           vi_io_mmap_ptr;
296         int                           vi_io_mmap_bytes;
297
298         ef_eventq_state*              evq_state;
299         char*                         evq_base;
300         unsigned                      evq_mask;
301         ef_vi_ioaddr_t                evq_timer_reg;
302
303         ef_vi_txq                     vi_txq;
304         ef_vi_rxq                     vi_rxq;
305         ef_vi_state*                  ep_state;
306         enum ef_vi_flags              vi_flags;
307 } ef_vi;
308
309
310 enum ef_vi_arch {
311         EF_VI_ARCH_FALCON,
312 };
313
314
315 struct ef_vi_nic_type {
316         unsigned char  arch;
317         char           variant;
318         unsigned char  revision;
319 };
320
321
322 /* This structure is opaque to the client & used to pass mapping data
323  * from the resource manager to the ef_vi lib. for ef_vi_init().
324  */
325 struct vi_mappings {
326         uint32_t         signature;
327 # define VI_MAPPING_VERSION   0x02  /*Byte: Increment me if struct altered*/
328 # define VI_MAPPING_SIGNATURE (0xBA1150 + VI_MAPPING_VERSION)
329
330         struct ef_vi_nic_type nic_type;
331
332         int              vi_instance;
333
334         unsigned         evq_bytes;
335         char*            evq_base;
336         ef_vi_ioaddr_t   evq_timer_reg;
337
338         unsigned         rx_queue_capacity;
339         ef_vi_ioaddr_t   rx_dma_ef1;
340         char*            rx_dma_falcon;
341         ef_vi_ioaddr_t   rx_bell;
342
343         unsigned         tx_queue_capacity;
344         ef_vi_ioaddr_t   tx_dma_ef1;
345         char*            tx_dma_falcon;
346         ef_vi_ioaddr_t   tx_bell;
347 };
348 /* This is used by clients to allocate a suitably sized buffer for the 
349  * resource manager to fill & ef_vi_init() to use. */
350 #define VI_MAPPINGS_SIZE (sizeof(struct vi_mappings))
351
352
353 /**********************************************************************
354  * ef_config **********************************************************
355  **********************************************************************/
356
357 struct ef_config_t {
358         int   log;                    /* debug logging level          */
359 };
360
361 extern struct ef_config_t  ef_config;
362
363
364 /**********************************************************************
365  * ef_vi **************************************************************
366  **********************************************************************/
367
368 /* Initialise [data_area] with information required to initialise an ef_vi.
369  * In the following, an unused param should be set to NULL. Note the case
370  * marked (*) of [iobuf_mmap] for falcon/driver; for normal driver this
371  * must be NULL.
372  *
373  * \param  data_area     [in,out] required, must ref at least VI_MAPPINGS_SIZE 
374  *                                bytes
375  * \param  evq_capacity  [in] number of events in event queue.  Specify 0 for
376  *                            no event queue.
377  * \param  rxq_capacity  [in] number of descriptors in RX DMA queue.  Specify
378  *                            0 for no RX queue.
379  * \param  txq_capacity  [in] number of descriptors in TX DMA queue.  Specify
380  *                            0 for no TX queue.
381  * \param  mmap_info     [in] mem-map info for resource
382  * \param  io_mmap       [in] ef1,    required
383  *                            falcon, required
384  * \param  iobuf_mmap    [in] ef1,    UL: unused
385  *                            falcon, UL: required
386  */
387 extern void ef_vi_init_mapping_vi(void* data_area, struct ef_vi_nic_type,
388                                   unsigned rxq_capacity,
389                                   unsigned txq_capacity, int instance,
390                                   void* io_mmap, void* iobuf_mmap_rx,
391                                   void* iobuf_mmap_tx, enum ef_vi_flags);
392
393
394 extern void ef_vi_init_mapping_evq(void* data_area, struct ef_vi_nic_type,
395                                    int instance, unsigned evq_bytes,
396                                    void* base, void* timer_reg);
397
398 ef_vi_inline unsigned ef_vi_resource_id(ef_vi* vi)
399
400         return vi->vi_resource_id; 
401 }
402
403 ef_vi_inline enum ef_vi_flags ef_vi_flags(ef_vi* vi)
404
405         return vi->vi_flags; 
406 }
407
408
409 /**********************************************************************
410  * Receive interface **************************************************
411  **********************************************************************/
412
413 /*! \i_ef_vi Returns the amount of space in the RX descriptor ring.
414 **
415 ** \return the amount of space in the queue.
416 */
417 ef_vi_inline int ef_vi_receive_space(ef_vi* vi) 
418 {
419         ef_vi_rxq_state* qs = &vi->ep_state->rxq;
420         return vi->vi_rxq.mask - (qs->added - qs->removed);
421 }
422
423
424 /*! \i_ef_vi Returns the fill level of the RX descriptor ring.
425 **
426 ** \return the fill level of the queue.
427 */
428 ef_vi_inline int ef_vi_receive_fill_level(ef_vi* vi) 
429 {
430         ef_vi_rxq_state* qs = &vi->ep_state->rxq;
431         return qs->added - qs->removed;
432 }
433
434
435 ef_vi_inline int ef_vi_receive_capacity(ef_vi* vi)
436
437         return vi->vi_rxq.mask;
438 }
439
440 /*! \i_ef_vi  Complete a receive operation.
441 **
442 ** When a receive completion event is received, it should be passed to
443 ** this function.  The request-id for the buffer that the packet was
444 ** delivered to is returned.
445 **
446 ** After this function returns, more space may be available in the
447 ** receive queue.
448 */
449 extern ef_request_id ef_vi_receive_done(const ef_vi*, const ef_event*);
450
451 /*! \i_ef_vi  Return request ID indicated by a receive event
452  */
453 ef_vi_inline ef_request_id ef_vi_receive_request_id(const ef_vi* vi,
454                                                     const ef_event* ef_ev)
455 {
456         const ef_vi_qword* ev = EF_GET_HW_EV_PTR(*ef_ev);
457         return ev->u32[0] & vi->vi_rxq.mask;
458 }
459   
460
461 /*! \i_ef_vi  Form a receive descriptor.
462 **
463 ** If \c initial_rx_bytes is zero use a reception size at least as large
464 ** as an MTU.
465 */
466 extern int ef_vi_receive_init(ef_vi* vi, ef_addr addr, ef_request_id dma_id,
467                               int intial_rx_bytes);
468
469 /*! \i_ef_vi  Submit initialised receive descriptors to the NIC. */
470 extern void ef_vi_receive_push(ef_vi* vi);
471
472 /*! \i_ef_vi  Post a buffer on the receive queue.
473 **
474 **   \return 0 on success, or -EAGAIN if the receive queue is full
475 */
476 extern int ef_vi_receive_post(ef_vi*, ef_addr addr,
477                               ef_request_id dma_id);
478
479 /**********************************************************************
480  * Transmit interface *************************************************
481  **********************************************************************/
482
483 /*! \i_ef_vi Return the amount of space (in descriptors) in the transmit
484 **           queue.
485 **
486 ** \return the amount of space in the queue (in descriptors)
487 */
488 ef_vi_inline int ef_vi_transmit_space(ef_vi* vi) 
489 {
490         ef_vi_txq_state* qs = &vi->ep_state->txq;
491         return vi->vi_txq.mask - (qs->added - qs->removed);
492 }
493
494
495 /*! \i_ef_vi Returns the fill level of the TX descriptor ring.
496 **
497 ** \return the fill level of the queue.
498 */
499 ef_vi_inline int ef_vi_transmit_fill_level(ef_vi* vi)
500 {
501         ef_vi_txq_state* qs = &vi->ep_state->txq;
502         return qs->added - qs->removed;
503 }
504
505
506 /*! \i_ef_vi Returns the total capacity of the TX descriptor ring.
507 **
508 ** \return the capacity of the queue.
509 */
510 ef_vi_inline int ef_vi_transmit_capacity(ef_vi* vi)
511
512         return vi->vi_txq.mask;
513 }
514
515
516 /*! \i_ef_vi  Transmit a packet.
517 **
518 **   \param bytes must be greater than ETH_ZLEN.
519 **   \return -EAGAIN if the transmit queue is full, or 0 on success
520 */
521 extern int ef_vi_transmit(ef_vi*, ef_addr, int bytes, ef_request_id dma_id);
522
523 /*! \i_ef_vi  Transmit a packet using a gather list.
524 **
525 **   \param iov_len must be greater than zero
526 **   \param iov the first must be non-zero in length (but others need not)
527 **
528 **   \return -EAGAIN if the queue is full, or 0 on success
529 */
530 extern int ef_vi_transmitv(ef_vi*, const ef_iovec* iov, int iov_len,
531                            ef_request_id dma_id);
532
533 /*! \i_ef_vi  Initialise a DMA request.
534 **
535 ** \return -EAGAIN if the queue is full, or 0 on success
536 */
537 extern int ef_vi_transmit_init(ef_vi*, ef_addr, int bytes,
538                                ef_request_id dma_id);
539
540 /*! \i_ef_vi  Initialise a DMA request.
541 **
542 ** \return -EAGAIN if the queue is full, or 0 on success
543 */
544 extern int ef_vi_transmitv_init(ef_vi*, const ef_iovec*, int iov_len,
545                                 ef_request_id dma_id);
546
547 /*! \i_ef_vi  Submit DMA requests to the NIC.
548 **
549 ** The DMA requests must have been initialised using
550 ** ef_vi_transmit_init() or ef_vi_transmitv_init().
551 */
552 extern void ef_vi_transmit_push(ef_vi*);
553
554
555 /*! \i_ef_vi Maximum number of transmit completions per transmit event. */
556 #define EF_VI_TRANSMIT_BATCH  64
557
558 /*! \i_ef_vi Determine the set of [ef_request_id]s for each DMA request
559 **           which has been completed by a given transmit completion
560 **           event.
561 **
562 ** \param ids must point to an array of length EF_VI_TRANSMIT_BATCH
563 ** \return the number of valid [ef_request_id]s (can be zero)
564 */
565 extern int ef_vi_transmit_unbundle(ef_vi* ep, const ef_event*,
566                                    ef_request_id* ids);
567
568
569 /*! \i_ef_event Returns true if ef_eventq_poll() will return event(s). */
570 extern int ef_eventq_has_event(ef_vi* vi);
571
572 /*! \i_ef_event Returns true if there are quite a few events in the event
573 ** queue.
574 **
575 ** This looks ahead in the event queue, so has the property that it will
576 ** not ping-pong a cache-line when it is called concurrently with events
577 ** being delivered.
578 */
579 extern int ef_eventq_has_many_events(ef_vi* evq, int look_ahead);
580
581 /*! Type of function to handle unknown events arriving on event queue
582 **  Return CI_TRUE iff the event has been handled.
583 */
584 typedef int/*bool*/ ef_event_handler_fn(void* priv, ef_vi* evq, ef_event* ev);
585
586 /*! Standard poll exception routine */
587 extern int/*bool*/ ef_eventq_poll_exception(void* priv, ef_vi* evq,
588                                             ef_event* ev);
589
590 /*! \i_ef_event  Retrieve events from the event queue, handle RX/TX events
591 **  and pass any others to an exception handler function
592 **
593 **   \return The number of events retrieved.
594 */
595 extern int ef_eventq_poll_evs(ef_vi* evq, ef_event* evs, int evs_len,
596                               ef_event_handler_fn *exception, void *expt_priv);
597
598 /*! \i_ef_event  Retrieve events from the event queue.
599 **
600 **   \return The number of events retrieved.
601 */
602 ef_vi_inline int ef_eventq_poll(ef_vi* evq, ef_event* evs, int evs_len)
603 {
604         return ef_eventq_poll_evs(evq, evs, evs_len,
605                             &ef_eventq_poll_exception, (void*)0);
606 }
607
608 /*! \i_ef_event Returns the capacity of an event queue. */
609 ef_vi_inline int ef_eventq_capacity(ef_vi* vi) 
610 {
611         return (vi->evq_mask + 1u) / sizeof(ef_hw_event);
612 }
613
614 /* Returns the instance ID of [vi] */
615 ef_vi_inline unsigned ef_vi_instance(ef_vi* vi)
616 { return vi->vi_i; }
617
618
619 /**********************************************************************
620  * Initialisation *****************************************************
621  **********************************************************************/
622
623 /*! Return size of state buffer of an initialised VI. */
624 extern int ef_vi_state_bytes(ef_vi*);
625
626 /*! Return size of buffer needed for VI state given sizes of RX and TX
627 ** DMA queues.  Queue sizes must be legal sizes (power of 2), or 0 (no
628 ** queue).
629 */
630 extern int ef_vi_calc_state_bytes(int rxq_size, int txq_size);
631
632 /*! Initialise [ef_vi] from the provided resources. [vvis] must have been
633 ** created by ef_make_vi_data() & remains owned by the caller.
634 */
635 extern void ef_vi_init(ef_vi*, void* vi_info, ef_vi_state* state,
636                        ef_eventq_state* evq_state, enum ef_vi_flags);
637
638 extern void ef_vi_state_init(ef_vi*);
639 extern void ef_eventq_state_init(ef_vi*);
640
641 /*! Convert an efhw device arch to ef_vi_arch, or returns -1 if not
642 ** recognised.
643 */
644 extern int  ef_vi_arch_from_efhw_arch(int efhw_arch);
645
646
647 #endif /* __EFAB_EF_VI_H__ */