ee9d39bbd2511a0d3495729f6f89c0b4d7757831
[cascardo/linux.git] / drivers / staging / cxt1e1 / functions.c
1 /* Copyright (C) 2003-2005  SBE, Inc.
2  *
3  *   This program is free software; you can redistribute it and/or modify
4  *   it under the terms of the GNU General Public License as published by
5  *   the Free Software Foundation; either version 2 of the License, or
6  *   (at your option) any later version.
7  *
8  *   This program is distributed in the hope that it will be useful,
9  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  *   GNU General Public License for more details.
12  */
13
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
16 #include <linux/slab.h>
17 #include <linux/io.h>
18 #include <asm/byteorder.h>
19 #include <linux/netdevice.h>
20 #include <linux/delay.h>
21 #include <linux/hdlc.h>
22 #include "pmcc4_sysdep.h"
23 #include "sbecom_inline_linux.h"
24 #include "libsbew.h"
25 #include "pmcc4.h"
26
27 #if defined(CONFIG_SBE_HDLC_V7) || defined(CONFIG_SBE_WAN256T3_HDLC_V7) || \
28 defined(CONFIG_SBE_HDLC_V7_MODULE) || \
29 defined(CONFIG_SBE_WAN256T3_HDLC_V7_MODULE)
30 #define _v7_hdlc_  1
31 #else
32 #define _v7_hdlc_  0
33 #endif
34
35 #if _v7_hdlc_
36 #define V7(x) (x ## _v7)
37 extern int  hdlc_netif_rx_v7(hdlc_device *, struct sk_buff *);
38 extern int  register_hdlc_device_v7(hdlc_device *);
39 extern int  unregister_hdlc_device_v7(hdlc_device *);
40
41 #else
42 #define V7(x) x
43 #endif
44
45
46 #ifndef USE_MAX_INT_DELAY
47 static int  dummy = 0;
48
49 #endif
50
51 extern int  drvr_state;
52
53
54 #if 1
55 u_int32_t
56 pci_read_32(u_int32_t *p)
57 {
58 #ifdef FLOW_DEBUG
59         u_int32_t   v;
60
61         FLUSH_PCI_READ();
62         v = le32_to_cpu(*p);
63         if (cxt1e1_log_level >= LOG_DEBUG)
64                 pr_info("pci_read : %x = %x\n", (u_int32_t) p, v);
65         return v;
66 #else
67         FLUSH_PCI_READ();              /* */
68         return le32_to_cpu(*p);
69 #endif
70 }
71
72 void
73 pci_write_32(u_int32_t *p, u_int32_t v)
74 {
75 #ifdef FLOW_DEBUG
76         if (cxt1e1_log_level >= LOG_DEBUG)
77                 pr_info("pci_write: %x = %x\n", (u_int32_t) p, v);
78 #endif
79         *p = cpu_to_le32 (v);
80         FLUSH_PCI_WRITE();             /* This routine is called from routines
81                                         * which do multiple register writes
82                                         * which themselves need flushing between
83                                         * writes in order to guarantee write
84                                         * ordering.  It is less code-cumbersome
85                                         * to flush here-in then to investigate
86                                         * and code the many other register
87                                         * writing routines. */
88 }
89 #endif
90
91
92 void
93 pci_flush_write(ci_t *ci)
94 {
95         volatile u_int32_t v;
96
97     /* issue a PCI read to flush PCI write thru bridge */
98         v = *(u_int32_t *) &ci->reg->glcd;  /* any address would do */
99
100     /*
101      * return nothing, this just reads PCI bridge interface to flush
102      * previously written data
103      */
104 }
105
106
107 static void
108 watchdog_func(unsigned long arg)
109 {
110         struct watchdog *wd = (void *) arg;
111
112         if (drvr_state != SBE_DRVR_AVAILABLE) {
113                 if (cxt1e1_log_level >= LOG_MONITOR)
114                         pr_warning("%s: drvr not available (%x)\n",
115                                    __func__, drvr_state);
116                 return;
117         }
118         schedule_work(&wd->work);
119         mod_timer(&wd->h, jiffies + wd->ticks);
120 }
121
122 int OS_init_watchdog(struct watchdog *wdp, void (*f) (void *),
123                      void *c, int usec)
124 {
125         wdp->func = f;
126         wdp->softc = c;
127         wdp->ticks = (HZ) * (usec / 1000) / 1000;
128         INIT_WORK(&wdp->work, (void *)f);
129         init_timer(&wdp->h);
130         {
131                 ci_t       *ci = (ci_t *) c;
132
133                 wdp->h.data = (unsigned long) &ci->wd;
134         }
135         wdp->h.function = watchdog_func;
136         return 0;
137 }
138
139 void
140 OS_uwait(int usec, char *description)
141 {
142         int         tmp;
143
144         if (usec >= 1000) {
145                 mdelay(usec / 1000);
146                 /* now delay residual */
147                 tmp = (usec / 1000) * 1000; /* round */
148                 tmp = usec - tmp;           /* residual */
149                 if (tmp) {                           /* wait on residual */
150                         udelay(tmp);
151                 }
152         } else {
153                 udelay(usec);
154         }
155 }
156
157 /* dummy short delay routine called as a subroutine so that compiler
158  * does not optimize/remove its intent (a short delay)
159  */
160
161 void
162 OS_uwait_dummy(void)
163 {
164 #ifndef USE_MAX_INT_DELAY
165         dummy++;
166 #else
167         udelay(1);
168 #endif
169 }
170
171
172 void
173 OS_sem_init(void *sem, int state)
174 {
175         switch (state) {
176         case SEM_TAKEN:
177             sema_init((struct semaphore *) sem, 0);
178             break;
179         case SEM_AVAILABLE:
180             sema_init((struct semaphore *) sem, 1);
181             break;
182         default:                        /* otherwise, set sem.count to state's
183                                         * value */
184             sema_init(sem, state);
185             break;
186         }
187 }
188
189
190 int
191 sd_line_is_ok(void *user)
192 {
193         struct net_device *ndev = (struct net_device *) user;
194
195         return netif_carrier_ok(ndev);
196 }
197
198 void
199 sd_line_is_up(void *user)
200 {
201         struct net_device *ndev = (struct net_device *) user;
202
203         netif_carrier_on(ndev);
204         return;
205 }
206
207 void
208 sd_line_is_down(void *user)
209 {
210         struct net_device *ndev = (struct net_device *) user;
211
212         netif_carrier_off(ndev);
213         return;
214 }
215
216 void
217 sd_disable_xmit(void *user)
218 {
219         struct net_device *dev = (struct net_device *) user;
220
221         netif_stop_queue(dev);
222         return;
223 }
224
225 void
226 sd_enable_xmit(void *user)
227 {
228         struct net_device *dev = (struct net_device *) user;
229
230         netif_wake_queue(dev);
231         return;
232 }
233
234 int
235 sd_queue_stopped(void *user)
236 {
237         struct net_device *ndev = (struct net_device *) user;
238
239         return netif_queue_stopped(ndev);
240 }
241
242 void sd_recv_consume(void *token, size_t len, void *user)
243 {
244         struct net_device *ndev = user;
245         struct sk_buff *skb = token;
246
247         skb->dev = ndev;
248         skb_put(skb, len);
249         skb->protocol = hdlc_type_trans(skb, ndev);
250         netif_rx(skb);
251 }
252
253
254 /**
255  ** Read some reserved location w/in the COMET chip as a usable
256  ** VMETRO trigger point or other trace marking event.
257  **/
258
259 #include "comet.h"
260
261 extern ci_t *CI;                /* dummy pointer to board ZERO's data */
262 void
263 VMETRO_TRIGGER(ci_t *ci, int x)
264 {
265         struct s_comet_reg    *comet;
266         volatile u_int32_t data;
267
268         comet = ci->port[0].cometbase;  /* default to COMET # 0 */
269
270         switch (x) {
271         default:
272         case 0:
273             data = pci_read_32((u_int32_t *) &comet->__res24);     /* 0x90 */
274             break;
275         case 1:
276             data = pci_read_32((u_int32_t *) &comet->__res25);     /* 0x94 */
277             break;
278         case 2:
279             data = pci_read_32((u_int32_t *) &comet->__res26);     /* 0x98 */
280             break;
281         case 3:
282             data = pci_read_32((u_int32_t *) &comet->__res27);     /* 0x9C */
283             break;
284         case 4:
285             data = pci_read_32((u_int32_t *) &comet->__res88);     /* 0x220 */
286             break;
287         case 5:
288             data = pci_read_32((u_int32_t *) &comet->__res89);     /* 0x224 */
289             break;
290         case 6:
291             data = pci_read_32((u_int32_t *) &comet->__res8A);     /* 0x228 */
292             break;
293         case 7:
294             data = pci_read_32((u_int32_t *) &comet->__res8B);     /* 0x22C */
295             break;
296         case 8:
297             data = pci_read_32((u_int32_t *) &comet->__resA0);     /* 0x280 */
298             break;
299         case 9:
300             data = pci_read_32((u_int32_t *) &comet->__resA1);     /* 0x284 */
301             break;
302         case 10:
303             data = pci_read_32((u_int32_t *) &comet->__resA2);     /* 0x288 */
304             break;
305         case 11:
306             data = pci_read_32((u_int32_t *) &comet->__resA3);     /* 0x28C */
307             break;
308         case 12:
309             data = pci_read_32((u_int32_t *) &comet->__resA4);     /* 0x290 */
310             break;
311         case 13:
312             data = pci_read_32((u_int32_t *) &comet->__resA5);     /* 0x294 */
313             break;
314         case 14:
315             data = pci_read_32((u_int32_t *) &comet->__resA6);     /* 0x298 */
316             break;
317         case 15:
318             data = pci_read_32((u_int32_t *) &comet->__resA7);     /* 0x29C */
319             break;
320         case 16:
321             data = pci_read_32((u_int32_t *) &comet->__res74);     /* 0x1D0 */
322             break;
323         case 17:
324             data = pci_read_32((u_int32_t *) &comet->__res75);     /* 0x1D4 */
325             break;
326         case 18:
327             data = pci_read_32((u_int32_t *) &comet->__res76);     /* 0x1D8 */
328             break;
329         case 19:
330             data = pci_read_32((u_int32_t *) &comet->__res77);     /* 0x1DC */
331             break;
332         }
333 }
334
335
336 /***  End-of-File  ***/