source: rtems/c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c @ ab9b447

5
Last change on this file since ab9b447 was ab9b447, checked in by Daniel Hellstrom <daniel@…>, on Jan 22, 2017 at 2:01:55 PM

leon, grspw_pkt: added work-task configuration options

Following changes:

  • possible for user to create work-tasks and assign custom message queues.
  • possible for user to override default ISR message to implement custom handling of DMA error, DMA RX/TX and link error from ISR.
  • work-task now checks message to determine which work to perform rather than looking at registers only, this makes it possible for user to implement custom handling.
  • exported work-queue message definitions and separated them so that a user can assign custom DMA RX/TX handling of a specific DMA channel.
  • added a work-task event callback to let user add custom handling or monitoring of DMA Stop, DMA error, Link Error or work-task exits etc.
  • Property mode set to 100644
File size: 88.4 KB
Line 
1/*
2 * Cobham Gaisler GRSPW/GRSPW2 SpaceWire Kernel Library Interface for RTEMS.
3 *
4 * This driver can be used to implement a standard I/O system "char"-driver
5 * or used directly. NOTE SMP support has not been tested.
6 *
7 * COPYRIGHT (c) 2011
8 * Cobham Gaisler AB
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#include <rtems.h>
16#include <bsp.h>
17#include <rtems/libio.h>
18#include <stdlib.h>
19#include <stdio.h>
20#include <string.h>
21#include <assert.h>
22#include <ctype.h>
23#include <malloc.h>
24#include <rtems/bspIo.h>
25
26#include <drvmgr/drvmgr.h>
27#include <ambapp.h>
28#include <drvmgr/ambapp_bus.h>
29#include <bsp/grspw_pkt.h>
30
31/* This driver has been prepared for SMP operation however never tested
32 * on a SMP system - use on your own risk.
33 */
34#ifdef RTEMS_HAS_SMP
35
36#include <rtems/score/smplock.h> /* spin-lock */
37
38/* SPIN_LOCK() and SPIN_UNLOCK() NOT_IMPLEMENTED_BY_RTEMS. Use _IRQ version
39 * to implement.
40 */
41#define SPIN_DECLARE(name) SMP_lock_spinlock_simple_Control name
42#define SPIN_INIT(lock) _SMP_lock_spinlock_simple_Initialize(lock)
43#define SPIN_LOCK(lock, level) SPIN_LOCK_IRQ(lock, level)
44#define SPIN_LOCK_IRQ(lock, level) (level) = _SMP_lock_spinlock_simple_Obtain(lock)
45#define SPIN_UNLOCK(lock, level) SPIN_UNLOCK_IRQ(lock, level)
46#define SPIN_UNLOCK_IRQ(lock, level) _SMP_lock_spinlock_simple_Release(lock, level)
47#define IRQFLAGS_TYPE ISR_Level
48
49#else
50
51#define SPIN_DECLARE(name)
52#define SPIN_INIT(lock)
53#define SPIN_LOCK(lock, level)
54#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_disable(level)
55#define SPIN_UNLOCK(lock, level)
56#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_enable(level)
57#define IRQFLAGS_TYPE rtems_interrupt_level
58
59#endif
60
61/*#define STATIC*/
62#define STATIC static
63
64/*#define GRSPW_DBG(args...) printk(args)*/
65#define GRSPW_DBG(args...)
66
67struct grspw_dma_regs {
68        volatile unsigned int ctrl;     /* DMA Channel Control */
69        volatile unsigned int rxmax;    /* RX Max Packet Length */
70        volatile unsigned int txdesc;   /* TX Descriptor Base/Current */
71        volatile unsigned int rxdesc;   /* RX Descriptor Base/Current */
72        volatile unsigned int addr;     /* Address Register */
73        volatile unsigned int resv[3];
74};
75
76struct grspw_regs {
77        volatile unsigned int ctrl;
78        volatile unsigned int status;
79        volatile unsigned int nodeaddr;
80        volatile unsigned int clkdiv;
81        volatile unsigned int destkey;
82        volatile unsigned int time;
83        volatile unsigned int timer;    /* Used only in GRSPW1 */
84        volatile unsigned int resv1;
85
86        /* DMA Registers, ctrl.NCH determines number of ports,
87         * up to 4 channels are supported
88         */
89        struct grspw_dma_regs dma[4];
90
91        volatile unsigned int icctrl;
92        volatile unsigned int icrx;
93        volatile unsigned int icack;
94        volatile unsigned int ictimeout;
95        volatile unsigned int ictickomask;
96        volatile unsigned int icaamask;
97        volatile unsigned int icrlpresc;
98        volatile unsigned int icrlisr;
99        volatile unsigned int icrlintack;
100        volatile unsigned int resv2;
101        volatile unsigned int icisr;
102        volatile unsigned int resv3;
103};
104
105/* GRSPW - Control Register - 0x00 */
106#define GRSPW_CTRL_RA_BIT       31
107#define GRSPW_CTRL_RX_BIT       30
108#define GRSPW_CTRL_RC_BIT       29
109#define GRSPW_CTRL_NCH_BIT      27
110#define GRSPW_CTRL_PO_BIT       26
111#define GRSPW_CTRL_ID_BIT       24
112#define GRSPW_CTRL_LE_BIT       22
113#define GRSPW_CTRL_PS_BIT       21
114#define GRSPW_CTRL_NP_BIT       20
115#define GRSPW_CTRL_RD_BIT       17
116#define GRSPW_CTRL_RE_BIT       16
117#define GRSPW_CTRL_TF_BIT       12
118#define GRSPW_CTRL_TR_BIT       11
119#define GRSPW_CTRL_TT_BIT       10
120#define GRSPW_CTRL_LI_BIT       9
121#define GRSPW_CTRL_TQ_BIT       8
122#define GRSPW_CTRL_RS_BIT       6
123#define GRSPW_CTRL_PM_BIT       5
124#define GRSPW_CTRL_TI_BIT       4
125#define GRSPW_CTRL_IE_BIT       3
126#define GRSPW_CTRL_AS_BIT       2
127#define GRSPW_CTRL_LS_BIT       1
128#define GRSPW_CTRL_LD_BIT       0
129
130#define GRSPW_CTRL_RA   (1<<GRSPW_CTRL_RA_BIT)
131#define GRSPW_CTRL_RX   (1<<GRSPW_CTRL_RX_BIT)
132#define GRSPW_CTRL_RC   (1<<GRSPW_CTRL_RC_BIT)
133#define GRSPW_CTRL_NCH  (0x3<<GRSPW_CTRL_NCH_BIT)
134#define GRSPW_CTRL_PO   (1<<GRSPW_CTRL_PO_BIT)
135#define GRSPW_CTRL_ID   (1<<GRSPW_CTRL_ID_BIT)
136#define GRSPW_CTRL_LE   (1<<GRSPW_CTRL_LE_BIT)
137#define GRSPW_CTRL_PS   (1<<GRSPW_CTRL_PS_BIT)
138#define GRSPW_CTRL_NP   (1<<GRSPW_CTRL_NP_BIT)
139#define GRSPW_CTRL_RD   (1<<GRSPW_CTRL_RD_BIT)
140#define GRSPW_CTRL_RE   (1<<GRSPW_CTRL_RE_BIT)
141#define GRSPW_CTRL_TF   (1<<GRSPW_CTRL_TF_BIT)
142#define GRSPW_CTRL_TR   (1<<GRSPW_CTRL_TR_BIT)
143#define GRSPW_CTRL_TT   (1<<GRSPW_CTRL_TT_BIT)
144#define GRSPW_CTRL_LI   (1<<GRSPW_CTRL_LI_BIT)
145#define GRSPW_CTRL_TQ   (1<<GRSPW_CTRL_TQ_BIT)
146#define GRSPW_CTRL_RS   (1<<GRSPW_CTRL_RS_BIT)
147#define GRSPW_CTRL_PM   (1<<GRSPW_CTRL_PM_BIT)
148#define GRSPW_CTRL_TI   (1<<GRSPW_CTRL_TI_BIT)
149#define GRSPW_CTRL_IE   (1<<GRSPW_CTRL_IE_BIT)
150#define GRSPW_CTRL_AS   (1<<GRSPW_CTRL_AS_BIT)
151#define GRSPW_CTRL_LS   (1<<GRSPW_CTRL_LS_BIT)
152#define GRSPW_CTRL_LD   (1<<GRSPW_CTRL_LD_BIT)
153
154#define GRSPW_CTRL_IRQSRC_MASK \
155        (GRSPW_CTRL_LI | GRSPW_CTRL_TQ)
156#define GRSPW_ICCTRL_IRQSRC_MASK \
157        (GRSPW_ICCTRL_TQ | GRSPW_ICCTRL_AQ | GRSPW_ICCTRL_IQ)
158
159
160/* GRSPW - Status Register - 0x04 */
161#define GRSPW_STS_LS_BIT        21
162#define GRSPW_STS_AP_BIT        9
163#define GRSPW_STS_EE_BIT        8
164#define GRSPW_STS_IA_BIT        7
165#define GRSPW_STS_WE_BIT        6       /* GRSPW1 */
166#define GRSPW_STS_PE_BIT        4
167#define GRSPW_STS_DE_BIT        3
168#define GRSPW_STS_ER_BIT        2
169#define GRSPW_STS_CE_BIT        1
170#define GRSPW_STS_TO_BIT        0
171
172#define GRSPW_STS_LS    (0x7<<GRSPW_STS_LS_BIT)
173#define GRSPW_STS_AP    (1<<GRSPW_STS_AP_BIT)
174#define GRSPW_STS_EE    (1<<GRSPW_STS_EE_BIT)
175#define GRSPW_STS_IA    (1<<GRSPW_STS_IA_BIT)
176#define GRSPW_STS_WE    (1<<GRSPW_STS_WE_BIT)   /* GRSPW1 */
177#define GRSPW_STS_PE    (1<<GRSPW_STS_PE_BIT)
178#define GRSPW_STS_DE    (1<<GRSPW_STS_DE_BIT)
179#define GRSPW_STS_ER    (1<<GRSPW_STS_ER_BIT)
180#define GRSPW_STS_CE    (1<<GRSPW_STS_CE_BIT)
181#define GRSPW_STS_TO    (1<<GRSPW_STS_TO_BIT)
182
183/* GRSPW - Default Address Register - 0x08 */
184#define GRSPW_DEF_ADDR_BIT      0
185#define GRSPW_DEF_MASK_BIT      8
186#define GRSPW_DEF_ADDR  (0xff<<GRSPW_DEF_ADDR_BIT)
187#define GRSPW_DEF_MASK  (0xff<<GRSPW_DEF_MASK_BIT)
188
189/* GRSPW - Clock Divisor Register - 0x0C */
190#define GRSPW_CLKDIV_START_BIT  8
191#define GRSPW_CLKDIV_RUN_BIT    0
192#define GRSPW_CLKDIV_START      (0xff<<GRSPW_CLKDIV_START_BIT)
193#define GRSPW_CLKDIV_RUN        (0xff<<GRSPW_CLKDIV_RUN_BIT)
194#define GRSPW_CLKDIV_MASK       (GRSPW_CLKDIV_START|GRSPW_CLKDIV_RUN)
195
196/* GRSPW - Destination key Register - 0x10 */
197#define GRSPW_DK_DESTKEY_BIT    0
198#define GRSPW_DK_DESTKEY        (0xff<<GRSPW_DK_DESTKEY_BIT)
199
200/* GRSPW - Time Register - 0x14 */
201#define GRSPW_TIME_CTRL_BIT     6
202#define GRSPW_TIME_CNT_BIT      0
203#define GRSPW_TIME_CTRL         (0x3<<GRSPW_TIME_CTRL_BIT)
204#define GRSPW_TIME_TCNT         (0x3f<<GRSPW_TIME_CNT_BIT)
205
206/* GRSPW - DMA Control Register - 0x20*N */
207#define GRSPW_DMACTRL_LE_BIT    16
208#define GRSPW_DMACTRL_SP_BIT    15
209#define GRSPW_DMACTRL_SA_BIT    14
210#define GRSPW_DMACTRL_EN_BIT    13
211#define GRSPW_DMACTRL_NS_BIT    12
212#define GRSPW_DMACTRL_RD_BIT    11
213#define GRSPW_DMACTRL_RX_BIT    10
214#define GRSPW_DMACTRL_AT_BIT    9
215#define GRSPW_DMACTRL_RA_BIT    8
216#define GRSPW_DMACTRL_TA_BIT    7
217#define GRSPW_DMACTRL_PR_BIT    6
218#define GRSPW_DMACTRL_PS_BIT    5
219#define GRSPW_DMACTRL_AI_BIT    4
220#define GRSPW_DMACTRL_RI_BIT    3
221#define GRSPW_DMACTRL_TI_BIT    2
222#define GRSPW_DMACTRL_RE_BIT    1
223#define GRSPW_DMACTRL_TE_BIT    0
224
225#define GRSPW_DMACTRL_LE        (1<<GRSPW_DMACTRL_LE_BIT)
226#define GRSPW_DMACTRL_SP        (1<<GRSPW_DMACTRL_SP_BIT)
227#define GRSPW_DMACTRL_SA        (1<<GRSPW_DMACTRL_SA_BIT)
228#define GRSPW_DMACTRL_EN        (1<<GRSPW_DMACTRL_EN_BIT)
229#define GRSPW_DMACTRL_NS        (1<<GRSPW_DMACTRL_NS_BIT)
230#define GRSPW_DMACTRL_RD        (1<<GRSPW_DMACTRL_RD_BIT)
231#define GRSPW_DMACTRL_RX        (1<<GRSPW_DMACTRL_RX_BIT)
232#define GRSPW_DMACTRL_AT        (1<<GRSPW_DMACTRL_AT_BIT)
233#define GRSPW_DMACTRL_RA        (1<<GRSPW_DMACTRL_RA_BIT)
234#define GRSPW_DMACTRL_TA        (1<<GRSPW_DMACTRL_TA_BIT)
235#define GRSPW_DMACTRL_PR        (1<<GRSPW_DMACTRL_PR_BIT)
236#define GRSPW_DMACTRL_PS        (1<<GRSPW_DMACTRL_PS_BIT)
237#define GRSPW_DMACTRL_AI        (1<<GRSPW_DMACTRL_AI_BIT)
238#define GRSPW_DMACTRL_RI        (1<<GRSPW_DMACTRL_RI_BIT)
239#define GRSPW_DMACTRL_TI        (1<<GRSPW_DMACTRL_TI_BIT)
240#define GRSPW_DMACTRL_RE        (1<<GRSPW_DMACTRL_RE_BIT)
241#define GRSPW_DMACTRL_TE        (1<<GRSPW_DMACTRL_TE_BIT)
242
243/* GRSPW - DMA Channel Max Packet Length Register - (0x20*N + 0x04) */
244#define GRSPW_DMARXLEN_MAX_BIT  0
245#define GRSPW_DMARXLEN_MAX      (0xffffff<<GRSPW_DMARXLEN_MAX_BIT)
246
247/* GRSPW - DMA Channel Address Register - (0x20*N + 0x10) */
248#define GRSPW_DMAADR_ADDR_BIT   0
249#define GRSPW_DMAADR_MASK_BIT   8
250#define GRSPW_DMAADR_ADDR       (0xff<<GRSPW_DMAADR_ADDR_BIT)
251#define GRSPW_DMAADR_MASK       (0xff<<GRSPW_DMAADR_MASK_BIT)
252
253/* GRSPW - Interrupt code receive register - 0xa4 */
254#define GRSPW_ICCTRL_INUM_BIT   27
255#define GRSPW_ICCTRL_IA_BIT     24
256#define GRSPW_ICCTRL_LE_BIT     23
257#define GRSPW_ICCTRL_PR_BIT     22
258#define GRSPW_ICCTRL_DQ_BIT     21 /* never used */
259#define GRSPW_ICCTRL_TQ_BIT     20
260#define GRSPW_ICCTRL_AQ_BIT     19
261#define GRSPW_ICCTRL_IQ_BIT     18
262#define GRSPW_ICCTRL_IR_BIT     17
263#define GRSPW_ICCTRL_IT_BIT     16
264#define GRSPW_ICCTRL_NUMI_BIT   13
265#define GRSPW_ICCTRL_BIRQ_BIT   8
266#define GRSPW_ICCTRL_ID_BIT     7
267#define GRSPW_ICCTRL_II_BIT     6
268#define GRSPW_ICCTRL_TXIRQ_BIT  0
269#define GRSPW_ICCTRL_INUM       (0x3f << GRSPW_ICCTRL_INUM_BIT)
270#define GRSPW_ICCTRL_IA         (1 << GRSPW_ICCTRL_IA_BIT)
271#define GRSPW_ICCTRL_LE         (1 << GRSPW_ICCTRL_LE_BIT)
272#define GRSPW_ICCTRL_PR         (1 << GRSPW_ICCTRL_PR_BIT)
273#define GRSPW_ICCTRL_DQ         (1 << GRSPW_ICCTRL_DQ_BIT)
274#define GRSPW_ICCTRL_TQ         (1 << GRSPW_ICCTRL_TQ_BIT)
275#define GRSPW_ICCTRL_AQ         (1 << GRSPW_ICCTRL_AQ_BIT)
276#define GRSPW_ICCTRL_IQ         (1 << GRSPW_ICCTRL_IQ_BIT)
277#define GRSPW_ICCTRL_IR         (1 << GRSPW_ICCTRL_IR_BIT)
278#define GRSPW_ICCTRL_IT         (1 << GRSPW_ICCTRL_IT_BIT)
279#define GRSPW_ICCTRL_NUMI       (0x7 << GRSPW_ICCTRL_NUMI_BIT)
280#define GRSPW_ICCTRL_BIRQ       (0x1f << GRSPW_ICCTRL_BIRQ_BIT)
281#define GRSPW_ICCTRL_ID         (1 << GRSPW_ICCTRL_ID_BIT)
282#define GRSPW_ICCTRL_II         (1 << GRSPW_ICCTRL_II_BIT)
283#define GRSPW_ICCTRL_TXIRQ      (0x3f << GRSPW_ICCTRL_TXIRQ_BIT)
284
285/* RX Buffer Descriptor */
286struct grspw_rxbd {
287   volatile unsigned int ctrl;
288   volatile unsigned int addr;
289};
290
291/* TX Buffer Descriptor */
292struct grspw_txbd {
293   volatile unsigned int ctrl;
294   volatile unsigned int haddr;
295   volatile unsigned int dlen;
296   volatile unsigned int daddr;
297};
298
299/* GRSPW - DMA RXBD Ctrl */
300#define GRSPW_RXBD_LEN_BIT 0
301#define GRSPW_RXBD_LEN  (0x1ffffff<<GRSPW_RXBD_LEN_BIT)
302#define GRSPW_RXBD_EN   (1<<25)
303#define GRSPW_RXBD_WR   (1<<26)
304#define GRSPW_RXBD_IE   (1<<27)
305#define GRSPW_RXBD_EP   (1<<28)
306#define GRSPW_RXBD_HC   (1<<29)
307#define GRSPW_RXBD_DC   (1<<30)
308#define GRSPW_RXBD_TR   (1<<31)
309
310#define GRSPW_TXBD_HLEN (0xff<<0)
311#define GRSPW_TXBD_NCL  (0xf<<8)
312#define GRSPW_TXBD_EN   (1<<12)
313#define GRSPW_TXBD_WR   (1<<13)
314#define GRSPW_TXBD_IE   (1<<14)
315#define GRSPW_TXBD_LE   (1<<15)
316#define GRSPW_TXBD_HC   (1<<16)
317#define GRSPW_TXBD_DC   (1<<17)
318
319#define GRSPW_DMAADR_MASK_BIT   8
320#define GRSPW_DMAADR_ADDR       (0xff<<GRSPW_DMAADR_ADDR_BIT)
321#define GRSPW_DMAADR_MASK       (0xff<<GRSPW_DMAADR_MASK_BIT)
322
323
324/* GRSPW Error Condition */
325#define GRSPW_STAT_ERROR        (GRSPW_STS_EE | GRSPW_STS_IA | GRSPW_STS_WE | GRSPW_STS_PE | GRSPW_STS_DE | GRSPW_STS_ER | GRSPW_STS_CE)
326#define GRSPW_DMA_STATUS_ERROR  (GRSPW_DMACTRL_RA | GRSPW_DMACTRL_TA)
327/* GRSPW Link configuration options */
328#define GRSPW_LINK_CFG          (GRSPW_CTRL_LI | GRSPW_CTRL_LD | GRSPW_CTRL_LS | GRSPW_CTRL_AS)
329#define GRSPW_LINKSTATE(status) ((status & GRSPW_CTRL_LS) >> GRSPW_CTRL_LS_BIT)
330
331/* Software Defaults */
332#define DEFAULT_RXMAX 1024      /* 1 KBytes Max RX Packet Size */
333
334/* GRSPW Constants */
335#define GRSPW_TXBD_NR 64        /* Maximum number of TX Descriptors */
336#define GRSPW_RXBD_NR 128       /* Maximum number of RX Descriptors */
337#define GRSPW_TXBD_SIZE 16      /* Size in bytes of one TX descriptor */
338#define GRSPW_RXBD_SIZE 8       /* Size in bytes of one RX descriptor */
339#define BDTAB_SIZE 0x400        /* BD Table Size (RX or TX) */
340#define BDTAB_ALIGN 0x400       /* BD Table Alignment Requirement */
341
342/* Memory and HW Registers Access routines. All 32-bit access routines */
343#define BD_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (unsigned int)(val))
344/*#define BD_READ(addr) (*(volatile unsigned int *)(addr))*/
345#define BD_READ(addr) leon_r32_no_cache((unsigned long)(addr))
346#define REG_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (unsigned int)(val))
347#define REG_READ(addr) (*(volatile unsigned int *)(addr))
348
349struct grspw_ring {
350        struct grspw_ring *next;        /* Next Descriptor */
351        union {
352                struct grspw_txbd *tx;  /* Descriptor Address */
353                struct grspw_rxbd *rx;  /* Descriptor Address */
354        } bd;
355        struct grspw_pkt *pkt;          /* Packet description associated.NULL if none*/ 
356};
357
358/* An entry in the TX descriptor Ring */
359struct grspw_txring {
360        struct grspw_txring *next;      /* Next Descriptor */
361        struct grspw_txbd *bd;          /* Descriptor Address */
362        struct grspw_pkt *pkt;          /* Packet description associated.NULL if none*/
363};
364
365/* An entry in the RX descriptor Ring */
366struct grspw_rxring {
367        struct grspw_rxring *next;      /* Next Descriptor */
368        struct grspw_rxbd *bd;          /* Descriptor Address */
369        struct grspw_pkt *pkt;          /* Packet description associated.NULL if none*/
370};
371
372
373struct grspw_dma_priv {
374        struct grspw_priv *core;        /* GRSPW Core */
375        struct grspw_dma_regs *regs;    /* DMA Channel Registers */
376        int index;                      /* DMA Channel Index @ GRSPW core */
377        int open;                       /* DMA Channel opened by user */
378        int started;                    /* DMA Channel activity (start|stop) */
379        rtems_id sem_rxdma;             /* DMA Channel RX Semaphore */
380        rtems_id sem_txdma;             /* DMA Channel TX Semaphore */
381        struct grspw_dma_stats stats;   /* DMA Channel Statistics */
382        struct grspw_dma_config cfg;    /* DMA Channel Configuration */
383
384        /*** RX ***/
385
386        /* RX Descriptor Ring */
387        struct grspw_rxbd *rx_bds;              /* Descriptor Address */
388        struct grspw_rxbd *rx_bds_hwa;          /* Descriptor HW Address */
389        struct grspw_rxring *rx_ring_base;
390        struct grspw_rxring *rx_ring_head;      /* Next descriptor to enable */
391        struct grspw_rxring *rx_ring_tail;      /* Oldest enabled Descriptor */
392        int rx_irq_en_cnt_curr;
393        struct {
394                int waiting;
395                int ready_cnt;
396                int op;
397                int recv_cnt;
398                rtems_id sem_wait;              /* RX Semaphore used to implement RX blocking */
399        } rx_wait;
400
401        /* Queue of Packets READY to be scheduled */
402        struct grspw_list ready;
403        int ready_cnt;
404
405        /* Scheduled RX Packets Queue */
406        struct grspw_list rx_sched;
407        int rx_sched_cnt;
408
409        /* Queue of Packets that has been RECIEVED */
410        struct grspw_list recv;
411        int recv_cnt;
412
413
414        /*** TX ***/
415
416        /* TX Descriptor Ring */
417        struct grspw_txbd *tx_bds;              /* Descriptor Address */
418        struct grspw_txbd *tx_bds_hwa;          /* Descriptor HW Address */
419        struct grspw_txring *tx_ring_base;
420        struct grspw_txring *tx_ring_head;
421        struct grspw_txring *tx_ring_tail;
422        int tx_irq_en_cnt_curr;
423        struct {
424                int waiting;
425                int send_cnt;
426                int op;
427                int sent_cnt;
428                rtems_id sem_wait;              /* TX Semaphore used to implement TX blocking */
429        } tx_wait;
430
431        /* Queue of Packets ready to be scheduled for transmission */
432        struct grspw_list send;
433        int send_cnt;
434
435        /* Scheduled TX Packets Queue */
436        struct grspw_list tx_sched;
437        int tx_sched_cnt;
438
439        /* Queue of Packets that has been SENT */
440        struct grspw_list sent;
441        int sent_cnt;
442};
443
444struct grspw_priv {
445        char devname[8];                /* Device name "grspw%d" */
446        struct drvmgr_dev *dev;         /* Device */
447        struct grspw_regs *regs;        /* Virtual Address of APB Registers */
448        int irq;                        /* AMBA IRQ number of core */
449        int index;                      /* Index in order it was probed */
450        int core_index;                 /* Core Bus Index */
451        int open;                       /* If Device is alrady opened (=1) or not (=0) */
452        void *data;                     /* User private Data for this device instance, set by grspw_initialize_user */
453
454        /* Features supported by Hardware */
455        struct grspw_hw_sup hwsup;
456
457        /* Pointer to an array of Maximally 4 DMA Channels */
458        struct grspw_dma_priv *dma;
459
460        /* Spin-lock ISR protection */
461        SPIN_DECLARE(devlock);
462
463        /* Descriptor Memory Area for TX & RX and all DMA channels */
464        unsigned int bd_mem;
465        unsigned int bd_mem_alloced;
466
467        /*** Time Code Handling ***/
468        void (*tcisr)(void *data, int timecode);
469        void *tcisr_arg;
470
471        /*** Interrupt-code Handling ***/
472        spwpkt_ic_isr_t icisr;
473        void *icisr_arg;
474
475        /* Bit mask representing events which shall cause link disable. */
476        unsigned int dis_link_on_err;
477
478        /* Bit mask for link status bits to clear by ISR */
479        unsigned int stscfg;
480
481        /*** Message Queue Handling ***/
482        struct grspw_work_config wc;
483
484        /* "Core Global" Statistics gathered, not dependent on DMA channel */
485        struct grspw_core_stats stats;
486};
487
488int grspw_initialized = 0;
489int grspw_count = 0;
490rtems_id grspw_sem;
491static struct grspw_priv *priv_tab[GRSPW_MAX];
492
493/* callback to upper layer when devices are discovered/removed */
494void *(*grspw_dev_add)(int) = NULL;
495void (*grspw_dev_del)(int,void*) = NULL;
496
497/* Defaults to do nothing - user can override this function.
498 * Called from work-task.
499 */
500void __attribute__((weak)) grspw_work_event(
501        enum grspw_worktask_ev ev,
502        unsigned int msg)
503{
504
505}
506
507/* USER OVERRIDABLE - The work task priority. Set to -1 to disable creating
508 * the work-task and work-queue to save space.
509 */
510int grspw_work_task_priority __attribute__((weak)) = 100;
511rtems_id grspw_work_task;
512static struct grspw_work_config grspw_wc_def;
513
514STATIC void grspw_hw_stop(struct grspw_priv *priv);
515STATIC void grspw_hw_dma_stop(struct grspw_dma_priv *dma);
516STATIC void grspw_dma_reset(struct grspw_dma_priv *dma);
517STATIC void grspw_dma_stop_locked(struct grspw_dma_priv *dma);
518STATIC void grspw_isr(void *data);
519
520void *grspw_open(int dev_no)
521{
522        struct grspw_priv *priv;
523        unsigned int bdtabsize, hwa;
524        int i;
525        union drvmgr_key_value *value;
526
527        if (grspw_initialized != 1 || (dev_no >= grspw_count))
528                return NULL;
529
530        priv = priv_tab[dev_no];
531
532        /* Take GRSPW lock - Wait until we get semaphore */
533        if (rtems_semaphore_obtain(grspw_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
534            != RTEMS_SUCCESSFUL)
535                return NULL;
536
537        if (priv->open) {
538                priv = NULL;
539                goto out;
540        }
541
542        /* Initialize Spin-lock for GRSPW Device. This is to protect
543         * CTRL and DMACTRL registers from ISR.
544         */
545        SPIN_INIT(&priv->devlock);
546
547        priv->tcisr = NULL;
548        priv->tcisr_arg = NULL;
549        priv->icisr = NULL;
550        priv->icisr_arg = NULL;
551        priv->stscfg = LINKSTS_MASK;
552
553        /* Default to common work queue and message queue, if not created
554         * during initialization then its disabled.
555         */
556        grspw_work_cfg(priv, &grspw_wc_def);
557
558        grspw_stats_clr(priv);
559
560        /* Allocate TX & RX Descriptor memory area for all DMA
561         * channels. Max-size descriptor area is allocated (or user assigned):
562         *  - 128 RX descriptors per DMA Channel
563         *  - 64 TX descriptors per DMA Channel
564         * Specified address must be in CPU RAM.
565         */
566        bdtabsize = 2 * BDTAB_SIZE * priv->hwsup.ndma_chans;
567        value = drvmgr_dev_key_get(priv->dev, "bdDmaArea", DRVMGR_KT_INT);
568        if (value) {
569                priv->bd_mem = value->i;
570                priv->bd_mem_alloced = 0;
571                if (priv->bd_mem & (BDTAB_ALIGN-1)) {
572                        GRSPW_DBG("GRSPW[%d]: user-def DMA-area not aligned",
573                                  priv->index);
574                        priv = NULL;
575                        goto out;
576                }
577        } else {
578                priv->bd_mem_alloced = (unsigned int)malloc(bdtabsize + BDTAB_ALIGN - 1);
579                if (priv->bd_mem_alloced == 0) {
580                        priv = NULL;
581                        goto out;
582                }
583                /* Align memory */
584                priv->bd_mem = (priv->bd_mem_alloced + (BDTAB_ALIGN - 1)) &
585                               ~(BDTAB_ALIGN-1);
586        }
587
588        /* Translate into DMA address that HW can use to access DMA
589         * descriptors
590         */
591        drvmgr_translate_check(
592                priv->dev,
593                CPUMEM_TO_DMA,
594                (void *)priv->bd_mem,
595                (void **)&hwa,
596                bdtabsize);
597
598        GRSPW_DBG("GRSPW%d DMA descriptor table setup: (alloced:%p, bd_mem:%p, size: %d)\n",
599                priv->index, priv->bd_mem_alloced, priv->bd_mem, bdtabsize + BDTAB_ALIGN - 1);
600        for (i=0; i<priv->hwsup.ndma_chans; i++) {
601                /* Do DMA Channel Init, other variables etc. are inited
602                 * when respective DMA channel is opened.
603                 *
604                 * index & core are initialized by probe function.
605                 */
606                priv->dma[i].open = 0;
607                priv->dma[i].rx_bds = (struct grspw_rxbd *)
608                        (priv->bd_mem + i*BDTAB_SIZE*2);
609                priv->dma[i].rx_bds_hwa = (struct grspw_rxbd *)
610                        (hwa + BDTAB_SIZE*(2*i));
611                priv->dma[i].tx_bds = (struct grspw_txbd *)
612                        (priv->bd_mem + BDTAB_SIZE*(2*i+1));
613                priv->dma[i].tx_bds_hwa = (struct grspw_txbd *)
614                        (hwa + BDTAB_SIZE*(2*i+1));
615                GRSPW_DBG("  DMA[%i]: RX %p - %p (%p - %p)   TX %p - %p (%p - %p)\n",
616                        i,
617                        priv->dma[i].rx_bds, (void *)priv->dma[i].rx_bds + BDTAB_SIZE - 1,
618                        priv->dma[i].rx_bds_hwa, (void *)priv->dma[i].rx_bds_hwa + BDTAB_SIZE - 1,
619                        priv->dma[i].tx_bds, (void *)priv->dma[i].tx_bds + BDTAB_SIZE - 1,
620                        priv->dma[i].tx_bds_hwa, (void *)priv->dma[i].tx_bds_hwa + BDTAB_SIZE - 1);
621        }
622
623        /* Basic initialization of hardware, clear some registers but
624         * keep Link/RMAP/Node-Address registers intact.
625         */
626        grspw_hw_stop(priv);
627
628        /* Register Interrupt handler and enable IRQ at IRQ ctrl */
629        drvmgr_interrupt_register(priv->dev, 0, priv->devname, grspw_isr, priv);
630
631        /* Take the device */
632        priv->open = 1;
633out:
634        rtems_semaphore_release(grspw_sem);
635        return priv;
636}
637
638int grspw_close(void *d)
639{
640        struct grspw_priv *priv = d;
641        int i;
642
643        /* Take GRSPW lock - Wait until we get semaphore */
644        if (rtems_semaphore_obtain(grspw_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
645            != RTEMS_SUCCESSFUL)
646                return -1;
647
648        /* Check that user has stopped and closed all DMA channels
649         * appropriately. At this point the Hardware shall not be doing DMA
650         * or generating Interrupts. We want HW in a "startup-state".
651         */
652        for (i=0; i<priv->hwsup.ndma_chans; i++) {
653                if (priv->dma[i].open) {
654                        rtems_semaphore_release(grspw_sem);
655                        return 1;
656                }
657        }
658        grspw_hw_stop(priv);
659
660        /* Mark not open */
661        priv->open = 0;
662        rtems_semaphore_release(grspw_sem);
663        return 0;
664}
665
666void grspw_hw_support(void *d, struct grspw_hw_sup *hw)
667{
668        struct grspw_priv *priv = d;
669
670        *hw = priv->hwsup;
671}
672
673void grspw_addr_ctrl(void *d, struct grspw_addr_config *cfg)
674{
675        struct grspw_priv *priv = d;
676        struct grspw_regs *regs = priv->regs;
677        unsigned int ctrl, nodeaddr;
678        IRQFLAGS_TYPE irqflags;
679        int i;
680
681        if (!priv || !cfg)
682                return;
683
684        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
685
686        if (cfg->promiscuous != -1) {
687                /* Set Configuration */
688                ctrl = REG_READ(&regs->ctrl);
689                if (cfg->promiscuous)
690                        ctrl |= GRSPW_CTRL_PM;
691                else
692                        ctrl &= ~GRSPW_CTRL_PM;
693                REG_WRITE(&regs->ctrl, ctrl);
694                REG_WRITE(&regs->nodeaddr, (cfg->def_mask<<8) | cfg->def_addr);
695
696                for (i=0; i<priv->hwsup.ndma_chans; i++) {
697                        ctrl = REG_READ(&regs->dma[i].ctrl);
698                        ctrl &= ~(GRSPW_DMACTRL_PS|GRSPW_DMACTRL_PR|GRSPW_DMA_STATUS_ERROR);
699                        if (cfg->dma_nacfg[i].node_en) {
700                                ctrl |= GRSPW_DMACTRL_EN;
701                                REG_WRITE(&regs->dma[i].addr,
702                                          (cfg->dma_nacfg[i].node_addr & 0xff) |
703                                          ((cfg->dma_nacfg[i].node_mask & 0xff)<<8));
704                        } else {
705                                ctrl &= ~GRSPW_DMACTRL_EN;
706                        }
707                        REG_WRITE(&regs->dma[i].ctrl, ctrl);
708                }
709        }
710
711        /* Read Current Configuration */
712        cfg->promiscuous = REG_READ(&regs->ctrl) & GRSPW_CTRL_PM;
713        nodeaddr = REG_READ(&regs->nodeaddr);
714        cfg->def_addr = (nodeaddr & GRSPW_DEF_ADDR) >> GRSPW_DEF_ADDR_BIT;
715        cfg->def_mask = (nodeaddr & GRSPW_DEF_MASK) >> GRSPW_DEF_MASK_BIT;
716        for (i=0; i<priv->hwsup.ndma_chans; i++) {
717                cfg->dma_nacfg[i].node_en = REG_READ(&regs->dma[i].ctrl) &
718                                                GRSPW_DMACTRL_EN;
719                ctrl = REG_READ(&regs->dma[i].addr);
720                cfg->dma_nacfg[i].node_addr = (ctrl & GRSPW_DMAADR_ADDR) >>
721                                                GRSPW_DMAADR_ADDR_BIT;
722                cfg->dma_nacfg[i].node_mask = (ctrl & GRSPW_DMAADR_MASK) >>
723                                                GRSPW_DMAADR_MASK_BIT;
724        }
725        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
726        for (; i<4; i++) {
727                cfg->dma_nacfg[i].node_en = 0;
728                cfg->dma_nacfg[i].node_addr = 0;
729                cfg->dma_nacfg[i].node_mask = 0;
730        }
731}
732
733/* Return Current Status Register */
734unsigned int grspw_link_status(void *d)
735{
736        struct grspw_priv *priv = d;
737
738        return REG_READ(&priv->regs->status);
739}
740
741/* Clear Status Register bits */
742void grspw_link_status_clr(void *d, unsigned int mask)
743{
744        struct grspw_priv *priv = d;
745
746        REG_WRITE(&priv->regs->status, mask);
747}
748
749/* Return Current Link State */
750spw_link_state_t grspw_link_state(void *d)
751{
752        struct grspw_priv *priv = d;
753        unsigned int status = REG_READ(&priv->regs->status);
754
755        return (status & GRSPW_STS_LS) >> GRSPW_STS_LS_BIT;
756}
757
758/* Enable Global IRQ only if some irq source is set */
759static inline int grspw_is_irqsource_set(unsigned int ctrl, unsigned int icctrl)
760{
761        return (ctrl & GRSPW_CTRL_IRQSRC_MASK) ||
762                (icctrl & GRSPW_ICCTRL_IRQSRC_MASK);
763}
764
765
766/* options and clkdiv [in/out]: set to -1 to only read current config */
767void grspw_link_ctrl(void *d, int *options, int *stscfg, int *clkdiv)
768{
769        struct grspw_priv *priv = d;
770        struct grspw_regs *regs = priv->regs;
771        unsigned int ctrl;
772        IRQFLAGS_TYPE irqflags;
773
774        /* Write? */
775        if (clkdiv) {
776                if (*clkdiv != -1)
777                        REG_WRITE(&regs->clkdiv, *clkdiv & GRSPW_CLKDIV_MASK);
778                *clkdiv = REG_READ(&regs->clkdiv) & GRSPW_CLKDIV_MASK;
779        }
780        if (options) {
781                SPIN_LOCK_IRQ(&priv->devlock, irqflags);
782                ctrl = REG_READ(&regs->ctrl);
783                if (*options != -1) {
784                        ctrl = (ctrl & ~GRSPW_LINK_CFG) |
785                                (*options & GRSPW_LINK_CFG);
786
787                        /* Enable Global IRQ only if some irq source is set */
788                        if (grspw_is_irqsource_set(ctrl, REG_READ(&regs->icctrl)))
789                                ctrl |= GRSPW_CTRL_IE;
790                        else
791                                ctrl &= ~GRSPW_CTRL_IE;
792
793                        REG_WRITE(&regs->ctrl, ctrl);
794                        /* Store the link disable events for use in
795                        ISR. The LINKOPTS_DIS_ON_* options are actually the
796                        corresponding bits in the status register, shifted
797                        by 16. */
798                        priv->dis_link_on_err = *options &
799                                (LINKOPTS_MASK_DIS_ON | LINKOPTS_DIS_ONERR);
800                }
801                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
802                *options = (ctrl & GRSPW_LINK_CFG) | priv->dis_link_on_err;
803        }
804        if (stscfg) {
805                if (*stscfg != -1) {
806                        priv->stscfg = *stscfg & LINKSTS_MASK;
807                }
808                *stscfg = priv->stscfg;
809        }
810}
811
812/* Generate Tick-In (increment Time Counter, Send Time Code) */
813void grspw_tc_tx(void *d)
814{
815        struct grspw_priv *priv = d;
816        struct grspw_regs *regs = priv->regs;
817        IRQFLAGS_TYPE irqflags;
818
819        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
820        REG_WRITE(&regs->ctrl, REG_READ(&regs->ctrl) | GRSPW_CTRL_TI);
821        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
822}
823
824void grspw_tc_ctrl(void *d, int *options)
825{
826        struct grspw_priv *priv = d;
827        struct grspw_regs *regs = priv->regs;
828        unsigned int ctrl;
829        IRQFLAGS_TYPE irqflags;
830
831        if (options == NULL)
832                return;
833
834        /* Write? */
835        if (*options != -1) {
836                SPIN_LOCK_IRQ(&priv->devlock, irqflags);
837                ctrl = REG_READ(&regs->ctrl);
838                ctrl &= ~(GRSPW_CTRL_TR|GRSPW_CTRL_TT|GRSPW_CTRL_TQ);
839                ctrl |= (*options & 0xd) << GRSPW_CTRL_TQ_BIT;
840
841                /* Enable Global IRQ only if some irq source is set */
842                if (grspw_is_irqsource_set(ctrl, REG_READ(&regs->icctrl)))
843                        ctrl |= GRSPW_CTRL_IE;
844                else
845                        ctrl &= ~GRSPW_CTRL_IE;
846
847                REG_WRITE(&regs->ctrl, ctrl);
848                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
849        } else
850                ctrl = REG_READ(&regs->ctrl);
851        *options = (ctrl >> GRSPW_CTRL_TQ_BIT) & 0xd;
852}
853
854/* Assign ISR Function to TimeCode RX IRQ */
855void grspw_tc_isr(void *d, void (*tcisr)(void *data, int tc), void *data)
856{
857        struct grspw_priv *priv = d;
858
859        priv->tcisr_arg = data;
860        priv->tcisr = tcisr;
861}
862
863/* Read/Write TCTRL and TIMECNT. Write if not -1, always read current value
864 * TCTRL   = bits 7 and 6
865 * TIMECNT = bits 5 to 0
866 */
867void grspw_tc_time(void *d, int *time)
868{
869        struct grspw_priv *priv = d;
870        struct grspw_regs *regs = priv->regs;
871
872        if (time == NULL)
873                return;
874        if (*time != -1)
875                REG_WRITE(&regs->time, *time & (GRSPW_TIME_TCNT | GRSPW_TIME_CTRL));
876        *time = REG_READ(&regs->time) & (GRSPW_TIME_TCNT | GRSPW_TIME_CTRL);
877}
878
879/* Generate Tick-In for the given Interrupt-code and check for generation
880 * error.
881 *
882 * Returns zero on success and non-zero on failure
883 */
884int grspw_ic_tickin(void *d, int ic)
885{
886        struct grspw_priv *priv = d;
887        struct grspw_regs *regs = priv->regs;
888        IRQFLAGS_TYPE irqflags;
889        unsigned int icctrl, mask;
890
891        /* Prepare before turning off IRQ */
892        mask = 0x3f << GRSPW_ICCTRL_TXIRQ_BIT;
893        ic = ((ic << GRSPW_ICCTRL_TXIRQ_BIT) & mask) |
894             GRSPW_ICCTRL_II | GRSPW_ICCTRL_ID;
895
896        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
897        icctrl = REG_READ(&regs->icctrl);
898        icctrl &= ~mask;
899        icctrl |= ic;
900        REG_WRITE(&regs->icctrl, icctrl); /* Generate SpW Interrupt Tick-In */
901        /* the ID bit is valid after two clocks, so we not to wait here */
902        icctrl = REG_READ(&regs->icctrl); /* Check SpW-Int generation error */
903        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
904
905        return icctrl & GRSPW_ICCTRL_ID;
906}
907
908#define ICOPTS_CTRL_MASK ICOPTS_EN_FLAGFILTER
909#define ICOPTS_ICCTRL_MASK                                              \
910        (ICOPTS_INTNUM | ICOPTS_EN_SPWIRQ_ON_EE  | ICOPTS_EN_SPWIRQ_ON_IA | \
911         ICOPTS_EN_PRIO | ICOPTS_EN_TIMEOUTIRQ | ICOPTS_EN_ACKIRQ | \
912         ICOPTS_EN_TICKOUTIRQ | ICOPTS_EN_RX | ICOPTS_EN_TX | \
913         ICOPTS_BASEIRQ)
914
915/* Control Interrupt-code settings of core
916 * Write if not pointing to -1, always read current value
917 *
918 * TODO: A lot of code duplication with grspw_tc_ctrl
919 */
920void grspw_ic_ctrl(void *d, unsigned int *options)
921{
922        struct grspw_priv *priv = d;
923        struct grspw_regs *regs = priv->regs;
924        unsigned int ctrl;
925        unsigned int icctrl;
926        IRQFLAGS_TYPE irqflags;
927
928        if (options == NULL)
929                return;
930
931        if (*options != -1) {
932                SPIN_LOCK_IRQ(&priv->devlock, irqflags);
933
934                ctrl = REG_READ(&regs->ctrl);
935                ctrl &= ~GRSPW_CTRL_TF; /* Depends on one to one relation between
936                                         * irqopts bits and ctrl bits */
937                ctrl |= (*options & ICOPTS_CTRL_MASK) <<
938                        (GRSPW_CTRL_TF_BIT - 0);
939
940                icctrl = REG_READ(&regs->icctrl);
941                icctrl &= ~ICOPTS_ICCTRL_MASK; /* Depends on one to one relation between
942                                                * irqopts bits and icctrl bits */
943                icctrl |= *options & ICOPTS_ICCTRL_MASK;
944
945                /* Enable Global IRQ only if some irq source is set */
946                if (grspw_is_irqsource_set(ctrl, icctrl))
947                        ctrl |= GRSPW_CTRL_IE;
948                else
949                        ctrl &= ~GRSPW_CTRL_IE;
950
951                REG_WRITE(&regs->ctrl, ctrl);
952                REG_WRITE(&regs->icctrl, icctrl);
953                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
954        }
955        *options = ((REG_READ(&regs->ctrl) & ICOPTS_CTRL_MASK) |
956                    (REG_READ(&regs->icctrl) & ICOPTS_ICCTRL_MASK));
957}
958
959void grspw_ic_config(void *d, int rw, struct spwpkt_ic_config *cfg)
960{
961        struct grspw_priv *priv = d;
962        struct grspw_regs *regs = priv->regs;
963
964        if (!cfg)
965                return;
966
967        if (rw & 1) {
968                REG_WRITE(&regs->ictickomask, cfg->tomask);
969                REG_WRITE(&regs->icaamask, cfg->aamask);
970                REG_WRITE(&regs->icrlpresc, cfg->scaler);
971                REG_WRITE(&regs->icrlisr, cfg->isr_reload);
972                REG_WRITE(&regs->icrlintack, cfg->ack_reload);
973        }
974        if (rw & 2) {
975                cfg->tomask = REG_READ(&regs->ictickomask);
976                cfg->aamask = REG_READ(&regs->icaamask);
977                cfg->scaler = REG_READ(&regs->icrlpresc);
978                cfg->isr_reload = REG_READ(&regs->icrlisr);
979                cfg->ack_reload = REG_READ(&regs->icrlintack);
980        }
981}
982
983/* Read or Write Interrupt-code status registers */
984void grspw_ic_sts(void *d, unsigned int *rxirq, unsigned int *rxack, unsigned int *intto)
985{
986        struct grspw_priv *priv = d;
987        struct grspw_regs *regs = priv->regs;
988
989        /* No locking needed since the status bits are clear-on-write */
990
991        if (rxirq) {
992                if (*rxirq != 0)
993                        REG_WRITE(&regs->icrx, *rxirq);
994                else
995                        *rxirq = REG_READ(&regs->icrx);
996        }
997
998        if (rxack) {
999                if (*rxack != 0)
1000                        REG_WRITE(&regs->icack, *rxack);
1001                else
1002                        *rxack = REG_READ(&regs->icack);
1003        }
1004
1005        if (intto) {
1006                if (*intto != 0)
1007                        REG_WRITE(&regs->ictimeout, *intto);
1008                else
1009                        *intto = REG_READ(&regs->ictimeout);
1010        }
1011}
1012
1013/* Assign handler function to Interrupt-code tick out IRQ */
1014void grspw_ic_isr(void *d, spwpkt_ic_isr_t handler, void *data)
1015{
1016        struct grspw_priv *priv = d;
1017
1018        priv->icisr_arg = data;
1019        priv->icisr = handler;
1020}
1021
1022/* Set (not -1) and/or read RMAP options. */
1023int grspw_rmap_ctrl(void *d, int *options, int *dstkey)
1024{
1025        struct grspw_priv *priv = d;
1026        struct grspw_regs *regs = priv->regs;
1027        unsigned int ctrl;
1028        IRQFLAGS_TYPE irqflags;
1029
1030        if (dstkey) {
1031                if (*dstkey != -1)
1032                        REG_WRITE(&regs->destkey, *dstkey & GRSPW_DK_DESTKEY);
1033                *dstkey = REG_READ(&regs->destkey) & GRSPW_DK_DESTKEY;
1034        }
1035        if (options) {
1036                if (*options != -1) {
1037                        if ((*options & RMAPOPTS_EN_RMAP) && !priv->hwsup.rmap)
1038                                return -1;
1039
1040
1041                        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1042                        ctrl = REG_READ(&regs->ctrl);
1043                        ctrl &= ~(GRSPW_CTRL_RE|GRSPW_CTRL_RD);
1044                        ctrl |= (*options & 0x3) << GRSPW_CTRL_RE_BIT;
1045                        REG_WRITE(&regs->ctrl, ctrl);
1046                        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1047                }
1048                *options = (REG_READ(&regs->ctrl) >> GRSPW_CTRL_RE_BIT) & 0x3;
1049        }
1050
1051        return 0;
1052}
1053
1054void grspw_rmap_support(void *d, char *rmap, char *rmap_crc)
1055{
1056        struct grspw_priv *priv = d;
1057
1058        if (rmap)
1059                *rmap = priv->hwsup.rmap;
1060        if (rmap_crc)
1061                *rmap_crc = priv->hwsup.rmap_crc;
1062}
1063
1064/* Select port, if
1065 * -1=The current selected port is returned
1066 * 0=Port 0
1067 * 1=Port 1
1068 * Others=Both Port0 and Port1
1069 */
1070int grspw_port_ctrl(void *d, int *port)
1071{
1072        struct grspw_priv *priv = d;
1073        struct grspw_regs *regs = priv->regs;
1074        unsigned int ctrl;
1075        IRQFLAGS_TYPE irqflags;
1076
1077        if (port == NULL)
1078                return -1;
1079
1080        if ((*port == 1) || (*port == 0)) {
1081                /* Select port user selected */
1082                if ((*port == 1) && (priv->hwsup.nports < 2))
1083                        return -1; /* Changing to Port 1, but only one port available */
1084                SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1085                ctrl = REG_READ(&regs->ctrl);
1086                ctrl &= ~(GRSPW_CTRL_NP | GRSPW_CTRL_PS);
1087                ctrl |= (*port & 1) << GRSPW_CTRL_PS_BIT;
1088                REG_WRITE(&regs->ctrl, ctrl);
1089                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1090        } else if (*port > 1) {
1091                /* Select both ports */
1092                SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1093                REG_WRITE(&regs->ctrl, REG_READ(&regs->ctrl) | GRSPW_CTRL_NP);
1094                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1095        }
1096
1097        /* Get current settings */
1098        ctrl = REG_READ(&regs->ctrl);
1099        if (ctrl & GRSPW_CTRL_NP) {
1100                /* Any port, selected by hardware */
1101                if (priv->hwsup.nports > 1)
1102                        *port = 3;
1103                else
1104                        *port = 0; /* Port0 the only port available */
1105        } else {
1106                *port = (ctrl & GRSPW_CTRL_PS) >> GRSPW_CTRL_PS_BIT;
1107        }
1108
1109        return 0;
1110}
1111
1112/* Returns Number ports available in hardware */
1113int grspw_port_count(void *d)
1114{
1115        struct grspw_priv *priv = d;
1116
1117        return priv->hwsup.nports;
1118}
1119
1120/* Current active port: 0 or 1 */
1121int grspw_port_active(void *d)
1122{
1123        struct grspw_priv *priv = d;
1124        unsigned int status;
1125
1126        status = REG_READ(&priv->regs->status);
1127
1128        return (status & GRSPW_STS_AP) >> GRSPW_STS_AP_BIT;
1129}
1130
1131void grspw_stats_read(void *d, struct grspw_core_stats *sts)
1132{
1133        struct grspw_priv *priv = d;
1134
1135        if (sts == NULL)
1136                return;
1137        memcpy(sts, &priv->stats, sizeof(priv->stats));
1138}
1139
1140void grspw_stats_clr(void *d)
1141{
1142        struct grspw_priv *priv = d;
1143
1144        /* Clear most of the statistics */     
1145        memset(&priv->stats, 0, sizeof(priv->stats));
1146}
1147
1148/*** DMA Interface ***/
1149
1150/* Initialize the RX and TX Descriptor Ring, empty of packets */
1151STATIC void grspw_bdrings_init(struct grspw_dma_priv *dma)
1152{
1153        struct grspw_ring *r;
1154        int i;
1155
1156        /* Empty BD rings */
1157        dma->rx_ring_head = dma->rx_ring_base;
1158        dma->rx_ring_tail = dma->rx_ring_base;
1159        dma->tx_ring_head = dma->tx_ring_base;
1160        dma->tx_ring_tail = dma->tx_ring_base;
1161
1162        /* Init RX Descriptors */
1163        r = (struct grspw_ring *)dma->rx_ring_base;
1164        for (i=0; i<GRSPW_RXBD_NR; i++) {
1165
1166                /* Init Ring Entry */
1167                r[i].next = &r[i+1];
1168                r[i].bd.rx = &dma->rx_bds[i];
1169                r[i].pkt = NULL;
1170
1171                /* Init HW Descriptor */
1172                BD_WRITE(&r[i].bd.rx->ctrl, 0);
1173                BD_WRITE(&r[i].bd.rx->addr, 0);
1174        }
1175        r[GRSPW_RXBD_NR-1].next = &r[0];
1176
1177        /* Init TX Descriptors */
1178        r = (struct grspw_ring *)dma->tx_ring_base;
1179        for (i=0; i<GRSPW_TXBD_NR; i++) {
1180
1181                /* Init Ring Entry */
1182                r[i].next = &r[i+1];
1183                r[i].bd.tx = &dma->tx_bds[i];
1184                r[i].pkt = NULL;
1185
1186                /* Init HW Descriptor */
1187                BD_WRITE(&r[i].bd.tx->ctrl, 0);
1188                BD_WRITE(&r[i].bd.tx->haddr, 0);
1189                BD_WRITE(&r[i].bd.tx->dlen, 0);
1190                BD_WRITE(&r[i].bd.tx->daddr, 0);
1191        }
1192        r[GRSPW_TXBD_NR-1].next = &r[0];
1193}
1194
1195/* Try to populate descriptor ring with as many as possible READY unused packet
1196 * buffers. The packets assigned with to a descriptor are put in the end of
1197 * the scheduled list.
1198 *
1199 * The number of Packets scheduled is returned.
1200 *
1201 *  - READY List -> RX-SCHED List
1202 *  - Descriptors are initialized and enabled for reception
1203 */
1204STATIC int grspw_rx_schedule_ready(struct grspw_dma_priv *dma)
1205{
1206        int cnt;
1207        unsigned int ctrl, dmactrl;
1208        void *hwaddr;
1209        struct grspw_rxring *curr_bd;
1210        struct grspw_pkt *curr_pkt, *last_pkt;
1211        struct grspw_list lst;
1212        IRQFLAGS_TYPE irqflags;
1213
1214        /* Is Ready Q empty? */
1215        if (grspw_list_is_empty(&dma->ready))
1216                return 0;
1217
1218        cnt = 0;
1219        lst.head = curr_pkt = dma->ready.head;
1220        curr_bd = dma->rx_ring_head;
1221        while (!curr_bd->pkt) {
1222
1223                /* Assign Packet to descriptor */
1224                curr_bd->pkt = curr_pkt;
1225
1226                /* Prepare descriptor address. */
1227                hwaddr = curr_pkt->data;
1228                if (curr_pkt->flags & PKT_FLAG_TR_DATA) {
1229                        drvmgr_translate(dma->core->dev, CPUMEM_TO_DMA,
1230                                         hwaddr, &hwaddr);
1231                        if (curr_pkt->data == hwaddr) /* translation needed? */
1232                                curr_pkt->flags &= ~PKT_FLAG_TR_DATA;
1233                }
1234                BD_WRITE(&curr_bd->bd->addr, hwaddr);
1235
1236                ctrl = GRSPW_RXBD_EN;
1237                if (curr_bd->next == dma->rx_ring_base) {
1238                        /* Wrap around (only needed when smaller descriptor
1239                         * table)
1240                         */
1241                        ctrl |= GRSPW_RXBD_WR;
1242                }
1243
1244                /* Is this Packet going to be an interrupt Packet? */
1245                if ((--dma->rx_irq_en_cnt_curr) <= 0) {
1246                        if (dma->cfg.rx_irq_en_cnt == 0) {
1247                                /* IRQ is disabled. A big number to avoid
1248                                 * equal to zero too often
1249                                 */
1250                                dma->rx_irq_en_cnt_curr = 0x3fffffff;
1251                        } else {
1252                                dma->rx_irq_en_cnt_curr = dma->cfg.rx_irq_en_cnt;
1253                                ctrl |= GRSPW_RXBD_IE;
1254                        }
1255                }
1256
1257                if (curr_pkt->flags & RXPKT_FLAG_IE)
1258                        ctrl |= GRSPW_RXBD_IE;
1259
1260                /* Enable descriptor */
1261                BD_WRITE(&curr_bd->bd->ctrl, ctrl);
1262
1263                last_pkt = curr_pkt;
1264                curr_bd = curr_bd->next;
1265                cnt++;
1266
1267                /* Get Next Packet from Ready Queue */
1268                if (curr_pkt == dma->ready.tail) {
1269                        /* Handled all in ready queue. */
1270                        curr_pkt = NULL;
1271                        break;
1272                }
1273                curr_pkt = curr_pkt->next;
1274        }
1275
1276        /* Has Packets been scheduled? */
1277        if (cnt > 0) {
1278                /* Prepare list for insertion/deleation */
1279                lst.tail = last_pkt;
1280
1281                /* Remove scheduled packets from ready queue */
1282                grspw_list_remove_head_list(&dma->ready, &lst);
1283                dma->ready_cnt -= cnt;
1284                if (dma->stats.ready_cnt_min > dma->ready_cnt)
1285                        dma->stats.ready_cnt_min = dma->ready_cnt;
1286
1287                /* Insert scheduled packets into scheduled queue */
1288                grspw_list_append_list(&dma->rx_sched, &lst);
1289                dma->rx_sched_cnt += cnt;
1290                if (dma->stats.rx_sched_cnt_max < dma->rx_sched_cnt)
1291                        dma->stats.rx_sched_cnt_max = dma->rx_sched_cnt;
1292
1293                /* Update TX ring posistion */
1294                dma->rx_ring_head = curr_bd;
1295
1296                /* Make hardware aware of the newly enabled descriptors
1297                 * We must protect from ISR which writes RI|TI
1298                 */
1299                SPIN_LOCK_IRQ(&dma->core->devlock, irqflags);
1300                dmactrl = REG_READ(&dma->regs->ctrl);
1301                dmactrl &= ~(GRSPW_DMACTRL_PS|GRSPW_DMACTRL_PR|GRSPW_DMA_STATUS_ERROR);
1302                dmactrl |= GRSPW_DMACTRL_RE | GRSPW_DMACTRL_RD;
1303                REG_WRITE(&dma->regs->ctrl, dmactrl);
1304                SPIN_UNLOCK_IRQ(&dma->core->devlock, irqflags);
1305        }
1306
1307        return cnt;
1308}
1309
1310/* Scans the RX desciptor table for scheduled Packet that has been received,
1311 * and moves these Packet from the head of the scheduled queue to the
1312 * tail of the recv queue.
1313 *
1314 * Also, for all packets the status is updated.
1315 *
1316 *  - SCHED List -> SENT List
1317 *
1318 * Return Value
1319 * Number of packets moved
1320 */
1321STATIC int grspw_rx_process_scheduled(struct grspw_dma_priv *dma)
1322{
1323        struct grspw_rxring *curr;
1324        struct grspw_pkt *last_pkt;
1325        int recv_pkt_cnt = 0;
1326        unsigned int ctrl;
1327        struct grspw_list lst;
1328
1329        curr = dma->rx_ring_tail;
1330
1331        /* Step into RX ring to find if packets have been scheduled for
1332         * reception.
1333         */
1334        if (!curr->pkt)
1335                return 0; /* No scheduled packets, thus no received, abort */
1336
1337        /* There has been Packets scheduled ==> scheduled Packets may have been
1338         * received and needs to be collected into RECV List.
1339         *
1340         * A temporary list "lst" with all received packets is created.
1341         */
1342        lst.head = curr->pkt;
1343
1344        /* Loop until first enabled "unrecveived" SpW Packet is found.
1345         * An unused descriptor is indicated by an unassigned pkt field.
1346         */
1347        while (curr->pkt && !((ctrl=BD_READ(&curr->bd->ctrl)) & GRSPW_RXBD_EN)) {
1348                /* Handle one received Packet */
1349
1350                /* Remember last handled Packet so that insertion/removal from
1351                 * Packet lists go fast.
1352                 */
1353                last_pkt = curr->pkt;
1354
1355                /* Get Length of Packet in bytes, and reception options */
1356                last_pkt->dlen = (ctrl & GRSPW_RXBD_LEN) >> GRSPW_RXBD_LEN_BIT;
1357
1358                /* Set flags to indicate error(s) and CRC information,
1359                 * and Mark Received.
1360                 */
1361                last_pkt->flags = (last_pkt->flags & ~RXPKT_FLAG_OUTPUT_MASK) |
1362                                  ((ctrl >> 20) & RXPKT_FLAG_OUTPUT_MASK) |
1363                                  RXPKT_FLAG_RX;
1364
1365                /* Packet was Truncated? */
1366                if (ctrl & GRSPW_RXBD_TR)
1367                        dma->stats.rx_err_trunk++;
1368
1369                /* Error End-Of-Packet? */
1370                if (ctrl & GRSPW_RXBD_EP)
1371                        dma->stats.rx_err_endpkt++;
1372                curr->pkt = NULL; /* Mark descriptor unused */
1373
1374                /* Increment */
1375                curr = curr->next;
1376                recv_pkt_cnt++;
1377        }
1378
1379        /* 1. Remove all handled packets from scheduled queue
1380         * 2. Put all handled packets into recv queue
1381         */
1382        if (recv_pkt_cnt > 0) {
1383
1384                /* Update Stats, Number of Received Packets */
1385                dma->stats.rx_pkts += recv_pkt_cnt;
1386
1387                /* Save RX ring posistion */
1388                dma->rx_ring_tail = curr;
1389
1390                /* Prepare list for insertion/deleation */
1391                lst.tail = last_pkt;
1392
1393                /* Remove received Packets from RX-SCHED queue */
1394                grspw_list_remove_head_list(&dma->rx_sched, &lst);
1395                dma->rx_sched_cnt -= recv_pkt_cnt;
1396                if (dma->stats.rx_sched_cnt_min > dma->rx_sched_cnt)
1397                        dma->stats.rx_sched_cnt_min = dma->rx_sched_cnt;
1398
1399                /* Insert received Packets into RECV queue */
1400                grspw_list_append_list(&dma->recv, &lst);
1401                dma->recv_cnt += recv_pkt_cnt;
1402                if (dma->stats.recv_cnt_max < dma->recv_cnt)
1403                        dma->stats.recv_cnt_max = dma->recv_cnt;
1404        }
1405
1406        return recv_pkt_cnt;
1407}
1408
1409/* Try to populate descriptor ring with as many SEND packets as possible. The
1410 * packets assigned with to a descriptor are put in the end of
1411 * the scheduled list.
1412 *
1413 * The number of Packets scheduled is returned.
1414 *
1415 *  - SEND List -> TX-SCHED List
1416 *  - Descriptors are initialized and enabled for transmission
1417 */
1418STATIC int grspw_tx_schedule_send(struct grspw_dma_priv *dma)
1419{
1420        int cnt;
1421        unsigned int ctrl, dmactrl;
1422        void *hwaddr;
1423        struct grspw_txring *curr_bd;
1424        struct grspw_pkt *curr_pkt, *last_pkt;
1425        struct grspw_list lst;
1426        IRQFLAGS_TYPE irqflags;
1427
1428        /* Is Ready Q empty? */
1429        if (grspw_list_is_empty(&dma->send))
1430                return 0;
1431
1432        cnt = 0;
1433        lst.head = curr_pkt = dma->send.head;
1434        curr_bd = dma->tx_ring_head;
1435        while (!curr_bd->pkt) {
1436
1437                /* Assign Packet to descriptor */
1438                curr_bd->pkt = curr_pkt;
1439
1440                /* Set up header transmission */
1441                if (curr_pkt->hdr && curr_pkt->hlen) {
1442                        hwaddr = curr_pkt->hdr;
1443                        if (curr_pkt->flags & PKT_FLAG_TR_HDR) {
1444                                drvmgr_translate(dma->core->dev, CPUMEM_TO_DMA,
1445                                                 hwaddr, &hwaddr);
1446                                /* translation needed? */
1447                                if (curr_pkt->hdr == hwaddr)
1448                                        curr_pkt->flags &= ~PKT_FLAG_TR_HDR;
1449                        }
1450                        BD_WRITE(&curr_bd->bd->haddr, hwaddr);
1451                        ctrl = GRSPW_TXBD_EN | curr_pkt->hlen;
1452                } else {
1453                        ctrl = GRSPW_TXBD_EN;
1454                }
1455                /* Enable IRQ generation and CRC options as specified
1456                 * by user.
1457                 */
1458                ctrl |= (curr_pkt->flags & TXPKT_FLAG_INPUT_MASK) << 8;
1459
1460                if (curr_bd->next == dma->tx_ring_base) {
1461                        /* Wrap around (only needed when smaller descriptor table) */
1462                        ctrl |= GRSPW_TXBD_WR;
1463                }
1464
1465                /* Is this Packet going to be an interrupt Packet? */
1466                if ((--dma->tx_irq_en_cnt_curr) <= 0) {
1467                        if (dma->cfg.tx_irq_en_cnt == 0) {
1468                                /* IRQ is disabled.
1469                                 * A big number to avoid equal to zero too often
1470                                 */
1471                                dma->tx_irq_en_cnt_curr = 0x3fffffff;
1472                        } else {
1473                                dma->tx_irq_en_cnt_curr = dma->cfg.tx_irq_en_cnt;
1474                                ctrl |= GRSPW_TXBD_IE;
1475                        }
1476                }
1477
1478                /* Prepare descriptor address. Parts of CTRL is written to
1479                 * DLEN for debug-only (CTRL is cleared by HW).
1480                 */
1481                if (curr_pkt->data && curr_pkt->dlen) {
1482                        hwaddr = curr_pkt->data;
1483                        if (curr_pkt->flags & PKT_FLAG_TR_DATA) {
1484                                drvmgr_translate(dma->core->dev, CPUMEM_TO_DMA,
1485                                                 hwaddr, &hwaddr);
1486                                /* translation needed? */
1487                                if (curr_pkt->data == hwaddr)
1488                                        curr_pkt->flags &= ~PKT_FLAG_TR_DATA;
1489                        }
1490                        BD_WRITE(&curr_bd->bd->daddr, hwaddr);
1491                        BD_WRITE(&curr_bd->bd->dlen, curr_pkt->dlen |
1492                                                     ((ctrl & 0x3f000) << 12));
1493                } else {
1494                        BD_WRITE(&curr_bd->bd->daddr, 0);
1495                        BD_WRITE(&curr_bd->bd->dlen, ((ctrl & 0x3f000) << 12));
1496                }
1497
1498                /* Enable descriptor */
1499                BD_WRITE(&curr_bd->bd->ctrl, ctrl);
1500
1501                last_pkt = curr_pkt;
1502                curr_bd = curr_bd->next;
1503                cnt++;
1504
1505                /* Get Next Packet from Ready Queue */
1506                if (curr_pkt == dma->send.tail) {
1507                        /* Handled all in ready queue. */
1508                        curr_pkt = NULL;
1509                        break;
1510                }
1511                curr_pkt = curr_pkt->next;
1512        }
1513
1514        /* Have Packets been scheduled? */
1515        if (cnt > 0) {
1516                /* Prepare list for insertion/deleation */
1517                lst.tail = last_pkt;
1518
1519                /* Remove scheduled packets from ready queue */
1520                grspw_list_remove_head_list(&dma->send, &lst);
1521                dma->send_cnt -= cnt;
1522                if (dma->stats.send_cnt_min > dma->send_cnt)
1523                        dma->stats.send_cnt_min = dma->send_cnt;
1524
1525                /* Insert scheduled packets into scheduled queue */
1526                grspw_list_append_list(&dma->tx_sched, &lst);
1527                dma->tx_sched_cnt += cnt;
1528                if (dma->stats.tx_sched_cnt_max < dma->tx_sched_cnt)
1529                        dma->stats.tx_sched_cnt_max = dma->tx_sched_cnt;
1530
1531                /* Update TX ring posistion */
1532                dma->tx_ring_head = curr_bd;
1533
1534                /* Make hardware aware of the newly enabled descriptors */
1535                SPIN_LOCK_IRQ(&dma->core->devlock, irqflags);
1536                dmactrl = REG_READ(&dma->regs->ctrl);
1537                dmactrl &= ~(GRSPW_DMACTRL_PS|GRSPW_DMACTRL_PR|GRSPW_DMA_STATUS_ERROR);
1538                dmactrl |= GRSPW_DMACTRL_TE;
1539                REG_WRITE(&dma->regs->ctrl, dmactrl);
1540                SPIN_UNLOCK_IRQ(&dma->core->devlock, irqflags);
1541        }
1542        return cnt;
1543}
1544
1545/* Scans the TX desciptor table for transmitted packets, and moves these
1546 * packets from the head of the scheduled queue to the tail of the sent queue.
1547 *
1548 * Also, for all packets the status is updated.
1549 *
1550 *  - SCHED List -> SENT List
1551 *
1552 * Return Value
1553 * Number of packet moved
1554 */
1555STATIC int grspw_tx_process_scheduled(struct grspw_dma_priv *dma)
1556{
1557        struct grspw_txring *curr;
1558        struct grspw_pkt *last_pkt;
1559        int sent_pkt_cnt = 0;
1560        unsigned int ctrl;
1561        struct grspw_list lst;
1562
1563        curr = dma->tx_ring_tail;
1564
1565        /* Step into TX ring to find if packets have been scheduled for
1566         * transmission.
1567         */
1568        if (!curr->pkt)
1569                return 0; /* No scheduled packets, thus no sent, abort */
1570
1571        /* There has been Packets scheduled ==> scheduled Packets may have been
1572         * transmitted and needs to be collected into SENT List.
1573         *
1574         * A temporary list "lst" with all sent packets is created.
1575         */
1576        lst.head = curr->pkt;
1577
1578        /* Loop until first enabled "un-transmitted" SpW Packet is found.
1579         * An unused descriptor is indicated by an unassigned pkt field.
1580         */
1581        while (curr->pkt && !((ctrl=BD_READ(&curr->bd->ctrl)) & GRSPW_TXBD_EN)) {
1582                /* Handle one sent Packet */
1583
1584                /* Remember last handled Packet so that insertion/removal from
1585                 * packet lists go fast.
1586                 */
1587                last_pkt = curr->pkt;
1588
1589                /* Set flags to indicate error(s) and Mark Sent.
1590                 */
1591                last_pkt->flags = (last_pkt->flags & ~TXPKT_FLAG_OUTPUT_MASK) |
1592                                        (ctrl & TXPKT_FLAG_LINKERR) |
1593                                        TXPKT_FLAG_TX;
1594
1595                /* Sent packet experienced link error? */
1596                if (ctrl & GRSPW_TXBD_LE)
1597                        dma->stats.tx_err_link++;
1598
1599                curr->pkt = NULL; /* Mark descriptor unused */
1600
1601                /* Increment */
1602                curr = curr->next;
1603                sent_pkt_cnt++;
1604        }
1605
1606        /* 1. Remove all handled packets from TX-SCHED queue
1607         * 2. Put all handled packets into SENT queue
1608         */
1609        if (sent_pkt_cnt > 0) {
1610                /* Update Stats, Number of Transmitted Packets */
1611                dma->stats.tx_pkts += sent_pkt_cnt;
1612
1613                /* Save TX ring posistion */
1614                dma->tx_ring_tail = curr;
1615
1616                /* Prepare list for insertion/deleation */
1617                lst.tail = last_pkt;
1618
1619                /* Remove sent packets from TX-SCHED queue */
1620                grspw_list_remove_head_list(&dma->tx_sched, &lst);
1621                dma->tx_sched_cnt -= sent_pkt_cnt;
1622                if (dma->stats.tx_sched_cnt_min > dma->tx_sched_cnt)
1623                        dma->stats.tx_sched_cnt_min = dma->tx_sched_cnt;
1624
1625                /* Insert received packets into SENT queue */
1626                grspw_list_append_list(&dma->sent, &lst);
1627                dma->sent_cnt += sent_pkt_cnt;
1628                if (dma->stats.sent_cnt_max < dma->sent_cnt)
1629                        dma->stats.sent_cnt_max = dma->sent_cnt;
1630        }
1631
1632        return sent_pkt_cnt;
1633}
1634
1635void *grspw_dma_open(void *d, int chan_no)
1636{
1637        struct grspw_priv *priv = d;
1638        struct grspw_dma_priv *dma;
1639        int size;
1640
1641        if ((chan_no < 0) || (priv->hwsup.ndma_chans <= chan_no))
1642                return NULL;
1643
1644        dma = &priv->dma[chan_no];
1645
1646        /* Take GRSPW lock */
1647        if (rtems_semaphore_obtain(grspw_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1648            != RTEMS_SUCCESSFUL)
1649                return NULL;
1650
1651        if (dma->open) {
1652                dma = NULL;
1653                goto out;
1654        }
1655
1656        dma->started = 0;
1657
1658        /* Set Default Configuration:
1659         *
1660         *  - MAX RX Packet Length =
1661         *  - Disable IRQ generation
1662         *  -
1663         */
1664        dma->cfg.rxmaxlen = DEFAULT_RXMAX;
1665        dma->cfg.rx_irq_en_cnt = 0;
1666        dma->cfg.tx_irq_en_cnt = 0;
1667        dma->cfg.flags = DMAFLAG_NO_SPILL;
1668
1669        /* set to NULL so that error exit works correctly */
1670        dma->sem_rxdma = RTEMS_ID_NONE;
1671        dma->sem_txdma = RTEMS_ID_NONE;
1672        dma->rx_wait.sem_wait = RTEMS_ID_NONE;
1673        dma->tx_wait.sem_wait = RTEMS_ID_NONE;
1674        dma->rx_ring_base = NULL;
1675
1676        /* DMA Channel Semaphore created with count = 1 */
1677        if (rtems_semaphore_create(
1678            rtems_build_name('S', 'D', '0' + priv->index, '0' + chan_no*2), 1,
1679            RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | \
1680            RTEMS_NO_INHERIT_PRIORITY | RTEMS_LOCAL | \
1681            RTEMS_NO_PRIORITY_CEILING, 0, &dma->sem_rxdma) != RTEMS_SUCCESSFUL) {
1682                dma->sem_rxdma = RTEMS_ID_NONE;
1683                goto err;
1684        }
1685        if (rtems_semaphore_create(
1686            rtems_build_name('S', 'D', '0' + priv->index, '0' + chan_no*2+1), 1,
1687            RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | \
1688            RTEMS_NO_INHERIT_PRIORITY | RTEMS_LOCAL | \
1689            RTEMS_NO_PRIORITY_CEILING, 0, &dma->sem_txdma) != RTEMS_SUCCESSFUL) {
1690                dma->sem_txdma = RTEMS_ID_NONE;
1691                goto err;
1692        }
1693
1694        /* Allocate memory for the two descriptor rings */
1695        size = sizeof(struct grspw_ring) * (GRSPW_RXBD_NR + GRSPW_TXBD_NR);
1696        dma->rx_ring_base = (struct grspw_rxring *)malloc(size);
1697        dma->tx_ring_base = (struct grspw_txring *)&dma->rx_ring_base[GRSPW_RXBD_NR];
1698        if (dma->rx_ring_base == NULL)
1699                goto err;
1700
1701        /* Create DMA RX and TX Channel sempahore with count = 0 */
1702        if (rtems_semaphore_create(
1703            rtems_build_name('S', 'R', '0' + priv->index, '0' + chan_no), 0,
1704            RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | \
1705            RTEMS_NO_INHERIT_PRIORITY | RTEMS_LOCAL | \
1706            RTEMS_NO_PRIORITY_CEILING, 0, &dma->rx_wait.sem_wait) != RTEMS_SUCCESSFUL) {
1707                dma->rx_wait.sem_wait = RTEMS_ID_NONE;
1708                goto err;
1709        }
1710        if (rtems_semaphore_create(
1711            rtems_build_name('S', 'T', '0' + priv->index, '0' + chan_no), 0,
1712            RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | \
1713            RTEMS_NO_INHERIT_PRIORITY | RTEMS_LOCAL | \
1714            RTEMS_NO_PRIORITY_CEILING, 0, &dma->tx_wait.sem_wait) != RTEMS_SUCCESSFUL) {
1715                dma->tx_wait.sem_wait = RTEMS_ID_NONE;
1716                goto err;
1717        }
1718
1719        /* Reset software structures */
1720        grspw_dma_reset(dma);
1721
1722        /* Take the device */
1723        dma->open = 1;
1724out:
1725        /* Return GRSPW Lock */
1726        rtems_semaphore_release(grspw_sem);
1727
1728        return dma;
1729
1730        /* initialization error happended */
1731err:
1732        if (dma->sem_rxdma != RTEMS_ID_NONE)
1733                rtems_semaphore_delete(dma->sem_rxdma);
1734        if (dma->sem_txdma != RTEMS_ID_NONE)
1735                rtems_semaphore_delete(dma->sem_txdma);
1736        if (dma->rx_wait.sem_wait != RTEMS_ID_NONE)
1737                rtems_semaphore_delete(dma->rx_wait.sem_wait);
1738        if (dma->tx_wait.sem_wait != RTEMS_ID_NONE)
1739                rtems_semaphore_delete(dma->tx_wait.sem_wait);
1740        if (dma->rx_ring_base)
1741                free(dma->rx_ring_base);
1742        dma = NULL;
1743        goto out;
1744}
1745
1746/* Initialize Software Structures:
1747 *  - Clear all Queues
1748 *  - init BD ring
1749 *  - init IRQ counter
1750 *  - clear statistics counters
1751 *  - init wait structures and semaphores
1752 */
1753STATIC void grspw_dma_reset(struct grspw_dma_priv *dma)
1754{
1755        /* Empty RX and TX queues */
1756        grspw_list_clr(&dma->ready);
1757        grspw_list_clr(&dma->rx_sched);
1758        grspw_list_clr(&dma->recv);
1759        grspw_list_clr(&dma->send);
1760        grspw_list_clr(&dma->tx_sched);
1761        grspw_list_clr(&dma->sent);
1762        dma->ready_cnt = 0;
1763        dma->rx_sched_cnt = 0;
1764        dma->recv_cnt = 0;
1765        dma->send_cnt = 0;
1766        dma->tx_sched_cnt = 0;
1767        dma->sent_cnt = 0;
1768
1769        dma->rx_irq_en_cnt_curr = 0;
1770        dma->tx_irq_en_cnt_curr = 0;
1771
1772        grspw_bdrings_init(dma);
1773
1774        dma->rx_wait.waiting = 0;
1775        dma->tx_wait.waiting = 0;
1776
1777        grspw_dma_stats_clr(dma);
1778}
1779
1780int grspw_dma_close(void *c)
1781{
1782        struct grspw_dma_priv *dma = c;
1783
1784        if (!dma->open)
1785                return 0;
1786
1787        /* Take device lock - Wait until we get semaphore */
1788        if (rtems_semaphore_obtain(dma->sem_rxdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1789            != RTEMS_SUCCESSFUL)
1790                return -1;
1791        if (rtems_semaphore_obtain(dma->sem_txdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1792            != RTEMS_SUCCESSFUL) {
1793                rtems_semaphore_release(dma->sem_rxdma);
1794                return -1;
1795        }
1796
1797        /* Can not close active DMA channel. User must stop DMA and make sure
1798         * no threads are active/blocked within driver.
1799         */
1800        if (dma->started || dma->rx_wait.waiting || dma->tx_wait.waiting) {
1801                rtems_semaphore_release(dma->sem_txdma);
1802                rtems_semaphore_release(dma->sem_rxdma);
1803                return 1;
1804        }
1805
1806        /* Free resources */
1807        rtems_semaphore_delete(dma->rx_wait.sem_wait);
1808        rtems_semaphore_delete(dma->tx_wait.sem_wait);
1809        /* Release and delete lock. Operations requiring lock will fail */
1810        rtems_semaphore_delete(dma->sem_txdma);
1811        rtems_semaphore_delete(dma->sem_rxdma);
1812        dma->sem_txdma = RTEMS_ID_NONE;
1813        dma->sem_rxdma = RTEMS_ID_NONE;
1814
1815        /* Free memory */
1816        if (dma->rx_ring_base)
1817                free(dma->rx_ring_base);
1818        dma->rx_ring_base = NULL;
1819        dma->tx_ring_base = NULL;
1820
1821        dma->open = 0;
1822        return 0;
1823}
1824
1825/* Schedule List of packets for transmission at some point in
1826 * future.
1827 *
1828 * 1. Move transmitted packets to SENT List (SCHED->SENT)
1829 * 2. Add the requested packets to the SEND List (USER->SEND)
1830 * 3. Schedule as many packets as possible (SEND->SCHED)
1831 */
1832int grspw_dma_tx_send(void *c, int opts, struct grspw_list *pkts, int count)
1833{
1834        struct grspw_dma_priv *dma = c;
1835        int ret;
1836
1837        /* Take DMA channel lock */
1838        if (rtems_semaphore_obtain(dma->sem_txdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1839            != RTEMS_SUCCESSFUL)
1840                return -1;
1841
1842        if (dma->started == 0) {
1843                ret = 1; /* signal DMA has been stopped */
1844                goto out;
1845        }
1846        ret = 0;
1847
1848        /* 1. Move transmitted packets to SENT List (SCHED->SENT) */
1849        if ((opts & 1) == 0)
1850                grspw_tx_process_scheduled(dma);
1851
1852        /* 2. Add the requested packets to the SEND List (USER->SEND) */
1853        if (pkts && (count > 0)) {
1854                grspw_list_append_list(&dma->send, pkts);
1855                dma->send_cnt += count;
1856                if (dma->stats.send_cnt_max < dma->send_cnt)
1857                        dma->stats.send_cnt_max = dma->send_cnt;
1858        }
1859
1860        /* 3. Schedule as many packets as possible (SEND->SCHED) */
1861        if ((opts & 2) == 0)
1862                grspw_tx_schedule_send(dma);
1863
1864out:
1865        /* Unlock DMA channel */
1866        rtems_semaphore_release(dma->sem_txdma);
1867
1868        return ret;
1869}
1870
1871int grspw_dma_tx_reclaim(void *c, int opts, struct grspw_list *pkts, int *count)
1872{
1873        struct grspw_dma_priv *dma = c;
1874        struct grspw_pkt *pkt, *lastpkt;
1875        int cnt, started;
1876
1877        /* Take DMA channel lock */
1878        if (rtems_semaphore_obtain(dma->sem_txdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1879            != RTEMS_SUCCESSFUL)
1880                return -1;
1881
1882        /* 1. Move transmitted packets to SENT List (SCHED->SENT) */
1883        started = dma->started;
1884        if ((started > 0) && ((opts & 1) == 0))
1885                grspw_tx_process_scheduled(dma);
1886
1887        /* Move all/count SENT packet to the callers list (SENT->USER) */
1888        if (pkts) {
1889                if ((count == NULL) || (*count == -1) ||
1890                    (*count >= dma->sent_cnt)) {
1891                        /* Move all SENT Packets */
1892                        *pkts = dma->sent;
1893                        grspw_list_clr(&dma->sent);
1894                        if (count)
1895                                *count = dma->sent_cnt;
1896                        dma->sent_cnt = 0;
1897                } else {
1898                        /* Move a number of SENT Packets */
1899                        pkts->head = pkt = lastpkt = dma->sent.head;
1900                        cnt = 0;
1901                        while (cnt < *count) {
1902                                lastpkt = pkt;
1903                                pkt = pkt->next;
1904                                cnt++;
1905                        }
1906                        if (cnt > 0) {
1907                                pkts->tail = lastpkt;
1908                                grspw_list_remove_head_list(&dma->sent, pkts);
1909                                dma->sent_cnt -= cnt;
1910                        } else {
1911                                grspw_list_clr(pkts);
1912                        }
1913                }
1914        } else if (count) {
1915                *count = 0;
1916        }
1917
1918        /* 3. Schedule as many packets as possible (SEND->SCHED) */
1919        if ((started > 0) && ((opts & 2) == 0))
1920                grspw_tx_schedule_send(dma);
1921
1922        /* Unlock DMA channel */
1923        rtems_semaphore_release(dma->sem_txdma);
1924
1925        return (~started) & 1; /* signal DMA has been stopped */
1926}
1927
1928void grspw_dma_tx_count(void *c, int *send, int *sched, int *sent, int *hw)
1929{
1930        struct grspw_dma_priv *dma = c;
1931        int sched_cnt, diff;
1932        unsigned int hwbd;
1933        struct grspw_txbd *tailbd;
1934
1935        /* Take device lock - Wait until we get semaphore.
1936         * The lock is taken so that the counters are in sync with each other
1937         * and that DMA descriptor table and tx_ring_tail is not being updated
1938         * during HW counter processing in this function.
1939         */
1940        if (rtems_semaphore_obtain(dma->sem_txdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1941            != RTEMS_SUCCESSFUL)
1942                return;
1943
1944        if (send)
1945                *send = dma->send_cnt;
1946        sched_cnt = dma->tx_sched_cnt;
1947        if (sched)
1948                *sched = sched_cnt;
1949        if (sent)
1950                *sent = dma->sent_cnt;
1951        if (hw) {
1952                /* Calculate number of descriptors (processed by HW) between
1953                 * HW pointer and oldest SW pointer.
1954                 */
1955                hwbd = REG_READ(&dma->regs->txdesc);
1956                tailbd = dma->tx_ring_tail->bd;
1957                diff = ((hwbd - (unsigned int)tailbd) / GRSPW_TXBD_SIZE) &
1958                        (GRSPW_TXBD_NR - 1);
1959                /* Handle special case when HW and SW pointers are equal
1960                 * because all TX descriptors have been processed by HW.
1961                 */
1962                if ((diff == 0) && (sched_cnt == GRSPW_TXBD_NR) &&
1963                    ((BD_READ(&tailbd->ctrl) & GRSPW_TXBD_EN) == 0)) {
1964                        diff = GRSPW_TXBD_NR;
1965                }
1966                *hw = diff;
1967        }
1968
1969        /* Unlock DMA channel */
1970        rtems_semaphore_release(dma->sem_txdma);
1971}
1972
1973static inline int grspw_tx_wait_eval(struct grspw_dma_priv *dma)
1974{
1975        int send_val, sent_val;
1976
1977        if (dma->tx_wait.send_cnt >= (dma->send_cnt + dma->tx_sched_cnt))
1978                send_val = 1;
1979        else
1980                send_val = 0;
1981
1982        if (dma->tx_wait.sent_cnt <= dma->sent_cnt)
1983                sent_val = 1;
1984        else
1985                sent_val = 0;
1986
1987        /* AND or OR ? */
1988        if (dma->tx_wait.op == 0)
1989                return send_val & sent_val; /* AND */
1990        else
1991                return send_val | sent_val; /* OR */
1992}
1993
1994/* Block until send_cnt or fewer packets are Queued in "Send and Scheduled" Q,
1995 * op (AND or OR), sent_cnt or more packet "have been sent" (Sent Q) condition
1996 * is met.
1997 * If a link error occurs and the Stop on Link error is defined, this function
1998 * will also return to caller.
1999 */
2000int grspw_dma_tx_wait(void *c, int send_cnt, int op, int sent_cnt, int timeout)
2001{
2002        struct grspw_dma_priv *dma = c;
2003        int ret, rc, initialized = 0;
2004
2005        if (timeout == 0)
2006                timeout = RTEMS_NO_TIMEOUT;
2007
2008check_condition:
2009
2010        /* Take DMA channel lock */
2011        if (rtems_semaphore_obtain(dma->sem_txdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
2012            != RTEMS_SUCCESSFUL)
2013                return -1;
2014
2015        /* Check so that no other thread is waiting, this driver only supports
2016         * one waiter at a time.
2017         */
2018        if (initialized == 0 && dma->tx_wait.waiting) {
2019                ret = 3;
2020                goto out_release;
2021        }
2022
2023        /* Stop if link error or similar (DMA stopped), abort */
2024        if (dma->started == 0) {
2025                ret = 1;
2026                goto out_release;
2027        }
2028
2029        /* Set up Condition */
2030        dma->tx_wait.send_cnt = send_cnt;
2031        dma->tx_wait.op = op;
2032        dma->tx_wait.sent_cnt = sent_cnt;
2033
2034        if (grspw_tx_wait_eval(dma) == 0) {
2035                /* Prepare Wait */
2036                initialized = 1;
2037                dma->tx_wait.waiting = 1;
2038
2039                /* Release DMA channel lock */
2040                rtems_semaphore_release(dma->sem_txdma);
2041
2042                /* Try to take Wait lock, if this fail link may have gone down
2043                 * or user stopped this DMA channel
2044                 */
2045                rc = rtems_semaphore_obtain(dma->tx_wait.sem_wait, RTEMS_WAIT,
2046                                                timeout);
2047                if (rc == RTEMS_TIMEOUT) {
2048                        ret = 2;
2049                        goto out;
2050                } else if (rc == RTEMS_UNSATISFIED ||
2051                           rc == RTEMS_OBJECT_WAS_DELETED) {
2052                        ret = 1; /* sem was flushed/deleted, means DMA stop */
2053                        goto out;
2054                } else if (rc != RTEMS_SUCCESSFUL) {
2055                        /* Unknown Error */
2056                        ret = -1;
2057                        goto out;
2058                } else if (dma->started == 0) {
2059                        ret = 1;
2060                        goto out;
2061                }
2062
2063                /* Check condition once more */
2064                goto check_condition;
2065        }
2066
2067        ret = 0;
2068
2069out_release:
2070        /* Unlock DMA channel */
2071        rtems_semaphore_release(dma->sem_txdma);
2072
2073out:
2074        if (initialized)
2075                dma->tx_wait.waiting = 0;
2076        return ret;
2077}
2078
2079int grspw_dma_rx_recv(void *c, int opts, struct grspw_list *pkts, int *count)
2080{
2081        struct grspw_dma_priv *dma = c;
2082        struct grspw_pkt *pkt, *lastpkt;
2083        int cnt, started;
2084
2085        /* Take DMA channel lock */
2086        if (rtems_semaphore_obtain(dma->sem_rxdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
2087            != RTEMS_SUCCESSFUL)
2088                return -1;
2089
2090        /* 1. Move Scheduled packets to RECV List (SCHED->RECV) */
2091        started = dma->started;
2092        if (((opts & 1) == 0) && (started > 0))
2093                grspw_rx_process_scheduled(dma);
2094
2095        /* Move all RECV packet to the callers list */
2096        if (pkts) {
2097                if ((count == NULL) || (*count == -1) ||
2098                    (*count >= dma->recv_cnt)) {
2099                        /* Move all Received packets */
2100                        *pkts = dma->recv;
2101                        grspw_list_clr(&dma->recv);
2102                        if ( count )
2103                                *count = dma->recv_cnt;
2104                        dma->recv_cnt = 0;
2105                } else {
2106                        /* Move a number of RECV Packets */
2107                        pkts->head = pkt = lastpkt = dma->recv.head;
2108                        cnt = 0;
2109                        while (cnt < *count) {
2110                                lastpkt = pkt;
2111                                pkt = pkt->next;
2112                                cnt++;
2113                        }
2114                        if (cnt > 0) {
2115                                pkts->tail = lastpkt;
2116                                grspw_list_remove_head_list(&dma->recv, pkts);
2117                                dma->recv_cnt -= cnt;
2118                        } else {
2119                                grspw_list_clr(pkts);
2120                        }
2121                }
2122        } else if (count) {
2123                *count = 0;
2124        }
2125
2126        /* 3. Schedule as many free packet buffers as possible (READY->SCHED) */
2127        if (((opts & 2) == 0) && (started > 0))
2128                grspw_rx_schedule_ready(dma);
2129
2130        /* Unlock DMA channel */
2131        rtems_semaphore_release(dma->sem_rxdma);
2132
2133        return (~started) & 1;
2134}
2135
2136int grspw_dma_rx_prepare(void *c, int opts, struct grspw_list *pkts, int count)
2137{
2138        struct grspw_dma_priv *dma = c;
2139        int ret;
2140
2141        /* Take DMA channel lock */
2142        if (rtems_semaphore_obtain(dma->sem_rxdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
2143            != RTEMS_SUCCESSFUL)
2144                return -1;
2145
2146        if (dma->started == 0) {
2147                ret = 1;
2148                goto out;
2149        }
2150
2151        /* 1. Move Received packets to RECV List (SCHED->RECV) */
2152        if ((opts & 1) == 0)
2153                grspw_rx_process_scheduled(dma);
2154
2155        /* 2. Add the "free/ready" packet buffers to the READY List (USER->READY) */
2156        if (pkts && (count > 0)) {
2157                grspw_list_append_list(&dma->ready, pkts);
2158                dma->ready_cnt += count;
2159                if (dma->stats.ready_cnt_max < dma->ready_cnt)
2160                        dma->stats.ready_cnt_max = dma->ready_cnt;
2161        }
2162
2163        /* 3. Schedule as many packets as possible (READY->SCHED) */
2164        if ((opts & 2) == 0)
2165                grspw_rx_schedule_ready(dma);
2166
2167        ret = 0;
2168out:
2169        /* Unlock DMA channel */
2170        rtems_semaphore_release(dma->sem_rxdma);
2171
2172        return ret;
2173}
2174
2175void grspw_dma_rx_count(void *c, int *ready, int *sched, int *recv, int *hw)
2176{
2177        struct grspw_dma_priv *dma = c;
2178        int sched_cnt, diff;
2179        unsigned int hwbd;
2180        struct grspw_rxbd *tailbd;
2181
2182        /* Take device lock - Wait until we get semaphore.
2183         * The lock is taken so that the counters are in sync with each other
2184         * and that DMA descriptor table and rx_ring_tail is not being updated
2185         * during HW counter processing in this function.
2186         */
2187        if (rtems_semaphore_obtain(dma->sem_rxdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
2188            != RTEMS_SUCCESSFUL)
2189                return;
2190
2191        if (ready)
2192                *ready = dma->ready_cnt;
2193        sched_cnt = dma->rx_sched_cnt;
2194        if (sched)
2195                *sched = sched_cnt;
2196        if (recv)
2197                *recv = dma->recv_cnt;
2198        if (hw) {
2199                /* Calculate number of descriptors (processed by HW) between
2200                 * HW pointer and oldest SW pointer.
2201                 */
2202                hwbd = REG_READ(&dma->regs->rxdesc);
2203                tailbd = dma->rx_ring_tail->bd;
2204                diff = ((hwbd - (unsigned int)tailbd) / GRSPW_RXBD_SIZE) &
2205                        (GRSPW_RXBD_NR - 1);
2206                /* Handle special case when HW and SW pointers are equal
2207                 * because all RX descriptors have been processed by HW.
2208                 */
2209                if ((diff == 0) && (sched_cnt == GRSPW_RXBD_NR) &&
2210                    ((BD_READ(&tailbd->ctrl) & GRSPW_RXBD_EN) == 0)) {
2211                        diff = GRSPW_RXBD_NR;
2212                }
2213                *hw = diff;
2214        }
2215
2216        /* Unlock DMA channel */
2217        rtems_semaphore_release(dma->sem_rxdma);
2218}
2219
2220static inline int grspw_rx_wait_eval(struct grspw_dma_priv *dma)
2221{
2222        int ready_val, recv_val;
2223
2224        if (dma->rx_wait.ready_cnt >= (dma->ready_cnt + dma->rx_sched_cnt))
2225                ready_val = 1;
2226        else
2227                ready_val = 0;
2228
2229        if (dma->rx_wait.recv_cnt <= dma->recv_cnt)
2230                recv_val = 1;
2231        else
2232                recv_val = 0;
2233
2234        /* AND or OR ? */
2235        if (dma->rx_wait.op == 0)
2236                return ready_val & recv_val; /* AND */
2237        else
2238                return ready_val | recv_val; /* OR */
2239}
2240
2241/* Block until recv_cnt or more packets are Queued in RECV Q, op (AND or OR),
2242 * ready_cnt or fewer packet buffers are available in the "READY and Scheduled" Q,
2243 * condition is met.
2244 * If a link error occurs and the Stop on Link error is defined, this function
2245 * will also return to caller, however with an error.
2246 */
2247int grspw_dma_rx_wait(void *c, int recv_cnt, int op, int ready_cnt, int timeout)
2248{
2249        struct grspw_dma_priv *dma = c;
2250        int ret, rc, initialized = 0;
2251
2252        if (timeout == 0)
2253                timeout = RTEMS_NO_TIMEOUT;
2254
2255check_condition:
2256
2257        /* Take DMA channel lock */
2258        if (rtems_semaphore_obtain(dma->sem_rxdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
2259            != RTEMS_SUCCESSFUL)
2260                return -1;
2261
2262        /* Check so that no other thread is waiting, this driver only supports
2263         * one waiter at a time.
2264         */
2265        if (initialized == 0 && dma->rx_wait.waiting) {
2266                ret = 3;
2267                goto out_release;
2268        }
2269
2270        /* Stop if link error or similar (DMA stopped), abort */
2271        if (dma->started == 0) {
2272                ret = 1;
2273                goto out_release;
2274        }
2275
2276        /* Set up Condition */
2277        dma->rx_wait.recv_cnt = recv_cnt;
2278        dma->rx_wait.op = op;
2279        dma->rx_wait.ready_cnt = ready_cnt;
2280
2281        if (grspw_rx_wait_eval(dma) == 0) {
2282                /* Prepare Wait */
2283                initialized = 1;
2284                dma->rx_wait.waiting = 1;
2285
2286                /* Release channel lock */
2287                rtems_semaphore_release(dma->sem_rxdma);
2288
2289                /* Try to take Wait lock, if this fail link may have gone down
2290                 * or user stopped this DMA channel
2291                 */
2292                rc = rtems_semaphore_obtain(dma->rx_wait.sem_wait, RTEMS_WAIT,
2293                                           timeout);
2294                if (rc == RTEMS_TIMEOUT) {
2295                        ret = 2;
2296                        goto out;
2297                } else if (rc == RTEMS_UNSATISFIED ||
2298                           rc == RTEMS_OBJECT_WAS_DELETED) {
2299                        ret = 1; /* sem was flushed/deleted, means DMA stop */
2300                        goto out;
2301                } else if (rc != RTEMS_SUCCESSFUL) {
2302                        /* Unknown Error */
2303                        ret = -1;
2304                        goto out;
2305                } else if (dma->started == 0) {
2306                        ret = 1;
2307                        goto out;
2308                }
2309
2310                /* Check condition once more */
2311                goto check_condition;
2312        }
2313
2314        ret = 0;
2315
2316out_release:
2317        /* Unlock DMA channel */
2318        rtems_semaphore_release(dma->sem_rxdma);
2319
2320out:
2321        if (initialized)
2322                dma->rx_wait.waiting = 0;
2323        return ret;
2324}
2325
2326int grspw_dma_config(void *c, struct grspw_dma_config *cfg)
2327{
2328        struct grspw_dma_priv *dma = c;
2329
2330        if (dma->started || !cfg)
2331                return -1;
2332
2333        if (cfg->flags & ~(DMAFLAG_MASK | DMAFLAG2_MASK))
2334                return -1;
2335
2336        /* Update Configuration */
2337        memcpy(&dma->cfg, cfg, sizeof(*cfg));
2338
2339        return 0;
2340}
2341
2342void grspw_dma_config_read(void *c, struct grspw_dma_config *cfg)
2343{
2344        struct grspw_dma_priv *dma = c;
2345
2346        /* Copy Current Configuration */
2347        memcpy(cfg, &dma->cfg, sizeof(*cfg));
2348}
2349
2350void grspw_dma_stats_read(void *c, struct grspw_dma_stats *sts)
2351{
2352        struct grspw_dma_priv *dma = c;
2353
2354        memcpy(sts, &dma->stats, sizeof(dma->stats));
2355}
2356
2357void grspw_dma_stats_clr(void *c)
2358{
2359        struct grspw_dma_priv *dma = c;
2360
2361        /* Clear most of the statistics */     
2362        memset(&dma->stats, 0, sizeof(dma->stats));
2363
2364        /* Init proper default values so that comparisons will work the
2365         * first time.
2366         */
2367        dma->stats.send_cnt_min = 0x3fffffff;
2368        dma->stats.tx_sched_cnt_min = 0x3fffffff;
2369        dma->stats.ready_cnt_min = 0x3fffffff;
2370        dma->stats.rx_sched_cnt_min = 0x3fffffff;
2371}
2372
2373int grspw_dma_start(void *c)
2374{
2375        struct grspw_dma_priv *dma = c;
2376        struct grspw_dma_regs *dregs = dma->regs;
2377        unsigned int ctrl;
2378        IRQFLAGS_TYPE irqflags;
2379
2380        if (dma->started)
2381                return 0;
2382
2383        /* Initialize Software Structures:
2384         *  - Clear all Queues
2385         *  - init BD ring
2386         *  - init IRQ counter
2387         *  - clear statistics counters
2388         *  - init wait structures and semaphores
2389         */
2390        grspw_dma_reset(dma);
2391
2392        /* RX&RD and TX is not enabled until user fills SEND and READY Queue
2393         * with SpaceWire Packet buffers. So we do not have to worry about
2394         * IRQs for this channel just yet. However other DMA channels
2395         * may be active.
2396         *
2397         * Some functionality that is not changed during started mode is set up
2398         * once and for all here:
2399         *
2400         *   - RX MAX Packet length
2401         *   - TX Descriptor base address to first BD in TX ring (not enabled)
2402         *   - RX Descriptor base address to first BD in RX ring (not enabled)
2403         *   - IRQs (TX DMA, RX DMA, DMA ERROR)
2404         *   - Strip PID
2405         *   - Strip Address
2406         *   - No Spill
2407         *   - Receiver Enable
2408         *   - disable on link error (LE)
2409         *
2410         * Note that the address register and the address enable bit in DMACTRL
2411         * register must be left untouched, they are configured on a GRSPW
2412         * core level.
2413         *
2414         * Note that the receiver is enabled here, but since descriptors are
2415         * not enabled the GRSPW core may stop/pause RX (if NS bit set) until
2416         * descriptors are enabled or it may ignore RX packets (NS=0) until
2417         * descriptors are enabled (writing RD bit).
2418         */
2419        REG_WRITE(&dregs->txdesc, dma->tx_bds_hwa);
2420        REG_WRITE(&dregs->rxdesc, dma->rx_bds_hwa);
2421
2422        /* MAX Packet length */
2423        REG_WRITE(&dma->regs->rxmax, dma->cfg.rxmaxlen);
2424
2425        ctrl =  GRSPW_DMACTRL_AI | GRSPW_DMACTRL_PS | GRSPW_DMACTRL_PR |
2426                GRSPW_DMACTRL_TA | GRSPW_DMACTRL_RA | GRSPW_DMACTRL_RE |
2427                (dma->cfg.flags & DMAFLAG_MASK) << GRSPW_DMACTRL_NS_BIT;
2428        if (dma->core->dis_link_on_err & LINKOPTS_DIS_ONERR)
2429                ctrl |= GRSPW_DMACTRL_LE;
2430        if (dma->cfg.rx_irq_en_cnt != 0 || dma->cfg.flags & DMAFLAG2_RXIE)
2431                ctrl |= GRSPW_DMACTRL_RI;
2432        if (dma->cfg.tx_irq_en_cnt != 0 || dma->cfg.flags & DMAFLAG2_TXIE)
2433                ctrl |= GRSPW_DMACTRL_TI;
2434        SPIN_LOCK_IRQ(&dma->core->devlock, irqflags);
2435        ctrl |= REG_READ(&dma->regs->ctrl) & GRSPW_DMACTRL_EN;
2436        REG_WRITE(&dregs->ctrl, ctrl);
2437        SPIN_UNLOCK_IRQ(&dma->core->devlock, irqflags);
2438
2439        dma->started = 1; /* open up other DMA interfaces */
2440
2441        return 0;
2442}
2443
2444STATIC void grspw_dma_stop_locked(struct grspw_dma_priv *dma)
2445{
2446        IRQFLAGS_TYPE irqflags;
2447
2448        if (dma->started == 0)
2449                return;
2450        dma->started = 0;
2451
2452        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
2453        grspw_hw_dma_stop(dma);
2454        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
2455
2456        /* From here no more packets will be sent, however
2457         * there may still exist scheduled packets that has been
2458         * sent, and packets in the SEND Queue waiting for free
2459         * descriptors. All packets are moved to the SENT Queue
2460         * so that the user may get its buffers back, the user
2461         * must look at the TXPKT_FLAG_TX in order to determine
2462         * if the packet was sent or not.
2463         */
2464
2465        /* Retreive scheduled all sent packets */
2466        grspw_tx_process_scheduled(dma);
2467
2468        /* Move un-sent packets in SEND and SCHED queue to the
2469         * SENT Queue. (never marked sent)
2470         */
2471        if (!grspw_list_is_empty(&dma->tx_sched)) {
2472                grspw_list_append_list(&dma->sent, &dma->tx_sched);
2473                grspw_list_clr(&dma->tx_sched);
2474                dma->sent_cnt += dma->tx_sched_cnt;
2475                dma->tx_sched_cnt = 0;
2476        }
2477        if (!grspw_list_is_empty(&dma->send)) {
2478                grspw_list_append_list(&dma->sent, &dma->send);
2479                grspw_list_clr(&dma->send);
2480                dma->sent_cnt += dma->send_cnt;
2481                dma->send_cnt = 0;
2482        }
2483
2484        /* Similar for RX */
2485        grspw_rx_process_scheduled(dma);
2486        if (!grspw_list_is_empty(&dma->rx_sched)) {
2487                grspw_list_append_list(&dma->recv, &dma->rx_sched);
2488                grspw_list_clr(&dma->rx_sched);
2489                dma->recv_cnt += dma->rx_sched_cnt;
2490                dma->rx_sched_cnt = 0;
2491        }
2492        if (!grspw_list_is_empty(&dma->ready)) {
2493                grspw_list_append_list(&dma->recv, &dma->ready);
2494                grspw_list_clr(&dma->ready);
2495                dma->recv_cnt += dma->ready_cnt;
2496                dma->ready_cnt = 0;
2497        }
2498
2499        /* Throw out blocked threads */
2500        rtems_semaphore_flush(dma->rx_wait.sem_wait);
2501        rtems_semaphore_flush(dma->tx_wait.sem_wait);
2502}
2503
2504void grspw_dma_stop(void *c)
2505{
2506        struct grspw_dma_priv *dma = c;
2507
2508        /* If DMA channel is closed we should not access the semaphore */
2509        if (!dma->open)
2510                return;
2511
2512        /* Take DMA Channel lock */
2513        if (rtems_semaphore_obtain(dma->sem_rxdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
2514            != RTEMS_SUCCESSFUL)
2515                return;
2516        if (rtems_semaphore_obtain(dma->sem_txdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
2517            != RTEMS_SUCCESSFUL) {
2518                rtems_semaphore_release(dma->sem_rxdma);
2519                return;
2520        }
2521
2522        grspw_dma_stop_locked(dma);
2523
2524        rtems_semaphore_release(dma->sem_txdma);
2525        rtems_semaphore_release(dma->sem_rxdma);
2526}
2527
2528/* Do general work, invoked indirectly from ISR */
2529static void grspw_work_shutdown_func(struct grspw_priv *priv)
2530{
2531        int i;
2532
2533        /* Link is down for some reason, and the user has configured
2534         * that we stop all (open) DMA channels and throw out all their
2535         * blocked threads.
2536         */
2537        for (i=0; i<priv->hwsup.ndma_chans; i++)
2538                grspw_dma_stop(&priv->dma[i]);
2539        grspw_hw_stop(priv);
2540}
2541
2542/* Do DMA work on one channel, invoked indirectly from ISR */
2543static void grspw_work_dma_func(struct grspw_dma_priv *dma, unsigned int msg)
2544{
2545        int tx_cond_true, rx_cond_true;
2546        unsigned int ctrl;
2547        IRQFLAGS_TYPE irqflags;
2548
2549        /* If DMA channel is closed we should not access the semaphore */
2550        if (dma->open == 0)
2551                return;
2552
2553        rx_cond_true = 0;
2554        tx_cond_true = 0;
2555        dma->stats.irq_cnt++;
2556
2557        /* Look at cause we were woken up and clear source */
2558        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
2559        if (dma->started == 0) {
2560                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
2561                return;
2562        }
2563        ctrl = REG_READ(&dma->regs->ctrl);
2564
2565        /* Read/Write DMA error ? */
2566        if (ctrl & GRSPW_DMA_STATUS_ERROR) {
2567                /* DMA error -> Stop DMA channel (both RX and TX) */
2568                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
2569                if (msg & WORK_DMA_ER_MASK) {
2570                        /* DMA error and user wants work-task to handle error */
2571                        grspw_dma_stop(dma);
2572                        grspw_work_event(WORKTASK_EV_DMA_STOP, msg);
2573                }
2574        } else if (((msg & WORK_DMA_RX_MASK) && (ctrl & GRSPW_DMACTRL_PR)) ||
2575                   ((msg & WORK_DMA_TX_MASK) && (ctrl & GRSPW_DMACTRL_PS))) {
2576                /* DMA has finished a TX/RX packet and user wants work-task to
2577                 * take care of DMA table processing.
2578                 */
2579                ctrl &= ~GRSPW_DMACTRL_AT;
2580
2581                if ((msg & WORK_DMA_RX_MASK) == 0)
2582                        ctrl &= ~GRSPW_DMACTRL_PR;
2583                else if (dma->cfg.rx_irq_en_cnt != 0 ||
2584                         (dma->cfg.flags & DMAFLAG2_RXIE))
2585                        ctrl |= GRSPW_DMACTRL_RI;
2586                if ((msg & WORK_DMA_TX_MASK) == 0)
2587                        ctrl &= ~GRSPW_DMACTRL_PS;
2588                else if ((dma->cfg.tx_irq_en_cnt != 0 ||
2589                         (dma->cfg.flags & DMAFLAG2_TXIE)))
2590                        ctrl |= GRSPW_DMACTRL_TI;
2591
2592                REG_WRITE(&dma->regs->ctrl, ctrl);
2593                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
2594                if ((msg & WORK_DMA_RX_MASK) && (ctrl & GRSPW_DMACTRL_PR)) {
2595                        /* Do RX Work */
2596
2597                        /* Take DMA channel RX lock */
2598                        if (rtems_semaphore_obtain(dma->sem_rxdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
2599                            != RTEMS_SUCCESSFUL)
2600                                return;
2601
2602                        dma->stats.rx_work_cnt++;
2603                        grspw_rx_process_scheduled(dma);
2604                        if (dma->started) {
2605                                dma->stats.rx_work_enabled +=
2606                                        grspw_rx_schedule_ready(dma);
2607                                /* Check to see if condition for waking blocked
2608                                 * USER task is fullfilled.
2609                                 */
2610                                if (dma->rx_wait.waiting)
2611                                        rx_cond_true = grspw_rx_wait_eval(dma);
2612                        }
2613                        rtems_semaphore_release(dma->sem_rxdma);
2614                }
2615                if ((msg & WORK_DMA_TX_MASK) && (ctrl & GRSPW_DMACTRL_PS)) {
2616                        /* Do TX Work */
2617
2618                        /* Take DMA channel TX lock */
2619                        if (rtems_semaphore_obtain(dma->sem_txdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
2620                            != RTEMS_SUCCESSFUL)
2621                                return;
2622
2623                        dma->stats.tx_work_cnt++;
2624                        grspw_tx_process_scheduled(dma);
2625                        if (dma->started) {
2626                                dma->stats.tx_work_enabled +=
2627                                        grspw_tx_schedule_send(dma);
2628                                /* Check to see if condition for waking blocked
2629                                 * USER task is fullfilled.
2630                                 */
2631                                if (dma->tx_wait.waiting)
2632                                        tx_cond_true = grspw_tx_wait_eval(dma);
2633                        }
2634                        rtems_semaphore_release(dma->sem_txdma);
2635                }
2636        } else
2637                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
2638
2639        if (rx_cond_true)
2640                rtems_semaphore_release(dma->rx_wait.sem_wait);
2641
2642        if (tx_cond_true)
2643                rtems_semaphore_release(dma->tx_wait.sem_wait);
2644}
2645
2646/* Work task is receiving work for the work message queue posted from
2647 * the ISR.
2648 */
2649void grspw_work_func(rtems_id msgQ)
2650{
2651        unsigned int message = 0, msg;
2652        size_t size;
2653        struct grspw_priv *priv;
2654        int i;
2655
2656        /* Wait for ISR to schedule work */
2657        while (rtems_message_queue_receive(msgQ, &message, &size,
2658               RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL) {
2659                if (message & WORK_QUIT_TASK)
2660                        break;
2661
2662                /* Handle work */
2663                priv = priv_tab[message >> WORK_CORE_BIT];
2664                if (message & WORK_SHUTDOWN) {
2665                        grspw_work_shutdown_func(priv);
2666                               
2667                        grspw_work_event(WORKTASK_EV_SHUTDOWN, message);
2668                } else if (message & WORK_DMA_MASK) {
2669                        for (i = 0; i < priv->hwsup.ndma_chans; i++) {
2670                                msg = message &
2671                                      (WORK_CORE_MASK | WORK_DMA_CHAN_MASK(i));
2672                                if (msg)
2673                                        grspw_work_dma_func(&priv->dma[i], msg);
2674                        }
2675                }
2676                message = 0;
2677        }
2678
2679        if (message & WORK_FREE_MSGQ)
2680                rtems_message_queue_delete(msgQ);
2681
2682        grspw_work_event(WORKTASK_EV_QUIT, message);
2683        rtems_task_delete(RTEMS_SELF);
2684}
2685
2686STATIC void grspw_isr(void *data)
2687{
2688        struct grspw_priv *priv = data;
2689        unsigned int dma_stat, stat, stat_clrmsk, ctrl, icctrl, timecode, irqs;
2690        unsigned int rxirq, rxack, intto;
2691        int i, handled = 0, call_user_int_isr;
2692        unsigned int message = WORK_NONE;
2693#ifdef RTEMS_HAS_SMP
2694        IRQFLAGS_TYPE irqflags;
2695#endif
2696
2697        /* Get Status from Hardware */
2698        stat = REG_READ(&priv->regs->status);
2699        stat_clrmsk = stat & (GRSPW_STS_TO | GRSPW_STAT_ERROR) &
2700                        (GRSPW_STS_TO | priv->stscfg);
2701
2702        /* Make sure to put the timecode handling first in order to get the
2703         * smallest possible interrupt latency
2704         */
2705        if ((stat & GRSPW_STS_TO) && (priv->tcisr != NULL)) {
2706                ctrl = REG_READ(&priv->regs->ctrl);
2707                if (ctrl & GRSPW_CTRL_TQ) {
2708                        /* Timecode received. Let custom function handle this */
2709                        timecode = REG_READ(&priv->regs->time) &
2710                                        (GRSPW_TIME_CTRL | GRSPW_TIME_TCNT);
2711                        (priv->tcisr)(priv->tcisr_arg, timecode);
2712                }
2713        }
2714
2715        /* Get Interrupt status from hardware */
2716        icctrl = REG_READ(&priv->regs->icctrl);
2717        if ((icctrl & GRSPW_ICCTRL_IRQSRC_MASK) && (priv->icisr != NULL)) {
2718                call_user_int_isr = 0;
2719                rxirq = rxack = intto = 0;
2720
2721                if ((icctrl & GRSPW_ICCTRL_IQ) &&
2722                    (rxirq = REG_READ(&priv->regs->icrx)) != 0)
2723                        call_user_int_isr = 1;
2724
2725                if ((icctrl & GRSPW_ICCTRL_AQ) &&
2726                    (rxack = REG_READ(&priv->regs->icack)) != 0)
2727                        call_user_int_isr = 1;
2728
2729                if ((icctrl & GRSPW_ICCTRL_TQ) &&
2730                    (intto = REG_READ(&priv->regs->ictimeout)) != 0)
2731                        call_user_int_isr = 1;                 
2732
2733                /* Let custom functions handle this POTENTIAL SPW interrupt. The
2734                 * user function is called even if no such IRQ has happened!
2735                 * User must make sure to clear all interrupts that have been
2736                 * handled from the three registers by writing a one.
2737                 */
2738                if (call_user_int_isr)
2739                        priv->icisr(priv->icisr_arg, rxirq, rxack, intto);
2740        }
2741
2742        /* An Error occured? */
2743        if (stat & GRSPW_STAT_ERROR) {
2744                /* Wake Global WorkQ */
2745                handled = 1;
2746
2747                if (stat & GRSPW_STS_EE)
2748                        priv->stats.err_eeop++;
2749
2750                if (stat & GRSPW_STS_IA)
2751                        priv->stats.err_addr++;
2752
2753                if (stat & GRSPW_STS_PE)
2754                        priv->stats.err_parity++;
2755
2756                if (stat & GRSPW_STS_DE)
2757                        priv->stats.err_disconnect++;
2758
2759                if (stat & GRSPW_STS_ER)
2760                        priv->stats.err_escape++;
2761
2762                if (stat & GRSPW_STS_CE)
2763                        priv->stats.err_credit++;
2764
2765                if (stat & GRSPW_STS_WE)
2766                        priv->stats.err_wsync++;
2767
2768                if ((priv->dis_link_on_err >> 16) & stat) {
2769                        /* Disable the link, no more transfers are expected
2770                         * on any DMA channel.
2771                         */
2772                        SPIN_LOCK(&priv->devlock, irqflags);
2773                        ctrl = REG_READ(&priv->regs->ctrl);
2774                        REG_WRITE(&priv->regs->ctrl, GRSPW_CTRL_LD |
2775                                (ctrl & ~(GRSPW_CTRL_IE|GRSPW_CTRL_LS)));
2776                        SPIN_UNLOCK(&priv->devlock, irqflags);
2777                        /* Signal to work-thread to stop DMA and clean up */
2778                        message = WORK_SHUTDOWN;
2779                }
2780        }
2781
2782        /* Clear Status Flags */
2783        if (stat_clrmsk) {
2784                handled = 1;
2785                REG_WRITE(&priv->regs->status, stat_clrmsk);
2786        }
2787
2788        /* A DMA transfer or Error occured? In that case disable more IRQs
2789         * from the DMA channel, then invoke the workQ.
2790         *
2791         * Also the GI interrupt flag may not be available for older
2792         * designs where (was added together with mutiple DMA channels).
2793         */
2794        SPIN_LOCK(&priv->devlock, irqflags);
2795        for (i=0; i<priv->hwsup.ndma_chans; i++) {
2796                dma_stat = REG_READ(&priv->regs->dma[i].ctrl);
2797                /* Check for Errors and if Packets been sent or received if
2798                 * respective IRQ are enabled
2799                 */
2800                irqs = (((dma_stat << 3) & (GRSPW_DMACTRL_PR | GRSPW_DMACTRL_PS))
2801                        | GRSPW_DMA_STATUS_ERROR) & dma_stat;
2802                if (!irqs)
2803                        continue;
2804
2805                /* Disable Further IRQs (until enabled again)
2806                 * from this DMA channel. Let the status
2807                 * bit remain so that they can be handled by
2808                 * work function.
2809                 */
2810                REG_WRITE(&priv->regs->dma[i].ctrl, dma_stat & 
2811                        ~(GRSPW_DMACTRL_RI|GRSPW_DMACTRL_TI|
2812                        GRSPW_DMACTRL_PR|GRSPW_DMACTRL_PS|
2813                        GRSPW_DMACTRL_RA|GRSPW_DMACTRL_TA|
2814                        GRSPW_DMACTRL_AT));
2815                handled = 1;
2816
2817                /* DMA error has priority, if error happens it is assumed that
2818                 * the common work-queue stops the DMA operation for that
2819                 * channel and makes the DMA tasks exit from their waiting
2820                 * functions (both RX and TX tasks).
2821                 */
2822                if (irqs & GRSPW_DMA_STATUS_ERROR) {
2823                        message |= WORK_DMA_ER(i);
2824                } else {
2825                        message |= WORK_DMA(i, irqs >> GRSPW_DMACTRL_PS_BIT);
2826                }
2827        }
2828        SPIN_UNLOCK(&priv->devlock, irqflags);
2829
2830        if (handled != 0)
2831                priv->stats.irq_cnt++;
2832
2833        /* Schedule work by sending message to work thread */
2834        if (message != WORK_NONE && priv->wc.msgisr) {
2835                int status;
2836                message |= WORK_CORE(priv->index);
2837                /* func interface compatible with msgQSend() on purpose, but
2838                 * at the same time the user can assign a custom function to
2839                 * handle DMA RX/TX operations as indicated by the "message"
2840                 * and clear the handled bits before given to msgQSend().
2841                 */
2842                status = priv->wc.msgisr(priv->wc.msgisr_arg, &message, 4);
2843                if (status != RTEMS_SUCCESSFUL) {
2844                        printk("grspw_isr(%d): message fail %d (0x%x)\n",
2845                                priv->index, status, message);
2846                }
2847        }
2848}
2849
2850STATIC void grspw_hw_dma_stop(struct grspw_dma_priv *dma)
2851{
2852        unsigned int ctrl;
2853        struct grspw_dma_regs *dregs = dma->regs;
2854
2855        ctrl = REG_READ(&dregs->ctrl) & (GRSPW_DMACTRL_LE | GRSPW_DMACTRL_EN |
2856               GRSPW_DMACTRL_SP | GRSPW_DMACTRL_SA | GRSPW_DMACTRL_NS);
2857        ctrl |= GRSPW_DMACTRL_AT;
2858        REG_WRITE(&dregs->ctrl, ctrl);
2859}
2860
2861STATIC void grspw_hw_dma_softreset(struct grspw_dma_priv *dma)
2862{
2863        unsigned int ctrl;
2864        struct grspw_dma_regs *dregs = dma->regs;
2865
2866        ctrl = REG_READ(&dregs->ctrl) & (GRSPW_DMACTRL_LE | GRSPW_DMACTRL_EN);
2867        REG_WRITE(&dregs->ctrl, ctrl);
2868
2869        REG_WRITE(&dregs->rxmax, DEFAULT_RXMAX);
2870        REG_WRITE(&dregs->txdesc, 0);
2871        REG_WRITE(&dregs->rxdesc, 0);
2872}
2873
2874/* Hardware Action:
2875 *  - stop DMA
2876 *  - do not bring down the link (RMAP may be active)
2877 *  - RMAP settings untouched (RMAP may be active)
2878 *  - port select untouched (RMAP may be active)
2879 *  - timecodes are disabled
2880 *  - IRQ generation disabled
2881 *  - status not cleared (let user analyze it if requested later on)
2882 *  - Node address / First DMA channels Node address
2883 *    is untouched (RMAP may be active)
2884 */
2885STATIC void grspw_hw_stop(struct grspw_priv *priv)
2886{
2887        int i;
2888        unsigned int ctrl;
2889        IRQFLAGS_TYPE irqflags;
2890
2891        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
2892
2893        for (i=0; i<priv->hwsup.ndma_chans; i++)
2894                grspw_hw_dma_stop(&priv->dma[i]);
2895
2896        ctrl = REG_READ(&priv->regs->ctrl);
2897        REG_WRITE(&priv->regs->ctrl, ctrl & (
2898                GRSPW_CTRL_LD | GRSPW_CTRL_LS | GRSPW_CTRL_AS |
2899                GRSPW_CTRL_RE | GRSPW_CTRL_RD |
2900                GRSPW_CTRL_NP | GRSPW_CTRL_PS));
2901
2902        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
2903}
2904
2905/* Soft reset of GRSPW core registers */
2906STATIC void grspw_hw_softreset(struct grspw_priv *priv)
2907{
2908        int i;
2909        unsigned int tmp;
2910
2911        for (i=0; i<priv->hwsup.ndma_chans; i++)
2912                grspw_hw_dma_softreset(&priv->dma[i]);
2913
2914        REG_WRITE(&priv->regs->status, 0xffffffff);
2915        REG_WRITE(&priv->regs->time, 0);
2916        /* Clear all but valuable reset values of ICCTRL */
2917        tmp = REG_READ(&priv->regs->icctrl);
2918        tmp &= GRSPW_ICCTRL_INUM | GRSPW_ICCTRL_BIRQ | GRSPW_ICCTRL_TXIRQ;
2919        tmp |= GRSPW_ICCTRL_ID;
2920        REG_WRITE(&priv->regs->icctrl, tmp);
2921        REG_WRITE(&priv->regs->icrx, 0xffffffff);
2922        REG_WRITE(&priv->regs->icack, 0xffffffff);
2923        REG_WRITE(&priv->regs->ictimeout, 0xffffffff);
2924}
2925
2926int grspw_dev_count(void)
2927{
2928        return grspw_count;
2929}
2930
2931void grspw_initialize_user(void *(*devfound)(int), void (*devremove)(int,void*))
2932{
2933        int i;
2934        struct grspw_priv *priv;
2935
2936        /* Set new Device Found Handler */
2937        grspw_dev_add = devfound;
2938        grspw_dev_del = devremove;
2939
2940        if (grspw_initialized == 1 && grspw_dev_add) {
2941                /* Call callback for every previously found device */
2942                for (i=0; i<grspw_count; i++) {
2943                        priv = priv_tab[i];
2944                        if (priv)
2945                                priv->data = grspw_dev_add(i);
2946                }
2947        }
2948}
2949
2950/******************* Driver manager interface ***********************/
2951
2952/* Driver prototypes */
2953static int grspw_common_init(void);
2954static int grspw2_init3(struct drvmgr_dev *dev);
2955
2956static struct drvmgr_drv_ops grspw2_ops =
2957{
2958        .init = {NULL,  NULL, grspw2_init3, NULL},
2959        .remove = NULL,
2960        .info = NULL
2961};
2962
2963static struct amba_dev_id grspw2_ids[] =
2964{
2965        {VENDOR_GAISLER, GAISLER_SPW}, /* not yet supported */
2966        {VENDOR_GAISLER, GAISLER_SPW2},
2967        {VENDOR_GAISLER, GAISLER_SPW2_DMA},
2968        {0, 0}          /* Mark end of table */
2969};
2970
2971static struct amba_drv_info grspw2_drv_info =
2972{
2973        {
2974                DRVMGR_OBJ_DRV,                 /* Driver */
2975                NULL,                           /* Next driver */
2976                NULL,                           /* Device list */
2977                DRIVER_AMBAPP_GAISLER_GRSPW2_ID,/* Driver ID */
2978                "GRSPW_PKT_DRV",                /* Driver Name */
2979                DRVMGR_BUS_TYPE_AMBAPP,         /* Bus Type */
2980                &grspw2_ops,
2981                NULL,                           /* Funcs */
2982                0,                              /* No devices yet */
2983                sizeof(struct grspw_priv),      /* Let DrvMgr alloc priv */
2984        },
2985        &grspw2_ids[0]
2986};
2987
2988void grspw2_register_drv (void)
2989{
2990        GRSPW_DBG("Registering GRSPW2 packet driver\n");
2991        drvmgr_drv_register(&grspw2_drv_info.general);
2992}
2993
2994static int grspw2_init3(struct drvmgr_dev *dev)
2995{
2996        struct grspw_priv *priv;
2997        struct amba_dev_info *ambadev;
2998        struct ambapp_core *pnpinfo;
2999        int i, size;
3000        unsigned int ctrl, icctrl, numi;
3001        union drvmgr_key_value *value;
3002
3003        GRSPW_DBG("GRSPW[%d] on bus %s\n", dev->minor_drv,
3004                dev->parent->dev->name);
3005
3006        if (grspw_count > GRSPW_MAX)
3007                return DRVMGR_ENORES;
3008
3009        priv = dev->priv;
3010        if (priv == NULL)
3011                return DRVMGR_NOMEM;
3012        priv->dev = dev;
3013
3014        /* If first device init common part of driver */
3015        if (grspw_common_init())
3016                return DRVMGR_FAIL;
3017
3018        /*** Now we take care of device initialization ***/
3019
3020        /* Get device information from AMBA PnP information */
3021        ambadev = (struct amba_dev_info *)dev->businfo;
3022        if (ambadev == NULL)
3023                return -1;
3024        pnpinfo = &ambadev->info;
3025        priv->irq = pnpinfo->irq;
3026        priv->regs = (struct grspw_regs *)pnpinfo->apb_slv->start;
3027
3028        /* Read Hardware Support from Control Register */
3029        ctrl = REG_READ(&priv->regs->ctrl);
3030        priv->hwsup.rmap = (ctrl & GRSPW_CTRL_RA) >> GRSPW_CTRL_RA_BIT;
3031        priv->hwsup.rmap_crc = (ctrl & GRSPW_CTRL_RC) >> GRSPW_CTRL_RC_BIT;
3032        priv->hwsup.rx_unalign = (ctrl & GRSPW_CTRL_RX) >> GRSPW_CTRL_RX_BIT;
3033        priv->hwsup.nports = 1 + ((ctrl & GRSPW_CTRL_PO) >> GRSPW_CTRL_PO_BIT);
3034        priv->hwsup.ndma_chans = 1 + ((ctrl & GRSPW_CTRL_NCH) >> GRSPW_CTRL_NCH_BIT);
3035        priv->hwsup.irq = ((ctrl & GRSPW_CTRL_ID) >> GRSPW_CTRL_ID_BIT);
3036        icctrl = REG_READ(&priv->regs->icctrl);
3037        numi = (icctrl & GRSPW_ICCTRL_NUMI) >> GRSPW_ICCTRL_NUMI_BIT;
3038        if (numi > 0)
3039                priv->hwsup.irq_num = 1 << (numi - 1);
3040        else 
3041                priv->hwsup.irq_num = 0;
3042
3043        /* Construct hardware version identification */
3044        priv->hwsup.hw_version = pnpinfo->device << 16 | pnpinfo->apb_slv->ver;
3045
3046        if ((pnpinfo->device == GAISLER_SPW2) ||
3047            (pnpinfo->device == GAISLER_SPW2_DMA)) {
3048                priv->hwsup.strip_adr = 1; /* All GRSPW2 can strip Address */
3049                priv->hwsup.strip_pid = 1; /* All GRSPW2 can strip PID */
3050        } else {
3051                /* Autodetect GRSPW1 features? */
3052                priv->hwsup.strip_adr = 0;
3053                priv->hwsup.strip_pid = 0;
3054        }
3055
3056        /* Probe width of SpaceWire Interrupt ISR timers. All have the same
3057         * width... so only the first is probed, if no timer result will be
3058         * zero.
3059         */
3060        REG_WRITE(&priv->regs->icrlpresc, 0x7fffffff);
3061        ctrl = REG_READ(&priv->regs->icrlpresc);
3062        REG_WRITE(&priv->regs->icrlpresc, 0);
3063        priv->hwsup.itmr_width = 0;
3064        while (ctrl & 1) {
3065                priv->hwsup.itmr_width++;
3066                ctrl = ctrl >> 1;
3067        }
3068
3069        /* Let user limit the number of DMA channels on this core to save
3070         * space. Only the first nDMA channels will be available.
3071         */
3072        value = drvmgr_dev_key_get(priv->dev, "nDMA", DRVMGR_KT_INT);
3073        if (value && (value->i < priv->hwsup.ndma_chans))
3074                priv->hwsup.ndma_chans = value->i;
3075
3076        /* Allocate and init Memory for all DMA channels */
3077        size = sizeof(struct grspw_dma_priv) * priv->hwsup.ndma_chans;
3078        priv->dma = (struct grspw_dma_priv *) malloc(size);
3079        if (priv->dma == NULL)
3080                return DRVMGR_NOMEM;
3081        memset(priv->dma, 0, size);
3082        for (i=0; i<priv->hwsup.ndma_chans; i++) {
3083                priv->dma[i].core = priv;
3084                priv->dma[i].index = i;
3085                priv->dma[i].regs = &priv->regs->dma[i];
3086        }
3087
3088        /* Startup Action:
3089         *  - stop DMA
3090         *  - do not bring down the link (RMAP may be active)
3091         *  - RMAP settings untouched (RMAP may be active)
3092         *  - port select untouched (RMAP may be active)
3093         *  - timecodes are diabled
3094         *  - IRQ generation disabled
3095         *  - status cleared
3096         *  - Node address / First DMA channels Node address
3097         *    is untouched (RMAP may be active)
3098         */
3099        grspw_hw_stop(priv);
3100        grspw_hw_softreset(priv);
3101
3102        /* Register character device in registered region */
3103        priv->index = grspw_count;
3104        priv_tab[priv->index] = priv;
3105        grspw_count++;
3106
3107        /* Device name */
3108        sprintf(priv->devname, "grspw%d", priv->index);
3109
3110        /* Tell above layer about new device */
3111        if (grspw_dev_add)
3112                priv->data = grspw_dev_add(priv->index);
3113
3114        return DRVMGR_OK;
3115}
3116
3117/******************* Driver Implementation ***********************/
3118/* Creates a MsgQ (optional) and spawns a worker task associated with the
3119 * message Q. The task can also be associated with a custom msgQ if *msgQ.
3120 * is non-zero.
3121 */
3122rtems_id grspw_work_spawn(int prio, int stack, rtems_id *pMsgQ, int msgMax)
3123{
3124        rtems_id tid;
3125        int created_msgq = 0;
3126
3127        if (pMsgQ == NULL)
3128                return OBJECTS_ID_NONE;
3129
3130        if (*pMsgQ == OBJECTS_ID_NONE) {
3131                if (msgMax <= 0)
3132                        msgMax = 32;
3133
3134                if (rtems_message_queue_create(
3135                        rtems_build_name('S', 'G', 'L', 'Q'),
3136                        msgMax, 4, RTEMS_FIFO, pMsgQ) !=
3137                        RTEMS_SUCCESSFUL)
3138                        return OBJECTS_ID_NONE;
3139                created_msgq = 1;
3140        }
3141
3142        if (prio < 0)
3143                prio = grspw_work_task_priority; /* default prio */
3144        if (stack < 0x800)
3145                stack = RTEMS_MINIMUM_STACK_SIZE; /* default stack size */
3146
3147        if (rtems_task_create(rtems_build_name('S', 'G', 'L', 'T'),
3148                prio, stack, RTEMS_PREEMPT | RTEMS_NO_ASR,
3149                RTEMS_NO_FLOATING_POINT, &tid) != RTEMS_SUCCESSFUL)
3150                tid = OBJECTS_ID_NONE;
3151        else if (rtems_task_start(tid, (rtems_task_entry)grspw_work_func, *pMsgQ) !=
3152                    RTEMS_SUCCESSFUL) {
3153                rtems_task_delete(tid);
3154                tid = OBJECTS_ID_NONE;
3155        }
3156
3157        if (tid == OBJECTS_ID_NONE && created_msgq) {
3158                rtems_message_queue_delete(*pMsgQ);
3159                *pMsgQ = OBJECTS_ID_NONE;
3160        }
3161        return tid;
3162}
3163
3164/* Free task associated with message queue and optionally also the message
3165 * queue itself. The message queue is deleted by the work task and is therefore
3166 * delayed until it the work task resumes its execution.
3167 */
3168rtems_status_code grspw_work_free(rtems_id msgQ, int freeMsgQ)
3169{
3170        int msg = WORK_QUIT_TASK;
3171        if (freeMsgQ)
3172                msg |= WORK_FREE_MSGQ;
3173        return rtems_message_queue_send(msgQ, &msg, 4);
3174}
3175
3176void grspw_work_cfg(void *d, struct grspw_work_config *wc)
3177{
3178        struct grspw_priv *priv = (struct grspw_priv *)d;
3179
3180        if (wc == NULL)
3181                wc = &grspw_wc_def; /* use default config */
3182        priv->wc = *wc;
3183}
3184
3185static int grspw_common_init(void)
3186{
3187        if (grspw_initialized == 1)
3188                return 0;
3189        if (grspw_initialized == -1)
3190                return -1;
3191        grspw_initialized = -1;
3192
3193        /* Device Semaphore created with count = 1 */
3194        if (rtems_semaphore_create(rtems_build_name('S', 'G', 'L', 'S'), 1,
3195            RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | \
3196            RTEMS_NO_INHERIT_PRIORITY | RTEMS_LOCAL | \
3197            RTEMS_NO_PRIORITY_CEILING, 0, &grspw_sem) != RTEMS_SUCCESSFUL)
3198                return -1;
3199
3200        /* Work queue, Work thread. Not created if user disables it.
3201         * user can disable it when interrupt is not used to save resources
3202         */
3203        if (grspw_work_task_priority != -1) {
3204                grspw_work_task = grspw_work_spawn(-1, 0,
3205                        (rtems_id *)&grspw_wc_def.msgisr_arg, 0);
3206                if (grspw_work_task == OBJECTS_ID_NONE)
3207                        return -2;
3208                grspw_wc_def.msgisr =
3209                        (grspw_msgqisr_t) rtems_message_queue_send;
3210        } else {
3211                grspw_wc_def.msgisr = NULL;
3212                grspw_wc_def.msgisr_arg = NULL;
3213        }
3214
3215        grspw_initialized = 1;
3216        return 0;
3217}
Note: See TracBrowser for help on using the repository browser.