source: rtems/c/src/lib/libbsp/sparc/shared/include/grspw_pkt.h @ eb5a42f6

5
Last change on this file since eb5a42f6 was eb5a42f6, checked in by Daniel Hellstrom <daniel@…>, on 03/23/16 at 09:45:26

leon, grspw_pkt: fixed device/dma closing

The user is now responsible to stop and close the DMA channels
before closing the device. To prevent complicated situations and
blocking the caller of grspw_close and grspw_dma_close a return
code was added to indicate to the user that the DMA may not have
been stopped or that blocked tasks are still active within the
driver for the specified device.

  • Property mode set to 100644
File size: 23.3 KB
Line 
1/*
2 *  GRSPW/GRSPW2 SpaceWire Kernel Library Interface
3 *
4 *  COPYRIGHT (c) 2011
5 *  Cobham Gaisler AB
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.org/license/LICENSE.
10 */
11
12#ifndef __GRSPW_PKT_H__
13#define __GRSPW_PKT_H__
14
15struct grspw_pkt;
16
17/* Maximum number of GRSPW devices supported by driver */
18#define GRSPW_MAX 32
19
20/* Weak overridable variable the user can use to define the worker-task
21 * priority (0..255) or to disable (-1) the creation of the worker-task
22 * and the message queue to save space */
23extern int grspw_work_task_priority;
24
25#ifndef GRSPW_PKT_FLAGS
26#define GRSPW_PKT_FLAGS
27/*** TX Packet flags ***/
28
29/* Enable IRQ generation */
30#define TXPKT_FLAG_IE 0x0040
31
32/* Enable Header CRC generation (if CRC is available in HW)
33 * Header CRC will be appended (one byte at end of header)
34 */
35#define TXPKT_FLAG_HCRC 0x0100
36
37/* Enable Data CRC generation (if CRC is available in HW)
38 * Data CRC will be appended (one byte at end of packet)
39 */
40#define TXPKT_FLAG_DCRC 0x0200
41
42/* Control how many bytes the beginning of the Header
43 * the CRC should not be calculated for */
44#define TXPKT_FLAG_NOCRC_MASK 0x0000000f
45#define TXPKT_FLAG_NOCRC_LEN0 0x00000000
46#define TXPKT_FLAG_NOCRC_LEN1 0x00000001
47#define TXPKT_FLAG_NOCRC_LEN2 0x00000002
48#define TXPKT_FLAG_NOCRC_LEN3 0x00000003
49#define TXPKT_FLAG_NOCRC_LEN4 0x00000004
50#define TXPKT_FLAG_NOCRC_LEN5 0x00000005
51#define TXPKT_FLAG_NOCRC_LEN6 0x00000006
52#define TXPKT_FLAG_NOCRC_LEN7 0x00000007
53#define TXPKT_FLAG_NOCRC_LEN8 0x00000008
54#define TXPKT_FLAG_NOCRC_LEN9 0x00000009
55#define TXPKT_FLAG_NOCRC_LENa 0x0000000a
56#define TXPKT_FLAG_NOCRC_LENb 0x0000000b
57#define TXPKT_FLAG_NOCRC_LENc 0x0000000c
58#define TXPKT_FLAG_NOCRC_LENd 0x0000000d
59#define TXPKT_FLAG_NOCRC_LENe 0x0000000e
60#define TXPKT_FLAG_NOCRC_LENf 0x0000000f
61
62#define TXPKT_FLAG_INPUT_MASK (TXPKT_FLAG_NOCRC_MASK | TXPKT_FLAG_IE | \
63                                TXPKT_FLAG_HCRC | TXPKT_FLAG_DCRC)
64
65/* Marks if packet was transmitted or not */
66#define TXPKT_FLAG_TX 0x4000
67
68/* Link Error */
69#define TXPKT_FLAG_LINKERR 0x8000
70
71#define TXPKT_FLAG_OUTPUT_MASK (TXPKT_FLAG_TX | TXPKT_FLAG_LINKERR)
72
73/*** RX Packet Flags ***/
74
75/* Enable IRQ generation */
76#define RXPKT_FLAG_IE 0x0010
77
78#define RXPKT_FLAG_INPUT_MASK (RXPKT_FLAG_IE)
79
80/* Packet was truncated */
81#define RXPKT_FLAG_TRUNK 0x0800
82/* Data CRC error (only valid if RMAP CRC is enabled) */
83#define RXPKT_FLAG_DCRC 0x0400
84/* Header CRC error (only valid if RMAP CRC is enabled) */
85#define RXPKT_FLAG_HCRC 0x0200
86/* Error in End-of-Packet */
87#define RXPKT_FLAG_EEOP 0x0100
88/* Marks if packet was recevied or not */
89#define RXPKT_FLAG_RX 0x8000
90
91#define RXPKT_FLAG_OUTPUT_MASK (RXPKT_FLAG_TRUNK | RXPKT_FLAG_DCRC | \
92                                RXPKT_FLAG_HCRC | RXPKT_FLAG_EEOP)
93
94/*** General packet flag options ***/
95
96/* Translate Hdr and/or Payload address */
97#define PKT_FLAG_TR_DATA 0x1000
98#define PKT_FLAG_TR_HDR 0x2000
99/* All General options */
100#define PKT_FLAG_MASK 0x3000
101
102#endif
103/* GRSPW RX/TX Packet structure.
104 *
105 * - For RX the 'hdr' and 'hlen' fields are not used, they are not written
106 *   by driver.
107 *
108 * - The 'pkt_id' field is untouched by driver, it is intended for packet
109 *   numbering or user-custom data.
110 *
111 * - The last packet in a list must have 'next' set to NULL.
112 *
113 * - data and hdr pointers are written without modification to hardware,
114 *   this means that caller must do address translation to hardware
115 *   address itself.
116 *
117 * - the 'flags' field are interpreted differently depending on transfer
118 *   type (RX/TX). See XXPKT_FLAG_* options above.
119 */
120struct grspw_pkt {
121        struct grspw_pkt *next; /* Next packet in list. NULL if last packet */
122        unsigned int pkt_id;    /* User assigned ID (not touched by driver) */
123        unsigned short flags;   /* RX/TX Options and status */
124        unsigned char reserved; /* Reserved, must be zero */
125        unsigned char hlen;     /* Length of Header Buffer (only TX) */
126        unsigned int dlen;      /* Length of Data Buffer */
127        void *data;     /* 4-byte or byte aligned depends on HW */
128        void *hdr;      /* 4-byte or byte aligned depends on HW (only TX) */
129};
130
131/* GRSPW SpaceWire Packet List */
132struct grspw_list {
133        struct grspw_pkt *head;
134        struct grspw_pkt *tail;
135};
136
137/* SpaceWire Link State */
138typedef enum {
139        SPW_LS_ERRRST = 0,
140        SPW_LS_ERRWAIT = 1,
141        SPW_LS_READY = 2,
142        SPW_LS_CONNECTING = 3,
143        SPW_LS_STARTED = 4,
144        SPW_LS_RUN = 5
145} spw_link_state_t;
146
147/* Address Configuration */
148struct grspw_addr_config {
149        /* Ignore address field and put all received packets to first
150         * DMA channel.
151         */
152        int promiscuous;
153
154        /* Default Node Address and Mask */
155        unsigned char def_addr;
156        unsigned char def_mask;
157        /* DMA Channel custom Node Address and Mask */
158        struct {
159                char node_en;                   /* Enable Separate Addr */
160                unsigned char node_addr;        /* Node address */
161                unsigned char node_mask;        /* Node address mask */
162        } dma_nacfg[4];
163};
164
165/* Hardware Support in GRSPW Core */
166struct grspw_hw_sup {
167        char    rmap;           /* If RMAP in HW is available */
168        char    rmap_crc;       /* If RMAP CRC is available */
169        char    rx_unalign;     /* RX unaligned (byte boundary) access allowed*/
170        char    nports;         /* Number of Ports (1 or 2) */
171        char    ndma_chans;     /* Number of DMA Channels (1..4) */
172        char    strip_adr;      /* Hardware can strip ADR from packet data */
173        char    strip_pid;      /* Hardware can strip PID from packet data */
174        int     hw_version;     /* GRSPW Hardware Version */
175        char    reserved[2];
176        char    irq;            /* SpW Distributed Interrupt available if 1 */
177        char    irq_num;        /* Number of interrupts that can be generated */
178        char    itmr_width;     /* SpW Intr. ISR timers bit width. 0=no timer */
179};
180
181struct grspw_core_stats {
182        int irq_cnt;
183        int err_credit;
184        int err_eeop;
185        int err_addr;
186        int err_parity;
187        int err_disconnect;
188        int err_escape;
189        int err_wsync; /* only in GRSPW1 */
190};
191
192/* grspw_link_ctrl() options */
193#define LINKOPTS_ENABLE         0x0000
194#define LINKOPTS_DISABLE        0x0001
195#define LINKOPTS_START          0x0002
196#define LINKOPTS_AUTOSTART      0x0004
197#define LINKOPTS_DIS_ONERR      0x0008  /* Disable DMA transmitter on link error
198                                         * Controls LE bit in DMACTRL register.
199                                         */
200#define LINKOPTS_DIS_ON_CE      0x0020000/* Disable Link on Credit error */
201#define LINKOPTS_DIS_ON_ER      0x0040000/* Disable Link on Escape error */
202#define LINKOPTS_DIS_ON_DE      0x0080000/* Disable Link on Disconnect error */
203#define LINKOPTS_DIS_ON_PE      0x0100000/* Disable Link on Parity error */
204#define LINKOPTS_DIS_ON_WE      0x0400000/* Disable Link on write synchonization
205                                          * error (GRSPW1 only)
206                                          */
207#define LINKOPTS_DIS_ON_EE      0x1000000/* Disable Link on Early EOP/EEP error*/
208
209/*#define LINKOPTS_TICK_OUT_IRQ 0x0100*//* Enable Tick-out IRQ */
210#define LINKOPTS_EIRQ           0x0200  /* Enable Error Link IRQ */
211
212#define LINKOPTS_MASK           0x15e020f/* All above options */
213#define LINKOPTS_MASK_DIS_ON    0x15e0000/* All disable link on error options
214                                          * On a certain error the link disable
215                                          * bit will be written and the work
216                                          * task will call dma_stop() for all
217                                          * channels.
218                                          */
219
220#define LINKSTS_CE              0x002   /* Credit error */
221#define LINKSTS_ER              0x004   /* Escape error */
222#define LINKSTS_DE              0x008   /* Disconnect error */
223#define LINKSTS_PE              0x010   /* Parity error */
224#define LINKSTS_WE              0x040   /* Write synchonization error (GRSPW1 only) */
225#define LINKSTS_IA              0x080   /* Invalid address */
226#define LINKSTS_EE              0x100   /* Early EOP/EEP */
227#define LINKSTS_MASK            0x1de
228
229/* grspw_tc_ctrl() options */
230#define TCOPTS_EN_RXIRQ 0x0001  /* Tick-Out IRQ */
231#define TCOPTS_EN_TX    0x0004
232#define TCOPTS_EN_RX    0x0008
233
234/* grspw_ic_ctrl() options:
235 * Corresponds code duplicatingly to GRSPW_CTRL_XX_BIT defines
236 */
237#define ICOPTS_INTNUM           (0x1f << 27)
238#define ICOPTS_EN_SPWIRQ_ON_EE  (1 << 24)
239#define ICOPTS_EN_SPWIRQ_ON_IA  (1 << 23)
240#define ICOPTS_EN_PRIO          (1 << 22)
241#define ICOPTS_EN_TIMEOUTIRQ    (1 << 20)
242#define ICOPTS_EN_ACKIRQ        (1 << 19)
243#define ICOPTS_EN_TICKOUTIRQ    (1 << 18)
244#define ICOPTS_EN_RX            (1 << 17)
245#define ICOPTS_EN_TX            (1 << 16)
246#define ICOPTS_BASEIRQ          (0x1f << 8)
247#define ICOPTS_EN_FLAGFILTER    (1 << 0) /* NOTE: Not in icctrl. CTRL.bit12 */
248
249/* grspw_ic_rlisr() and grspw_ic_rlintack()  */
250#define ICRELOAD_EN             (1 << 31)
251#define ICRELOAD_MASK           0x7fffffff
252
253/* grspw_rmap_ctrl() options */
254#define RMAPOPTS_EN_RMAP        0x0001
255#define RMAPOPTS_EN_BUF         0x0002
256
257/* grspw_dma_config.flags options */
258#define DMAFLAG_NO_SPILL        0x0001  /* See HW doc DMA-CTRL NS bit */
259#define DMAFLAG_RESV1           0x0002  /* HAS NO EFFECT */
260#define DMAFLAG_STRIP_ADR       0x0004  /* See HW doc DMA-CTRL SA bit */
261#define DMAFLAG_STRIP_PID       0x0008  /* See HW doc DMA-CTRL SP bit */
262#define DMAFLAG_RESV2           0x0010  /* HAS NO EFFECT */
263#define DMAFLAG_MASK    (DMAFLAG_NO_SPILL|DMAFLAG_STRIP_ADR|DMAFLAG_STRIP_PID)
264
265struct grspw_dma_config {
266        int flags;              /* DMA config flags, see DMAFLAG_* options */
267        int rxmaxlen;           /* RX Max Packet Length */
268        int rx_irq_en_cnt;      /* Enable RX IRQ every cnt descriptors */
269        int tx_irq_en_cnt;      /* Enable TX IRQ every cnt descriptors */
270};
271
272/* Statistics per DMA channel */
273struct grspw_dma_stats {
274        /* IRQ Statistics */
275        int irq_cnt;            /* Number of DMA IRQs generated by channel */
276
277        /* Descriptor Statistics */
278        int tx_pkts;            /* Number of Transmitted packets */
279        int tx_err_link;        /* Number of Transmitted packets with Link Error*/
280        int rx_pkts;            /* Number of Received packets */
281        int rx_err_trunk;       /* Number of Received Truncated packets */
282        int rx_err_endpkt;      /* Number of Received packets with bad ending */
283
284        /* Diagnostics to help developers sizing their number buffers to avoid
285         * out-of-buffers or other phenomenons.
286         */
287        int send_cnt_min;       /* Minimum number of packets in TX SEND Q */
288        int send_cnt_max;       /* Maximum number of packets in TX SEND Q */
289        int tx_sched_cnt_min;   /* Minimum number of packets in TX SCHED Q */
290        int tx_sched_cnt_max;   /* Maximum number of packets in TX SCHED Q */
291        int sent_cnt_max;       /* Maximum number of packets in TX SENT Q */
292        int tx_work_cnt;        /* Times the work thread processed TX BDs */
293        int tx_work_enabled;    /* No. RX BDs enabled by work thread */
294
295        int ready_cnt_min;      /* Minimum number of packets in RX READY Q */
296        int ready_cnt_max;      /* Maximum number of packets in RX READY Q */
297        int rx_sched_cnt_min;   /* Minimum number of packets in RX SCHED Q */
298        int rx_sched_cnt_max;   /* Maximum number of packets in RX SCHED Q */
299        int recv_cnt_max;       /* Maximum number of packets in RX RECV Q */
300        int rx_work_cnt;        /* Times the work thread processed RX BDs */
301        int rx_work_enabled;    /* No. RX BDs enabled by work thread */
302};
303
304extern void grspw_initialize_user(
305        /* Callback every time a GRSPW device is found. Args: DeviceIndex */
306        void *(*devfound)(int),
307        /* Callback every time a GRSPW device is removed. Args:
308         * int   = DeviceIndex
309         * void* = Return Value from devfound()
310         */
311        void (*devremove)(int,void*)
312        );
313extern int grspw_dev_count(void);
314extern void *grspw_open(int dev_no);
315extern int grspw_close(void *d);
316extern void grspw_hw_support(void *d, struct grspw_hw_sup *hw);
317extern void grspw_stats_read(void *d, struct grspw_core_stats *sts);
318extern void grspw_stats_clr(void *d);
319
320/* Set and Read current node address configuration. The dma_nacfg[N] field
321 * represents the configuration for DMA Channel N.
322 *
323 * Set cfg->promiscous to -1 in order to only read current configuration.
324 */
325extern void grspw_addr_ctrl(void *d, struct grspw_addr_config *cfg);
326
327/*** Link Control interface ***/
328/* Read Link State */
329extern spw_link_state_t grspw_link_state(void *d);
330/* options [in/out]: set to -1 to only read current config
331 *
332 * CLKDIV register contain:
333 *  bits 7..0  : Clock Div RUN (only run-state)
334 *  bits 15..8 : Clock Div During Startup (all link states except run-state)
335 */
336extern void grspw_link_ctrl(void *d, int *options, int *stscfg, int *clkdiv);
337/* Read the current value of the status register */
338extern unsigned int grspw_link_status(void *d);
339/* Clear bits in the status register */
340extern void grspw_link_status_clr(void *d, unsigned int clearmask);
341
342/*** Time Code Interface ***/
343/* Generate Tick-In (increment Time Counter, Send Time Code) */
344extern void grspw_tc_tx(void *d);
345/* Control Timcode settings of core */
346extern void grspw_tc_ctrl(void *d, int *options);
347/* Assign ISR Function to TimeCode RX IRQ */
348extern void grspw_tc_isr(void *d, void (*tcisr)(void *data, int tc), void *data);
349/* Read/Write TCTRL and TIMECNT. Write if not -1, always read current value
350 * TCTRL   = bits 7 and 6
351 * TIMECNT = bits 5 to 0
352 */
353extern void grspw_tc_time(void *d, int *time);
354
355/*** Interrupt-code Interface ***/
356struct spwpkt_ic_config {
357        unsigned int tomask;
358        unsigned int aamask;
359        unsigned int scaler;
360        unsigned int isr_reload;
361        unsigned int ack_reload;
362};
363/* Function Interrupt-Code ISR callback prototype. Called when respective
364 * interrupt handling option has been enabled by grspw_ic_ctrl(), the
365 * arguments rxirq, rxack and intto are read from the registers of the
366 * GRSPW core read by the GRSPW ISR, they are individually valid only when
367 * repective handling been turned on.
368 *
369 * data    - Custom data provided by user
370 * rxirq   - Interrupt-Code Recevie register of the GRSPW core read by ISR
371 *           (only defined if IQ bit enabled through grspw_ic_ctrl())
372 * rxack   - Interrupt-Ack-Code Recevie register of the GRSPW core read by ISR
373 *           (only defined if AQ bit enabled through grspw_ic_ctrl())
374 * intto   - Interrupt Tick-out Recevie register of the GRSPW core read by ISR
375 *           (only defined if TQ bit enabled through grspw_ic_ctrl())
376 */
377typedef void (*spwpkt_ic_isr_t)(void *data, unsigned int rxirq,
378                                unsigned int rxack, unsigned int intto);
379/* Control Interrupt-code settings of core
380 * Write if 'options' not pointing to -1, always read current value
381 */
382extern void grspw_ic_ctrl(void *d, unsigned int *options);
383/* Write (rw&1 == 1) configuration parameters to registers and/or,
384 * Read  (rw&2 == 1) configuration parameters from registers, in that sequence.
385 */
386extern void grspw_ic_config(void *d, int rw, struct spwpkt_ic_config *cfg);
387/* Read or Write Interrupt-code status registers.
388 * If pointer argument *ptr == 0 then only read, if *ptr != 0 then only write.
389 * If *ptr is NULL no operation.
390 */
391extern void grspw_ic_sts(void *d, unsigned int *rxirq, unsigned int *rxack,
392                        unsigned int *intto);
393/* Generate Tick-In for the given Interrupt-code
394 * Returns zero on success and non-zero on failure
395 *
396 * Interrupt code bits (ic):
397 * Bit 5 - ACK if 1
398 * Bits 4-0 Interrupt-code number
399 */
400extern int grspw_ic_tickin(void *d, int ic);
401/* Assign handler function to Interrupt-code timeout IRQ */
402extern void grspw_ic_isr(void *d, spwpkt_ic_isr_t handler, void *data);
403
404/*** RMAP Control Interface ***/
405/* Set (not -1) and/or read RMAP options. */
406extern int grspw_rmap_ctrl(void *d, int *options, int *dstkey);
407extern void grspw_rmap_support(void *d, char *rmap, char *rmap_crc);
408
409/*** SpW Port Control Interface ***/
410
411/* Select port, if
412 * -1=The current selected port is returned
413 * 0=Port 0
414 * 1=Port 1
415 * Other positive values=Both Port0 and Port1
416 */
417extern int grspw_port_ctrl(void *d, int *port);
418/* Returns Number ports available in hardware */
419extern int grspw_port_count(void *d);
420/* Returns the current active port */
421extern int grspw_port_active(void *d);
422
423/*** DMA Interface ***/
424extern void *grspw_dma_open(void *d, int chan_no);
425extern int grspw_dma_close(void *c);
426
427extern int grspw_dma_start(void *c);
428extern void grspw_dma_stop(void *c);
429
430/* Schedule List of packets for transmission at some point in
431 * future.
432 *
433 * 1. Move transmitted packets to SENT List (SCHED->SENT)
434 * 2. Add the requested packets to the SEND List (USER->SEND)
435 * 3. Schedule as many packets as possible for transmission (SEND->SCHED)
436 *
437 * Call this function with pkts=NULL to just do step 1 and 3. This may be
438 * required in Polling-mode.
439 *
440 * The above steps 1 and 3 may be skipped by setting 'opts':
441 *  bit0 = 1: Skip Step 1.
442 *  bit1 = 1: Skip Step 3.
443 * Skipping both step 1 and 3 may be usefull when IRQ is enabled, then
444 * the work queue will be totaly responsible for handling descriptors.
445 *
446 * The fastest solution in retreiving sent TX packets and sending new frames
447 * is to call:
448 *  A. grspw_dma_tx_reclaim(opts=0)
449 *  B. grspw_dma_tx_send(opts=1)
450 *
451 * NOTE: the TXPKT_FLAG_TX flag must not be set.
452 *
453 * Return Code
454 *  -1   Error
455 *  0    Successfully added pkts to send/sched list
456 *  1    DMA stopped. No operation.
457 */
458extern int grspw_dma_tx_send(void *c, int opts, struct grspw_list *pkts, int count);
459
460/* Reclaim TX packet buffers that has previously been scheduled for transmission
461 * with grspw_dma_tx_send().
462 *
463 * 1. Move transmitted packets to SENT List (SCHED->SENT)
464 * 2. Move all SENT List to pkts list (SENT->USER)
465 * 3. Schedule as many packets as possible for transmission (SEND->SCHED)
466 *
467 * The above steps 1 may be skipped by setting 'opts':
468 *  bit0 = 1: Skip Step 1.
469 *  bit1 = 1: Skip Step 3.
470 *
471 * The fastest solution in retreiving sent TX packets and sending new frames
472 * is to call:
473 *  A. grspw_dma_tx_reclaim(opts=2) (Skip step 3)
474 *  B. grspw_dma_tx_send(opts=1) (Skip step 1)
475 *
476 * Return Code
477 *  -1   Error
478 *  0    Successful. pkts list filled with all packets from sent list
479 *  1    Same as 0, but indicates that DMA stopped
480 */
481extern int grspw_dma_tx_reclaim(void *c, int opts, struct grspw_list *pkts, int *count);
482
483/* Get current number of Packets in respective TX Queue. */
484extern void grspw_dma_tx_count(void *c, int *send, int *sched, int *sent);
485
486#define GRSPW_OP_AND 0
487#define GRSPW_OP_OR 1
488/* Block until send_cnt or fewer packets are Queued in "Send and Scheduled" Q,
489 * op (AND or OR), sent_cnt or more packet "have been sent" (Sent Q) condition
490 * is met.
491 * If a link error occurs and the Stop on Link error is defined, this function
492 * will also return to caller.
493 * The timeout argument is used to return after timeout ticks, regardless of
494 * the other conditions. If timeout is zero, the function will wait forever
495 * until the condition is satisfied.
496 *
497 * NOTE: if IRQ of TX descriptors are not enabled conditions are never
498 *       checked, this may hang infinitely unless a timeout has been specified
499 *
500 * Return Code
501 *  -1   Error
502 *  0    Returing to caller because specified conditions are now fullfilled
503 *  1    DMA stopped
504 *  2    Timeout, conditions are not met
505 *  3    Another task is already waiting. Service is Busy.
506 */
507extern int grspw_dma_tx_wait(void *c, int send_cnt, int op, int sent_cnt, int timeout);
508
509/* Get received RX packet buffers that has previously been scheduled for
510 * reception with grspw_dma_rx_prepare().
511 *
512 * 1. Move Scheduled packets to RECV List (SCHED->RECV)
513 * 2. Move all RECV packet to the callers list (RECV->USER)
514 * 3. Schedule as many free packet buffers as possible (READY->SCHED)
515 *
516 * The above steps 1 may be skipped by setting 'opts':
517 *  bit0 = 1: Skip Step 1.
518 *  bit1 = 1: Skip Step 3.
519 *
520 * The fastest solution in retreiving received RX packets and preparing new
521 * packet buffers for future receive, is to call:
522 *  A. grspw_dma_rx_recv(opts=2, &recvlist) (Skip step 3)
523 *  B. grspw_dma_rx_prepare(opts=1, &freelist) (Skip step 1)
524 *
525 * Return Code
526 *  -1   Error
527 *  0    Successfully filled pkts list with packets from recv list.
528 *  1    DMA stopped
529 */
530extern int grspw_dma_rx_recv(void *c, int opts, struct grspw_list *pkts, int *count);
531
532/* Add more RX packet buffers for future for reception. The received packets
533 * can later be read out with grspw_dma_rx_recv().
534 *
535 * 1. Move Received packets to RECV List (SCHED->RECV)
536 * 2. Add the "free/ready" packet buffers to the READY List (USER->READY)
537 * 3. Schedule as many packets as possible (READY->SCHED)
538 *
539 * The above steps 1 may be skipped by setting 'opts':
540 *  bit0 = 1: Skip Step 1.
541 *  bit1 = 1: Skip Step 3.
542 *
543 * The fastest solution in retreiving received RX packets and preparing new
544 * packet buffers for future receive, is to call:
545 *  A. grspw_dma_rx_recv(opts=2, &recvlist) (Skip step 3)
546 *  B. grspw_dma_rx_prepare(opts=1, &freelist) (Skip step 1)
547 *
548 * Return Code
549 *  -1   Error
550 *  0    Successfully added packet buffers from pkt list into the ready queue
551 *  1    DMA stopped
552 */
553extern int grspw_dma_rx_prepare(void *c, int opts, struct grspw_list *pkts, int count);
554
555/* Get current number of Packets in respective RX Queue. */
556extern void grspw_dma_rx_count(void *c, int *ready, int *sched, int *recv);
557
558/* Block until recv_cnt or more packets are Queued in RECV Q, op (AND or OR),
559 * ready_cnt or fewer packet buffers are available in the "READY and Scheduled" Q,
560 * condition is met.
561 * If a link error occurs and the Stop on Link error is defined, this function
562 * will also return to caller, however with an error.
563 * The timeout argument is used to return after timeout ticks, regardless of
564 * the other conditions. If timeout is zero, the function will wait forever
565 * until the condition is satisfied.
566 *
567 * NOTE: if IRQ of RX descriptors are not enabled conditions are never
568 *       checked, this may hang infinitely unless a timeout has been specified
569 *
570 * Return Code
571 *  -1   Error
572 *  0    Returing to caller because specified conditions are now fullfilled
573 *  1    DMA stopped
574 *  2    Timeout, conditions are not met
575 *  3    Another task is already waiting. Service is Busy.
576 */
577extern int grspw_dma_rx_wait(void *c, int recv_cnt, int op, int ready_cnt, int timeout);
578
579extern int grspw_dma_config(void *c, struct grspw_dma_config *cfg);
580extern void grspw_dma_config_read(void *c, struct grspw_dma_config *cfg);
581
582extern void grspw_dma_stats_read(void *c, struct grspw_dma_stats *sts);
583extern void grspw_dma_stats_clr(void *c);
584
585/* Register GRSPW packet driver to Driver Manager */
586void grspw2_register_drv (void);
587
588/*** GRSPW SpaceWire Packet List Handling Routines ***/
589
590static inline void grspw_list_clr(struct grspw_list *list)
591{
592        list->head = NULL;
593        list->tail = NULL;
594}
595
596static inline int grspw_list_is_empty(struct grspw_list *list)
597{
598        return (list->head == NULL);
599}
600
601/* Return Number of entries in list */
602static inline int grspw_list_cnt(struct grspw_list *list)
603{
604        struct grspw_pkt *lastpkt = NULL, *pkt = list->head;
605        int cnt = 0;
606        while ( pkt ) {
607                cnt++;
608                lastpkt = pkt;
609                pkt = pkt->next;
610        }
611        if ( lastpkt && (list->tail != lastpkt) )
612                return -1;
613        return cnt;
614}
615
616static inline void
617grspw_list_append(struct grspw_list *list, struct grspw_pkt *pkt)
618{
619        pkt->next = NULL;
620        if ( list->tail == NULL ) {
621                list->head = pkt;
622        } else {
623                list->tail->next = pkt;
624        }
625        list->tail = pkt;
626}
627
628static inline void
629grspw_list_prepend(struct grspw_list *list, struct grspw_pkt *pkt)
630{
631        pkt->next = list->head;
632        if ( list->head == NULL ) {
633                list->tail = pkt;
634        }
635        list->head = pkt;
636}
637
638static inline void
639grspw_list_append_list(struct grspw_list *list, struct grspw_list *alist)
640{
641        alist->tail->next = NULL;
642        if ( list->tail == NULL ) {
643                list->head = alist->head;
644        } else {
645                list->tail->next = alist->head;
646        }
647        list->tail = alist->tail;
648}
649
650static inline void
651grspw_list_prepend_list(struct grspw_list *list, struct grspw_list *alist)
652{
653        if ( list->head == NULL ) {
654                list->tail = alist->tail;
655                alist->tail->next = NULL;
656        } else {
657                alist->tail->next = list->head;
658        }
659        list->head = alist->head;
660}
661
662/* Remove dlist (delete-list) from head of list */
663static inline void
664grspw_list_remove_head_list(struct grspw_list *list, struct grspw_list *dlist)
665{
666        list->head = dlist->tail->next;
667        if ( list->head == NULL ) {
668                list->tail = NULL;
669        }
670        dlist->tail->next = NULL;
671}
672
673/* Take A number of entries from head of list 'list' and put the entires
674 * to rlist (result list).
675 */
676static inline int
677grspw_list_take_head_list(struct grspw_list *list, struct grspw_list *rlist, int max)
678{
679        int cnt;
680        struct grspw_pkt *pkt, *last;
681
682        pkt = list->head;
683
684        if ( (max < 1) || (pkt == NULL) ) {
685                grspw_list_clr(rlist);
686                return 0;
687        }
688
689        cnt = 0;
690        rlist->head = pkt;
691        last = pkt;
692        while ((cnt < max) && pkt) {
693                last = pkt;
694                pkt = pkt->next;
695                cnt++;
696        }
697        rlist->tail = last;
698        grspw_list_remove_head_list(list, rlist);
699        return cnt;
700}
701
702#endif
Note: See TracBrowser for help on using the repository browser.