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