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

5
Last change on this file since fec8288 was fec8288, checked in by Daniel Hellstrom <daniel@…>, on 01/23/17 at 15:45:48

leon, grspw_pkt: SMP support

The driver already was developed with SMP in mind however SMP was
disabled waiting for final fixups and testing.

The new function to control the affinity of the ISR was added
but does not work for now since the LEON BSP does not reroute
IRQs between CPUs during run-time:

grspw_isr_affinity()

  • Property mode set to 100644
File size: 29.2 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/* grspw_dma_config.flags misc options (not shifted internally) */
265#define DMAFLAG2_TXIE   0x00100000      /* See HW doc DMA-CTRL TI bit.
266                                         * Used to enable TX DMA interrupt
267                                         * when tx_irq_en_cnt=0.
268                                         */
269#define DMAFLAG2_RXIE   0x00200000      /* See HW doc DMA-CTRL RI bit.
270                                         * Used to enable RX DMA interrupt
271                                         * when rx_irq_en_cnt=0.
272                                         */
273/* Defines how the ISR will disable RX/TX DMA interrupt source when a DMA RX/TX
274 * interrupt has happended. DMA Error Interrupt always disables both RX/TX DMA
275 * interrupt. By default both RX/TX IRQs are disabled when either a RX, TX or
276 * both RX/TX DMA interrupt has been requested. The work-task, custom
277 * application handler or custom ISR handler is responsible to re-enable
278 * DMA interrupts.
279 */
280#define DMAFLAG2_IRQD_SRC  0x01000000   /* Disable triggering RX/TX source */
281#define DMAFLAG2_IRQD_NONE 0x00c00000   /* Never disable RX/TX IRQ in ISR */
282#define DMAFLAG2_IRQD_BOTH 0x00000000   /* Always disable both RX/TX sources */
283#define DMAFLAG2_IRQD_MASK 0x01c00000   /* Mask of options */
284#define DMAFLAG2_IRQD_BIT  22
285
286#define DMAFLAG2_MASK   (DMAFLAG2_TXIE | DMAFLAG2_RXIE | DMAFLAG2_IRQD_MASK)
287
288struct grspw_dma_config {
289        int flags;              /* DMA config flags, see DMAFLAG1&2_* options */
290        int rxmaxlen;           /* RX Max Packet Length */
291        int rx_irq_en_cnt;      /* Enable RX IRQ every cnt descriptors */
292        int tx_irq_en_cnt;      /* Enable TX IRQ every cnt descriptors */
293};
294
295/* Statistics per DMA channel */
296struct grspw_dma_stats {
297        /* IRQ Statistics */
298        int irq_cnt;            /* Number of DMA IRQs generated by channel */
299
300        /* Descriptor Statistics */
301        int tx_pkts;            /* Number of Transmitted packets */
302        int tx_err_link;        /* Number of Transmitted packets with Link Error*/
303        int rx_pkts;            /* Number of Received packets */
304        int rx_err_trunk;       /* Number of Received Truncated packets */
305        int rx_err_endpkt;      /* Number of Received packets with bad ending */
306
307        /* Diagnostics to help developers sizing their number buffers to avoid
308         * out-of-buffers or other phenomenons.
309         */
310        int send_cnt_min;       /* Minimum number of packets in TX SEND Q */
311        int send_cnt_max;       /* Maximum number of packets in TX SEND Q */
312        int tx_sched_cnt_min;   /* Minimum number of packets in TX SCHED Q */
313        int tx_sched_cnt_max;   /* Maximum number of packets in TX SCHED Q */
314        int sent_cnt_max;       /* Maximum number of packets in TX SENT Q */
315        int tx_work_cnt;        /* Times the work thread processed TX BDs */
316        int tx_work_enabled;    /* No. RX BDs enabled by work thread */
317
318        int ready_cnt_min;      /* Minimum number of packets in RX READY Q */
319        int ready_cnt_max;      /* Maximum number of packets in RX READY Q */
320        int rx_sched_cnt_min;   /* Minimum number of packets in RX SCHED Q */
321        int rx_sched_cnt_max;   /* Maximum number of packets in RX SCHED Q */
322        int recv_cnt_max;       /* Maximum number of packets in RX RECV Q */
323        int rx_work_cnt;        /* Times the work thread processed RX BDs */
324        int rx_work_enabled;    /* No. RX BDs enabled by work thread */
325};
326
327/* ISR message sending call back. Compatible with rtems_message_queue_send().
328 * The 'buf' parameter has a pointer to a WORK-TASK message defined by the
329 * WORK_* macros below. The message indicates what GRSPW device operations
330 * are pending, thus what caused the interrupt.
331 *
332 * \param data   defined by grspw_work_config.msgisr_arg, default a rtems_id.
333 * \param buf    Pointer to a 32-bit message word
334 * \param n      Always 4 (byte size of buf).
335 */
336typedef int (*grspw_msgqisr_t)(void *data, unsigned int *buf, unsigned int n);
337
338/* Work message definitions, the int sent to *buf
339 * Bits 31..24: reserved.
340 * Bits 23..16: GRSPW device number message is associated with.
341 * Bit  15:     reserved.
342 * Bit  14:     work-task shall delete message queue on exit.
343 * Bit  13:     work-task shall exit and delete itself.
344 * Bit  12:     link error - shut down all DMA operations (stop DMA channels).
345 * Bit  11..8:  Indicats DMA error on DMA channel 3..0.
346 * Bit  7..0:   Indicats RX and/or TX packets completed on channel 3..0.
347 */
348#define WORK_NONE         0
349#define WORK_SHUTDOWN     0x1000 /* Signal shut down */
350#define WORK_QUIT_TASK    0x2000 /* Work task shall exit (delete itself) */
351#define WORK_FREE_MSGQ    0x4000 /* Delete MsgQ (valid when WORK_QUIT_TASK) */
352#define WORK_DMA(chan, rxtx) (((rxtx) & 0x3) << ((chan) * 2))
353#define WORK_DMA_TX(chan) WORK_DMA(chan, 1)
354#define WORK_DMA_RX(chan) WORK_DMA(chan, 2)
355#define WORK_DMA_ER(chan) (0x1 << ((chan) + 8))
356#define WORK_DMA_MASK     0xfff /* max 4 channels all work */
357#define WORK_DMA_TX_MASK  0x055 /* max 4 channels TX work */
358#define WORK_DMA_RX_MASK  0x0aa /* max 4 channels RX work */
359#define WORK_DMA_ER_MASK  0xf00 /* max 4 channels Error work */
360#define WORK_DMA_CHAN_MASK(chan) (WORK_DMA_ER(chan) | WORK_DMA(chan, 0x3))
361#define WORK_CORE_BIT     16
362#define WORK_CORE_MASK    0x00ff0000
363#define WORK_CORE(device) ((device) << WORK_CORE_BIT)
364
365/* Message Q used to send messages to work task */
366struct grspw_work_config {
367        grspw_msgqisr_t msgisr;
368        void *msgisr_arg; /* example: rtems_id to Msg Q */
369};
370
371extern void grspw_initialize_user(
372        /* Callback every time a GRSPW device is found. Args: DeviceIndex */
373        void *(*devfound)(int),
374        /* Callback every time a GRSPW device is removed. Args:
375         * int   = DeviceIndex
376         * void* = Return Value from devfound()
377         */
378        void (*devremove)(int,void*)
379        );
380
381/* Creates a MsgQ (optional) and spawns a worker task associated with the
382 * message Q. The task can also be associated with a custom msgQ if *msgQ.
383 * is non-zero.
384 *
385 * \param prio     Task priority, set to -1 for default.
386 * \param stack    Task stack size, set to 0 for default.
387 * \param msgQ     pMsgQ=NULL: illegal,
388 *                 pMsqQ==0: create new MsgQ with task and place in *pMsgQ,
389 *                 *pmsqQ!=0: pointer to MsgQ used for task.
390 * \param msgMax   Maximum number of messages, set to 0 for default.
391 * \return         0 on failure, task id on success.
392 */
393extern rtems_id grspw_work_spawn(int prio, int stack, rtems_id *pMsgQ, int msgMax);
394
395/* Free task associated with message queue and optionally also the message
396 * queue itself. The message queue is deleted by the work task and is therefore
397 * delayed until it the work task resumes its execution.
398 */
399extern rtems_status_code grspw_work_free(rtems_id msgQ, int freeMsgQ);
400
401/* Configure a GRSPW device Work task and Message Q set up.
402 * This affects messages to:
403 *  - DMA AHB error interrupt handling (mandatory)
404 *  - Link status interrupt handling (optional)
405 *  - RX DMA, defaults to common msgQ (configured per DMA channel)
406 */
407extern void grspw_work_cfg(void *d, struct grspw_work_config *wc);
408
409/* Work-task function, called only from the work task. The function is provided
410 * as a way for the user to create its own work tasks.
411 * The argument determines which message queue the task shall read its
412 * work jobs from.
413 *
414 * The messages are always 32-bit words and follows the format defined by the
415 * WORK_* macros above.
416 */
417extern void grspw_work_func(rtems_id msgQ);
418
419enum grspw_worktask_ev {
420        WORKTASK_EV_NONE = 0,
421        WORKTASK_EV_QUIT = 1,
422        WORKTASK_EV_SHUTDOWN = 2,
423        WORKTASK_EV_DMA_STOP = 3,
424};
425
426/* Weak function to let user override. Function called every time one of the
427 * events above is handled by the work-task. The message 'msg' is the current
428 * message being processed by the work-task.
429 * The user can for example add custom code to invoke on a DMA error, link
430 * error or monitor when the work-task exits after a call to grspw_work_free().
431 */
432extern void grspw_work_event(enum grspw_worktask_ev ev, unsigned int msg);
433
434#ifdef RTEMS_SMP
435/* Set ISR interrupt affinity. The LEON IRQCtrl requires that the cpumask shall
436 * always have one bit set.
437 */
438extern int grspw_isr_affinity(void *d, const cpu_set_t *cpus);
439#endif
440
441extern int grspw_dev_count(void);
442extern void *grspw_open(int dev_no);
443extern int grspw_close(void *d);
444extern void grspw_hw_support(void *d, struct grspw_hw_sup *hw);
445extern void grspw_stats_read(void *d, struct grspw_core_stats *sts);
446extern void grspw_stats_clr(void *d);
447
448/* Set and Read current node address configuration. The dma_nacfg[N] field
449 * represents the configuration for DMA Channel N.
450 *
451 * Set cfg->promiscous to -1 in order to only read current configuration.
452 */
453extern void grspw_addr_ctrl(void *d, struct grspw_addr_config *cfg);
454
455/*** Link Control interface ***/
456/* Read Link State */
457extern spw_link_state_t grspw_link_state(void *d);
458/* options [in/out]: set to -1 to only read current config
459 *
460 * CLKDIV register contain:
461 *  bits 7..0  : Clock Div RUN (only run-state)
462 *  bits 15..8 : Clock Div During Startup (all link states except run-state)
463 */
464extern void grspw_link_ctrl(void *d, int *options, int *stscfg, int *clkdiv);
465/* Read the current value of the status register */
466extern unsigned int grspw_link_status(void *d);
467/* Clear bits in the status register */
468extern void grspw_link_status_clr(void *d, unsigned int clearmask);
469
470/*** Time Code Interface ***/
471/* Generate Tick-In (increment Time Counter, Send Time Code) */
472extern void grspw_tc_tx(void *d);
473/* Control Timcode settings of core */
474extern void grspw_tc_ctrl(void *d, int *options);
475/* Assign ISR Function to TimeCode RX IRQ */
476extern void grspw_tc_isr(void *d, void (*tcisr)(void *data, int tc), void *data);
477/* Read/Write TCTRL and TIMECNT. Write if not -1, always read current value
478 * TCTRL   = bits 7 and 6
479 * TIMECNT = bits 5 to 0
480 */
481extern void grspw_tc_time(void *d, int *time);
482
483/*** Interrupt-code Interface ***/
484struct spwpkt_ic_config {
485        unsigned int tomask;
486        unsigned int aamask;
487        unsigned int scaler;
488        unsigned int isr_reload;
489        unsigned int ack_reload;
490};
491/* Function Interrupt-Code ISR callback prototype. Called when respective
492 * interrupt handling option has been enabled by grspw_ic_ctrl(), the
493 * arguments rxirq, rxack and intto are read from the registers of the
494 * GRSPW core read by the GRSPW ISR, they are individually valid only when
495 * repective handling been turned on.
496 *
497 * data    - Custom data provided by user
498 * rxirq   - Interrupt-Code Recevie register of the GRSPW core read by ISR
499 *           (only defined if IQ bit enabled through grspw_ic_ctrl())
500 * rxack   - Interrupt-Ack-Code Recevie register of the GRSPW core read by ISR
501 *           (only defined if AQ bit enabled through grspw_ic_ctrl())
502 * intto   - Interrupt Tick-out Recevie register of the GRSPW core read by ISR
503 *           (only defined if TQ bit enabled through grspw_ic_ctrl())
504 */
505typedef void (*spwpkt_ic_isr_t)(void *data, unsigned int rxirq,
506                                unsigned int rxack, unsigned int intto);
507/* Control Interrupt-code settings of core
508 * Write if 'options' not pointing to -1, always read current value
509 */
510extern void grspw_ic_ctrl(void *d, unsigned int *options);
511/* Write (rw&1 == 1) configuration parameters to registers and/or,
512 * Read  (rw&2 == 1) configuration parameters from registers, in that sequence.
513 */
514extern void grspw_ic_config(void *d, int rw, struct spwpkt_ic_config *cfg);
515/* Read or Write Interrupt-code status registers.
516 * If pointer argument *ptr == 0 then only read, if *ptr != 0 then only write.
517 * If *ptr is NULL no operation.
518 */
519extern void grspw_ic_sts(void *d, unsigned int *rxirq, unsigned int *rxack,
520                        unsigned int *intto);
521/* Generate Tick-In for the given Interrupt-code
522 * Returns zero on success and non-zero on failure
523 *
524 * Interrupt code bits (ic):
525 * Bit 5 - ACK if 1
526 * Bits 4-0 Interrupt-code number
527 */
528extern int grspw_ic_tickin(void *d, int ic);
529/* Assign handler function to Interrupt-code timeout IRQ */
530extern void grspw_ic_isr(void *d, spwpkt_ic_isr_t handler, void *data);
531
532/*** RMAP Control Interface ***/
533/* Set (not -1) and/or read RMAP options. */
534extern int grspw_rmap_ctrl(void *d, int *options, int *dstkey);
535extern void grspw_rmap_support(void *d, char *rmap, char *rmap_crc);
536
537/*** SpW Port Control Interface ***/
538
539/* Select port, if
540 * -1=The current selected port is returned
541 * 0=Port 0
542 * 1=Port 1
543 * Other positive values=Both Port0 and Port1
544 */
545extern int grspw_port_ctrl(void *d, int *port);
546/* Returns Number ports available in hardware */
547extern int grspw_port_count(void *d);
548/* Returns the current active port */
549extern int grspw_port_active(void *d);
550
551/*** DMA Interface ***/
552extern void *grspw_dma_open(void *d, int chan_no);
553extern int grspw_dma_close(void *c);
554
555extern int grspw_dma_start(void *c);
556extern void grspw_dma_stop(void *c);
557
558/* Enable interrupt manually */
559extern unsigned int grspw_dma_enable_int(void *c, int rxtx, int force);
560
561/* Return Current DMA Control & Status Register */
562extern unsigned int grspw_dma_ctrlsts(void *c);
563
564/* Schedule List of packets for transmission at some point in
565 * future.
566 *
567 * 1. Move transmitted packets to SENT List (SCHED->SENT)
568 * 2. Add the requested packets to the SEND List (USER->SEND)
569 * 3. Schedule as many packets as possible for transmission (SEND->SCHED)
570 *
571 * Call this function with pkts=NULL to just do step 1 and 3. This may be
572 * required in Polling-mode.
573 *
574 * The above steps 1 and 3 may be skipped by setting 'opts':
575 *  bit0 = 1: Skip Step 1.
576 *  bit1 = 1: Skip Step 3.
577 * Skipping both step 1 and 3 may be usefull when IRQ is enabled, then
578 * the work queue will be totaly responsible for handling descriptors.
579 *
580 * The fastest solution in retreiving sent TX packets and sending new frames
581 * is to call:
582 *  A. grspw_dma_tx_reclaim(opts=0)
583 *  B. grspw_dma_tx_send(opts=1)
584 *
585 * NOTE: the TXPKT_FLAG_TX flag must not be set.
586 *
587 * Return Code
588 *  -1   Error
589 *  0    Successfully added pkts to send/sched list
590 *  1    DMA stopped. No operation.
591 */
592extern int grspw_dma_tx_send(void *c, int opts, struct grspw_list *pkts, int count);
593
594/* Reclaim TX packet buffers that has previously been scheduled for transmission
595 * with grspw_dma_tx_send().
596 *
597 * 1. Move transmitted packets to SENT List (SCHED->SENT)
598 * 2. Move all SENT List to pkts list (SENT->USER)
599 * 3. Schedule as many packets as possible for transmission (SEND->SCHED)
600 *
601 * The above steps 1 may be skipped by setting 'opts':
602 *  bit0 = 1: Skip Step 1.
603 *  bit1 = 1: Skip Step 3.
604 *
605 * The fastest solution in retreiving sent TX packets and sending new frames
606 * is to call:
607 *  A. grspw_dma_tx_reclaim(opts=2) (Skip step 3)
608 *  B. grspw_dma_tx_send(opts=1) (Skip step 1)
609 *
610 * Return Code
611 *  -1   Error
612 *  0    Successful. pkts list filled with all packets from sent list
613 *  1    Same as 0, but indicates that DMA stopped
614 */
615extern int grspw_dma_tx_reclaim(void *c, int opts, struct grspw_list *pkts, int *count);
616
617/* Get current number of Packets in respective TX Queue. */
618extern void grspw_dma_tx_count(void *c, int *send, int *sched, int *sent, int *hw);
619
620#define GRSPW_OP_AND 0
621#define GRSPW_OP_OR 1
622/* Block until send_cnt or fewer packets are Queued in "Send and Scheduled" Q,
623 * op (AND or OR), sent_cnt or more packet "have been sent" (Sent Q) condition
624 * is met.
625 * If a link error occurs and the Stop on Link error is defined, this function
626 * will also return to caller.
627 * The timeout argument is used to return after timeout ticks, regardless of
628 * the other conditions. If timeout is zero, the function will wait forever
629 * until the condition is satisfied.
630 *
631 * NOTE: if IRQ of TX descriptors are not enabled conditions are never
632 *       checked, this may hang infinitely unless a timeout has been specified
633 *
634 * Return Code
635 *  -1   Error
636 *  0    Returing to caller because specified conditions are now fullfilled
637 *  1    DMA stopped
638 *  2    Timeout, conditions are not met
639 *  3    Another task is already waiting. Service is Busy.
640 */
641extern int grspw_dma_tx_wait(void *c, int send_cnt, int op, int sent_cnt, int timeout);
642
643/* Get received RX packet buffers that has previously been scheduled for
644 * reception with grspw_dma_rx_prepare().
645 *
646 * 1. Move Scheduled packets to RECV List (SCHED->RECV)
647 * 2. Move all RECV packet to the callers list (RECV->USER)
648 * 3. Schedule as many free packet buffers as possible (READY->SCHED)
649 *
650 * The above steps 1 may be skipped by setting 'opts':
651 *  bit0 = 1: Skip Step 1.
652 *  bit1 = 1: Skip Step 3.
653 *
654 * The fastest solution in retreiving received RX packets and preparing new
655 * packet buffers for future receive, is to call:
656 *  A. grspw_dma_rx_recv(opts=2, &recvlist) (Skip step 3)
657 *  B. grspw_dma_rx_prepare(opts=1, &freelist) (Skip step 1)
658 *
659 * Return Code
660 *  -1   Error
661 *  0    Successfully filled pkts list with packets from recv list.
662 *  1    DMA stopped
663 */
664extern int grspw_dma_rx_recv(void *c, int opts, struct grspw_list *pkts, int *count);
665
666/* Add more RX packet buffers for future for reception. The received packets
667 * can later be read out with grspw_dma_rx_recv().
668 *
669 * 1. Move Received packets to RECV List (SCHED->RECV)
670 * 2. Add the "free/ready" packet buffers to the READY List (USER->READY)
671 * 3. Schedule as many packets as possible (READY->SCHED)
672 *
673 * The above steps 1 may be skipped by setting 'opts':
674 *  bit0 = 1: Skip Step 1.
675 *  bit1 = 1: Skip Step 3.
676 *
677 * The fastest solution in retreiving received RX packets and preparing new
678 * packet buffers for future receive, is to call:
679 *  A. grspw_dma_rx_recv(opts=2, &recvlist) (Skip step 3)
680 *  B. grspw_dma_rx_prepare(opts=1, &freelist) (Skip step 1)
681 *
682 * Return Code
683 *  -1   Error
684 *  0    Successfully added packet buffers from pkt list into the ready queue
685 *  1    DMA stopped
686 */
687extern int grspw_dma_rx_prepare(void *c, int opts, struct grspw_list *pkts, int count);
688
689/* Get current number of Packets in respective RX Queue. */
690extern void grspw_dma_rx_count(void *c, int *ready, int *sched, int *recv, int *hw);
691
692/* Block until recv_cnt or more packets are Queued in RECV Q, op (AND or OR),
693 * ready_cnt or fewer packet buffers are available in the "READY and Scheduled" Q,
694 * condition is met.
695 * If a link error occurs and the Stop on Link error is defined, this function
696 * will also return to caller, however with an error.
697 * The timeout argument is used to return after timeout ticks, regardless of
698 * the other conditions. If timeout is zero, the function will wait forever
699 * until the condition is satisfied.
700 *
701 * NOTE: if IRQ of RX descriptors are not enabled conditions are never
702 *       checked, this may hang infinitely unless a timeout has been specified
703 *
704 * Return Code
705 *  -1   Error
706 *  0    Returing to caller because specified conditions are now fullfilled
707 *  1    DMA stopped
708 *  2    Timeout, conditions are not met
709 *  3    Another task is already waiting. Service is Busy.
710 */
711extern int grspw_dma_rx_wait(void *c, int recv_cnt, int op, int ready_cnt, int timeout);
712
713extern int grspw_dma_config(void *c, struct grspw_dma_config *cfg);
714extern void grspw_dma_config_read(void *c, struct grspw_dma_config *cfg);
715
716extern void grspw_dma_stats_read(void *c, struct grspw_dma_stats *sts);
717extern void grspw_dma_stats_clr(void *c);
718
719/* Register GRSPW packet driver to Driver Manager */
720void grspw2_register_drv (void);
721
722/*** GRSPW SpaceWire Packet List Handling Routines ***/
723
724static inline void grspw_list_clr(struct grspw_list *list)
725{
726        list->head = NULL;
727        list->tail = NULL;
728}
729
730static inline int grspw_list_is_empty(struct grspw_list *list)
731{
732        return (list->head == NULL);
733}
734
735/* Return Number of entries in list */
736static inline int grspw_list_cnt(struct grspw_list *list)
737{
738        struct grspw_pkt *lastpkt = NULL, *pkt = list->head;
739        int cnt = 0;
740        while ( pkt ) {
741                cnt++;
742                lastpkt = pkt;
743                pkt = pkt->next;
744        }
745        if ( lastpkt && (list->tail != lastpkt) )
746                return -1;
747        return cnt;
748}
749
750static inline void
751grspw_list_append(struct grspw_list *list, struct grspw_pkt *pkt)
752{
753        pkt->next = NULL;
754        if ( list->tail == NULL ) {
755                list->head = pkt;
756        } else {
757                list->tail->next = pkt;
758        }
759        list->tail = pkt;
760}
761
762static inline void
763grspw_list_prepend(struct grspw_list *list, struct grspw_pkt *pkt)
764{
765        pkt->next = list->head;
766        if ( list->head == NULL ) {
767                list->tail = pkt;
768        }
769        list->head = pkt;
770}
771
772static inline void
773grspw_list_append_list(struct grspw_list *list, struct grspw_list *alist)
774{
775        if (grspw_list_is_empty(alist)) {
776                return;
777        }
778        alist->tail->next = NULL;
779        if ( list->tail == NULL ) {
780                list->head = alist->head;
781        } else {
782                list->tail->next = alist->head;
783        }
784        list->tail = alist->tail;
785}
786
787static inline void
788grspw_list_prepend_list(struct grspw_list *list, struct grspw_list *alist)
789{
790        if (grspw_list_is_empty(alist)) {
791                return;
792        }
793        if ( list->head == NULL ) {
794                list->tail = alist->tail;
795                alist->tail->next = NULL;
796        } else {
797                alist->tail->next = list->head;
798        }
799        list->head = alist->head;
800}
801
802/* Remove dlist (delete-list) from head of list */
803static inline void
804grspw_list_remove_head_list(struct grspw_list *list, struct grspw_list *dlist)
805{
806        if (grspw_list_is_empty(dlist)) {
807                return;
808        }
809        list->head = dlist->tail->next;
810        if ( list->head == NULL ) {
811                list->tail = NULL;
812        }
813        dlist->tail->next = NULL;
814}
815
816/* Take A number of entries from head of list 'list' and put the entires
817 * to rlist (result list).
818 */
819static inline int
820grspw_list_take_head_list(struct grspw_list *list, struct grspw_list *rlist, int max)
821{
822        int cnt;
823        struct grspw_pkt *pkt, *last;
824
825        pkt = list->head;
826
827        if ( (max < 1) || (pkt == NULL) ) {
828                grspw_list_clr(rlist);
829                return 0;
830        }
831
832        cnt = 0;
833        rlist->head = pkt;
834        last = pkt;
835        while ((cnt < max) && pkt) {
836                last = pkt;
837                pkt = pkt->next;
838                cnt++;
839        }
840        rlist->tail = last;
841        grspw_list_remove_head_list(list, rlist);
842        return cnt;
843}
844
845#endif
Note: See TracBrowser for help on using the repository browser.