aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Beers <bob.beers@gmail.com>2010-03-04 08:40:46 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-11 14:35:31 -0400
commit50ee11fe383255db8e5c3307319d470015616f27 (patch)
treed6900a217a10602d53199d360487548650e100e2
parent588063a10f4e21cd3a2cc693c0c1ebb846ac4ce5 (diff)
staging: Add driver to support wanPMC-CxT1E1 card.
Obviously still needs serious attention, but it compiles. Original author: Rick Dobbs Add driver to support wanPMC-CxT1E1 card. This card provides 1-4 ports of T1E1 in PMC form factor. Note, Rick doesn't want his email showing up as the "From:" author, but has given his blessing to have the code included in the kernel tree. Signed-off-by: Bob Beers <bob.beers@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/cxt1e1/Kconfig22
-rw-r--r--drivers/staging/cxt1e1/Makefile19
-rw-r--r--drivers/staging/cxt1e1/comet.c566
-rw-r--r--drivers/staging/cxt1e1/comet.h366
-rw-r--r--drivers/staging/cxt1e1/comet_tables.c561
-rw-r--r--drivers/staging/cxt1e1/comet_tables.h85
-rw-r--r--drivers/staging/cxt1e1/functions.c366
-rw-r--r--drivers/staging/cxt1e1/hwprobe.c400
-rw-r--r--drivers/staging/cxt1e1/libsbew.h581
-rw-r--r--drivers/staging/cxt1e1/linux.c1354
-rw-r--r--drivers/staging/cxt1e1/musycc.c2180
-rw-r--r--drivers/staging/cxt1e1/musycc.h460
-rw-r--r--drivers/staging/cxt1e1/ossiRelease.c39
-rw-r--r--drivers/staging/cxt1e1/pmc93x6_eeprom.c559
-rw-r--r--drivers/staging/cxt1e1/pmc93x6_eeprom.h60
-rw-r--r--drivers/staging/cxt1e1/pmcc4.h155
-rw-r--r--drivers/staging/cxt1e1/pmcc4_cpld.h124
-rw-r--r--drivers/staging/cxt1e1/pmcc4_defs.h82
-rw-r--r--drivers/staging/cxt1e1/pmcc4_drv.c1855
-rw-r--r--drivers/staging/cxt1e1/pmcc4_ioctls.h81
-rw-r--r--drivers/staging/cxt1e1/pmcc4_private.h295
-rw-r--r--drivers/staging/cxt1e1/pmcc4_sysdep.h62
-rw-r--r--drivers/staging/cxt1e1/sbe_bid.h61
-rw-r--r--drivers/staging/cxt1e1/sbe_promformat.h157
-rw-r--r--drivers/staging/cxt1e1/sbecom_inline_linux.h310
-rw-r--r--drivers/staging/cxt1e1/sbecrc.c137
-rw-r--r--drivers/staging/cxt1e1/sbeid.c217
-rw-r--r--drivers/staging/cxt1e1/sbeproc.c358
-rw-r--r--drivers/staging/cxt1e1/sbeproc.h52
-rw-r--r--drivers/staging/cxt1e1/sbew_ioc.h136
32 files changed, 11703 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 7696a664f8a..8db8632541f 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -139,5 +139,7 @@ source "drivers/staging/dt3155/Kconfig"
139 139
140source "drivers/staging/crystalhd/Kconfig" 140source "drivers/staging/crystalhd/Kconfig"
141 141
142source "drivers/staging/cxt1e1/Kconfig"
143
142endif # !STAGING_EXCLUDE_BUILD 144endif # !STAGING_EXCLUDE_BUILD
143endif # STAGING 145endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index ea2e70e2fed..ab61e2601ff 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -51,3 +51,4 @@ obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/
51obj-$(CONFIG_FB_SM7XX) += sm7xx/ 51obj-$(CONFIG_FB_SM7XX) += sm7xx/
52obj-$(CONFIG_DT3155) += dt3155/ 52obj-$(CONFIG_DT3155) += dt3155/
53obj-$(CONFIG_CRYSTALHD) += crystalhd/ 53obj-$(CONFIG_CRYSTALHD) += crystalhd/
54obj-$(CONFIG_CXT1E1) += cxt1e1/
diff --git a/drivers/staging/cxt1e1/Kconfig b/drivers/staging/cxt1e1/Kconfig
new file mode 100644
index 00000000000..68e9b6d973f
--- /dev/null
+++ b/drivers/staging/cxt1e1/Kconfig
@@ -0,0 +1,22 @@
1config CXT1E1
2 tristate "SBE wanPMC-C[421]E1T1 hardware support"
3 depends on HDLC && PCI
4 ---help---
5 This driver supports the SBE wanPMC-CxT1E1 1, 2 and 4 port T3
6 channelized stream WAN adapter card which contains a HDLC/Transparent
7 mode controller.
8
9 If you want to compile this driver as a module
10 say M here and read <file:Documentation/modules.txt>.
11 The module will be called 'cxt1e1'.
12
13 If unsure, say N.
14
15config SBE_PMCC4_NCOMM
16 bool "SBE PMCC4 NCOMM support"
17 depends on CXT1E1
18 ---help---
19 SBE supplies optional support for NCOMM products.
20
21 If you have purchased this optional support you must say Y or M
22 here to allow the driver to operate with the NCOMM product.
diff --git a/drivers/staging/cxt1e1/Makefile b/drivers/staging/cxt1e1/Makefile
new file mode 100644
index 00000000000..10020d7b79a
--- /dev/null
+++ b/drivers/staging/cxt1e1/Makefile
@@ -0,0 +1,19 @@
1obj-$(CONFIG_CXT1E1) += cxt1e1.o
2
3EXTRA_CFLAGS += -DSBE_PMCC4_ENABLE
4EXTRA_CFLAGS += -DSBE_ISR_TASKLET
5EXTRA_CFLAGS += -DSBE_INCLUDE_SYMBOLS
6
7cxt1e1-objs += \
8 ossiRelease.o \
9 musycc.o \
10 pmcc4_drv.o \
11 comet.o \
12 linux.o \
13 functions.o \
14 hwprobe.o \
15 sbeproc.o \
16 pmc93x6_eeprom.o \
17 sbecrc.o \
18 comet_tables.o \
19 sbeid.o
diff --git a/drivers/staging/cxt1e1/comet.c b/drivers/staging/cxt1e1/comet.c
new file mode 100644
index 00000000000..b7090996703
--- /dev/null
+++ b/drivers/staging/cxt1e1/comet.c
@@ -0,0 +1,566 @@
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 <asm/io.h>
15#include <linux/hdlc.h>
16#include "pmcc4_sysdep.h"
17#include "sbecom_inline_linux.h"
18#include "libsbew.h"
19#include "pmcc4.h"
20#include "comet.h"
21#include "comet_tables.h"
22
23#ifdef SBE_INCLUDE_SYMBOLS
24#define STATIC
25#else
26#define STATIC static
27#endif
28
29
30extern int log_level;
31
32#define COMET_NUM_SAMPLES 24 /* Number of entries in the waveform table */
33#define COMET_NUM_UNITS 5 /* Number of points per entry in table */
34
35/* forward references */
36STATIC void SetPwrLevel (comet_t * comet);
37STATIC void WrtRcvEqualizerTbl (ci_t * ci, comet_t * comet, u_int32_t *table);
38STATIC void WrtXmtWaveformTbl (ci_t * ci, comet_t * comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]);
39
40
41void *TWV_table[12] = {
42 TWVLongHaul0DB, TWVLongHaul7_5DB, TWVLongHaul15DB, TWVLongHaul22_5DB,
43 TWVShortHaul0, TWVShortHaul1, TWVShortHaul2, TWVShortHaul3, TWVShortHaul4,
44 TWVShortHaul5,
45 TWV_E1_75Ohm, /** PORT POINT - 75 Ohm not supported **/
46 TWV_E1_120Ohm
47};
48
49
50static int
51lbo_tbl_lkup (int t1, int lbo)
52{
53 if ((lbo < CFG_LBO_LH0) || (lbo > CFG_LBO_E120)) /* error switches to
54 * default */
55 {
56 if (t1)
57 lbo = CFG_LBO_LH0; /* default T1 waveform table */
58 else
59 lbo = CFG_LBO_E120; /* default E1 waveform table */
60 }
61 return (lbo - 1); /* make index ZERO relative */
62}
63
64
65void
66init_comet (void *ci, comet_t * comet, u_int32_t port_mode, int clockmaster,
67 u_int8_t moreParams)
68{
69 u_int8_t isT1mode;
70 u_int8_t tix = CFG_LBO_LH0; /* T1 default */
71
72 isT1mode = IS_FRAME_ANY_T1 (port_mode);
73 /* T1 or E1 */
74 if (isT1mode)
75 {
76 pci_write_32 ((u_int32_t *) &comet->gbl_cfg, 0xa0); /* Select T1 Mode & PIO
77 * output enabled */
78 tix = lbo_tbl_lkup (isT1mode, CFG_LBO_LH0); /* default T1 waveform
79 * table */
80 } else
81 {
82 pci_write_32 ((u_int32_t *) &comet->gbl_cfg, 0x81); /* Select E1 Mode & PIO
83 * output enabled */
84 tix = lbo_tbl_lkup (isT1mode, CFG_LBO_E120); /* default E1 waveform
85 * table */
86 }
87
88 if (moreParams & CFG_LBO_MASK)
89 tix = lbo_tbl_lkup (isT1mode, moreParams & CFG_LBO_MASK); /* dial-in requested
90 * waveform table */
91
92 /* Tx line Intfc cfg ** Set for analog & no special patterns */
93 pci_write_32 ((u_int32_t *) &comet->tx_line_cfg, 0x00); /* Transmit Line
94 * Interface Config. */
95
96 /* master test ** Ignore Test settings for now */
97 pci_write_32 ((u_int32_t *) &comet->mtest, 0x00); /* making sure it's
98 * Default value */
99
100 /* Turn on Center (CENT) and everything else off */
101 pci_write_32 ((u_int32_t *) &comet->rjat_cfg, 0x10); /* RJAT cfg */
102 /* Set Jitter Attenuation to recommend T1 values */
103 if (isT1mode)
104 {
105 pci_write_32 ((u_int32_t *) &comet->rjat_n1clk, 0x2F); /* RJAT Divider N1
106 * Control */
107 pci_write_32 ((u_int32_t *) &comet->rjat_n2clk, 0x2F); /* RJAT Divider N2
108 * Control */
109 } else
110 {
111 pci_write_32 ((u_int32_t *) &comet->rjat_n1clk, 0xFF); /* RJAT Divider N1
112 * Control */
113 pci_write_32 ((u_int32_t *) &comet->rjat_n2clk, 0xFF); /* RJAT Divider N2
114 * Control */
115 }
116
117 /* Turn on Center (CENT) and everything else off */
118 pci_write_32 ((u_int32_t *) &comet->tjat_cfg, 0x10); /* TJAT Config. */
119
120 /* Do not bypass jitter attenuation and bypass elastic store */
121 pci_write_32 ((u_int32_t *) &comet->rx_opt, 0x00); /* rx opts */
122
123 /* TJAT ctrl & TJAT divider ctrl */
124 /* Set Jitter Attenuation to recommended T1 values */
125 if (isT1mode)
126 {
127 pci_write_32 ((u_int32_t *) &comet->tjat_n1clk, 0x2F); /* TJAT Divider N1
128 * Control */
129 pci_write_32 ((u_int32_t *) &comet->tjat_n2clk, 0x2F); /* TJAT Divider N2
130 * Control */
131 } else
132 {
133 pci_write_32 ((u_int32_t *) &comet->tjat_n1clk, 0xFF); /* TJAT Divider N1
134 * Control */
135 pci_write_32 ((u_int32_t *) &comet->tjat_n2clk, 0xFF); /* TJAT Divider N2
136 * Control */
137 }
138
139 /* 1c: rx ELST cfg 20: tx ELST cfg 28&38: rx&tx data link ctrl */
140 if (isT1mode)
141 { /* Select 193-bit frame format */
142 pci_write_32 ((u_int32_t *) &comet->rx_elst_cfg, 0x00);
143 pci_write_32 ((u_int32_t *) &comet->tx_elst_cfg, 0x00);
144 } else
145 { /* Select 256-bit frame format */
146 pci_write_32 ((u_int32_t *) &comet->rx_elst_cfg, 0x03);
147 pci_write_32 ((u_int32_t *) &comet->tx_elst_cfg, 0x03);
148 pci_write_32 ((u_int32_t *) &comet->rxce1_ctl, 0x00); /* disable T1 data link
149 * receive */
150 pci_write_32 ((u_int32_t *) &comet->txci1_ctl, 0x00); /* disable T1 data link
151 * transmit */
152 }
153
154 /* the following is a default value */
155 /* Enable 8 out of 10 validation */
156 pci_write_32 ((u_int32_t *) &comet->t1_rboc_ena, 0x00); /* t1RBOC
157 * enable(BOC:BitOriented
158 * Code) */
159 if (isT1mode)
160 {
161
162 /* IBCD cfg: aka Inband Code Detection ** loopback code length set to */
163 pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x04); /* 6 bit down, 5 bit up
164 * (assert) */
165 pci_write_32 ((u_int32_t *) &comet->ibcd_act, 0x08); /* line loopback
166 * activate pattern */
167 pci_write_32 ((u_int32_t *) &comet->ibcd_deact, 0x24); /* deactivate code
168 * pattern (i.e.001) */
169 }
170 /* 10: CDRC cfg 28&38: rx&tx data link 1 ctrl 48: t1 frmr cfg */
171 /* 50: SIGX cfg, COSS (change of signaling state) 54: XBAS cfg */
172 /* 60: t1 ALMI cfg */
173 /* Configure Line Coding */
174
175 switch (port_mode)
176 {
177 case CFG_FRAME_SF: /* 1 - T1 B8ZS */
178 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
179 pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0);
180 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
181 pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0x20); /* 5:B8ZS */
182 pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0);
183 break;
184 case CFG_FRAME_ESF: /* 2 - T1 B8ZS */
185 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
186 pci_write_32 ((u_int32_t *) &comet->rxce1_ctl, 0x20); /* Bit 5: T1 DataLink
187 * Enable */
188 pci_write_32 ((u_int32_t *) &comet->txci1_ctl, 0x20); /* 5: T1 DataLink Enable */
189 pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0x30); /* 4:ESF 5:ESFFA */
190 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0x04); /* 2:ESF */
191 pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0x30); /* 4:ESF 5:B8ZS */
192 pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0x10); /* 4:ESF */
193 break;
194 case CFG_FRAME_E1PLAIN: /* 3 - HDB3 */
195 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
196 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
197 pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0);
198 pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x40);
199 break;
200 case CFG_FRAME_E1CAS: /* 4 - HDB3 */
201 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
202 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
203 pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x60);
204 pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0);
205 break;
206 case CFG_FRAME_E1CRC: /* 5 - HDB3 */
207 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
208 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
209 pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x10);
210 pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0xc2);
211 break;
212 case CFG_FRAME_E1CRC_CAS: /* 6 - HDB3 */
213 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
214 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
215 pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x70);
216 pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x82);
217 break;
218 case CFG_FRAME_SF_AMI: /* 7 - T1 AMI */
219 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line
220 * Decoding */
221 pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0);
222 pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0);
223 pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0);
224 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
225 break;
226 case CFG_FRAME_ESF_AMI: /* 8 - T1 AMI */
227 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line
228 * Decoding */
229 pci_write_32 ((u_int32_t *) &comet->rxce1_ctl, 0x20); /* 5: T1 DataLink Enable */
230 pci_write_32 ((u_int32_t *) &comet->txci1_ctl, 0x20); /* 5: T1 DataLink Enable */
231 pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0x30); /* Bit 4:ESF 5:ESFFA */
232 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0x04); /* 2:ESF */
233 pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0x10); /* 4:ESF */
234 pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0x10); /* 4:ESF */
235 break;
236 case CFG_FRAME_E1PLAIN_AMI: /* 9 - AMI */
237 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line
238 * Decoding */
239 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
240 pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x80);
241 pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x40);
242 break;
243 case CFG_FRAME_E1CAS_AMI: /* 10 - AMI */
244 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line
245 * Decoding */
246 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
247 pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0xe0);
248 pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0);
249 break;
250 case CFG_FRAME_E1CRC_AMI: /* 11 - AMI */
251 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line
252 * Decoding */
253 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
254 pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x90);
255 pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0xc2);
256 break;
257 case CFG_FRAME_E1CRC_CAS_AMI: /* 12 - AMI */
258 pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line
259 * Decoding */
260 pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
261 pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0xf0);
262 pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x82);
263 break;
264 } /* end switch */
265
266 /***
267 * Set Full Frame mode (NXDSO[1] = 0, NXDSO[0] = 0)
268 * CMODE=1: Clock slave mode with BRCLK as an input,
269 * DE=0: Use falling edge of BRCLK for data,
270 * FE=0: Use falling edge of BRCLK for frame,
271 * CMS=0: Use backplane freq,
272 * RATE[1:0]=0,0: T1
273 ***/
274
275
276 /* 0x30: "BRIF cfg"; 0x20 is 'CMODE', 0x03 is (bit) rate */
277 /* note "rate bits can only be set once after reset" */
278 if (clockmaster)
279 { /* CMODE == clockMode, 0=clock master (so
280 * all 3 others should be slave) */
281 if (isT1mode) /* rate = 1.544 Mb/s */
282 pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x00); /* Comet 0 Master
283 * Mode(CMODE=0) */
284 else /* rate = 2.048 Mb/s */
285 pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x01); /* Comet 0 Master
286 * Mode(CMODE=0) */
287
288 /* 31: BRIF frame pulse cfg 06: tx timing options */
289 pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, 0x00); /* Master Mode
290 * i.e.FPMODE=0 (@0x20) */
291 if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL)
292 {
293 if (log_level >= LOG_SBEBUG12)
294 printk (">> init_comet: clockmaster internal clock\n");
295 pci_write_32 ((u_int32_t *) &comet->tx_time, 0x0d); /* internal oscillator */
296 } else /* external clock source */
297 {
298 if (log_level >= LOG_SBEBUG12)
299 printk (">> init_comet: clockmaster external clock\n");
300 pci_write_32 ((u_int32_t *) &comet->tx_time, 0x09); /* loop timing
301 * (external) */
302 }
303
304 } else /* slave */
305 {
306 if (isT1mode)
307 pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x20); /* Slave Mode(CMODE=1,
308 * see above) */
309 else
310 pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x21); /* Slave Mode (CMODE=1) */
311 pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, 0x20); /* Slave Mode i.e.
312 * FPMODE=1 (@0x20) */
313 if (log_level >= LOG_SBEBUG12)
314 printk (">> init_comet: clockslave internal clock\n");
315 pci_write_32 ((u_int32_t *) &comet->tx_time, 0x0d); /* oscillator timing */
316 }
317
318 /* 32: BRIF parity F-bit cfg */
319 /* Totem-pole operation */
320 pci_write_32 ((u_int32_t *) &comet->brif_pfcfg, 0x01); /* Receive Backplane
321 * Parity/F-bit */
322
323 /* dc: RLPS equalizer V ref */
324 /* Configuration */
325 if (isT1mode)
326 pci_write_32 ((u_int32_t *) &comet->rlps_eqvr, 0x2c); /* RLPS Equalizer
327 * Voltage */
328 else
329 pci_write_32 ((u_int32_t *) &comet->rlps_eqvr, 0x34); /* RLPS Equalizer
330 * Voltage */
331
332 /* Reserved bit set and SQUELCH enabled */
333 /* f8: RLPS cfg & status f9: RLPS ALOS detect/clear threshold */
334 pci_write_32 ((u_int32_t *) &comet->rlps_cfgsts, 0x11); /* RLPS Configuration
335 * Status */
336 if (isT1mode)
337 pci_write_32 ((u_int32_t *) &comet->rlps_alos_thresh, 0x55); /* ? */
338 else
339 pci_write_32 ((u_int32_t *) &comet->rlps_alos_thresh, 0x22); /* ? */
340
341
342 /* Set Full Frame mode (NXDSO[1] = 0, NXDSO[0] = 0) */
343 /* CMODE=0: Clock slave mode with BTCLK as an input, DE=1: Use rising */
344 /* edge of BTCLK for data, FE=1: Use rising edge of BTCLK for frame, */
345 /* CMS=0: Use backplane freq, RATE[1:0]=0,0: T1 */
346/*** Transmit side is always an Input, Slave Clock*/
347 /* 40: BTIF cfg 41: BTIF frame pulse cfg */
348 if (isT1mode)
349 pci_write_32 ((u_int32_t *) &comet->btif_cfg, 0x38); /* BTIF Configuration
350 * Reg. */
351 else
352 pci_write_32 ((u_int32_t *) &comet->btif_cfg, 0x39); /* BTIF Configuration
353 * Reg. */
354
355 pci_write_32 ((u_int32_t *) &comet->btif_fpcfg, 0x01); /* BTIF Frame Pulse
356 * Config. */
357
358 /* 0a: master diag 06: tx timing options */
359 /* if set Comet to loop back */
360
361 /* Comets set to normal */
362 pci_write_32 ((u_int32_t *) &comet->mdiag, 0x00);
363
364 /* BTCLK driven by TCLKI internally (crystal driven) and Xmt Elasted */
365 /* Store is enabled. */
366
367 WrtXmtWaveformTbl (ci, comet, TWV_table[tix]);
368 if (isT1mode)
369 WrtRcvEqualizerTbl ((ci_t *) ci, comet, &T1_Equalizer[0]);
370 else
371 WrtRcvEqualizerTbl ((ci_t *) ci, comet, &E1_Equalizer[0]);
372 SetPwrLevel (comet);
373}
374
375/*
376** Name: WrtXmtWaveform
377** Description: Formulate the Data for the Pulse Waveform Storage
378** Write register, (F2), from the sample and unit inputs.
379** Write the data to the Pulse Waveform Storage Data register.
380** Returns: Nothing
381*/
382STATIC void
383WrtXmtWaveform (ci_t * ci, comet_t * comet, u_int32_t sample, u_int32_t unit, u_int8_t data)
384{
385 u_int8_t WaveformAddr;
386
387 WaveformAddr = (sample << 3) + (unit & 7);
388 pci_write_32 ((u_int32_t *) &comet->xlpg_pwave_addr, WaveformAddr);
389 pci_flush_write (ci); /* for write order preservation when
390 * Optimizing driver */
391 pci_write_32 ((u_int32_t *) &comet->xlpg_pwave_data, 0x7F & data);
392}
393
394/*
395** Name: WrtXmtWaveformTbl
396** Description: Fill in the Transmit Waveform Values
397** for driving the transmitter DAC.
398** Returns: Nothing
399*/
400STATIC void
401WrtXmtWaveformTbl (ci_t * ci, comet_t * comet,
402 u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS])
403{
404 u_int32_t sample, unit;
405
406 for (sample = 0; sample < COMET_NUM_SAMPLES; sample++)
407 {
408 for (unit = 0; unit < COMET_NUM_UNITS; unit++)
409 WrtXmtWaveform (ci, comet, sample, unit, table[sample][unit]);
410 }
411
412 /* Enable transmitter and set output amplitude */
413 pci_write_32 ((u_int32_t *) &comet->xlpg_cfg, table[COMET_NUM_SAMPLES][0]);
414}
415
416
417/*
418** Name: WrtXmtWaveform
419** Description: Fill in the Receive Equalizer RAM from the desired
420** table.
421** Returns: Nothing
422**
423** Remarks: Per PM4351 Device Errata, Receive Equalizer RAM Initialization
424** is coded with early setup of indirect address.
425*/
426
427STATIC void
428WrtRcvEqualizerTbl (ci_t * ci, comet_t * comet, u_int32_t *table)
429{
430 u_int32_t ramaddr;
431 volatile u_int32_t value;
432
433 for (ramaddr = 0; ramaddr < 256; ramaddr++)
434 {
435 /*** the following lines are per Errata 7, 2.5 ***/
436 {
437 pci_write_32 ((u_int32_t *) &comet->rlps_eq_rwsel, 0x80); /* Set up for a read
438 * operation */
439 pci_flush_write (ci); /* for write order preservation when
440 * Optimizing driver */
441 pci_write_32 ((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr); /* write the addr,
442 * initiate a read */
443 pci_flush_write (ci); /* for write order preservation when
444 * Optimizing driver */
445 /*
446 * wait 3 line rate clock cycles to ensure address bits are
447 * captured by T1/E1 clock
448 */
449 OS_uwait (4, "wret"); /* 683ns * 3 = 1366 ns, approx 2us (but
450 * use 4us) */
451 }
452
453 value = *table++;
454 pci_write_32 ((u_int32_t *) &comet->rlps_idata3, (u_int8_t) (value >> 24));
455 pci_write_32 ((u_int32_t *) &comet->rlps_idata2, (u_int8_t) (value >> 16));
456 pci_write_32 ((u_int32_t *) &comet->rlps_idata1, (u_int8_t) (value >> 8));
457 pci_write_32 ((u_int32_t *) &comet->rlps_idata0, (u_int8_t) value);
458 pci_flush_write (ci); /* for write order preservation when
459 * Optimizing driver */
460
461 /* Storing RAM address, causes RAM to be updated */
462
463 pci_write_32 ((u_int32_t *) &comet->rlps_eq_rwsel, 0); /* Set up for a write
464 * operation */
465 pci_flush_write (ci); /* for write order preservation when
466 * Optimizing driver */
467 pci_write_32 ((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr); /* write the addr,
468 * initiate a read */
469 pci_flush_write (ci); /* for write order preservation when
470 * Optimizing driver */
471 /*
472 * wait 3 line rate clock cycles to ensure address bits are captured
473 * by T1/E1 clock
474 */
475 OS_uwait (4, "wret"); /* 683ns * 3 = 1366 ns, approx 2us (but
476 * use 4us) */
477 }
478
479 pci_write_32 ((u_int32_t *) &comet->rlps_eq_cfg, 0xCB); /* Enable Equalizer &
480 * set it to use 256
481 * periods */
482}
483
484
485/*
486** Name: SetPwrLevel
487** Description: Implement power level setting algorithm described below
488** Returns: Nothing
489*/
490
491STATIC void
492SetPwrLevel (comet_t * comet)
493{
494 volatile u_int32_t temp;
495
496/*
497** Algorithm to Balance the Power Distribution of Ttip Tring
498**
499** Zero register F6
500** Write 0x01 to register F4
501** Write another 0x01 to register F4
502** Read register F4
503** Remove the 0x01 bit by Anding register F4 with 0xFE
504** Write the resultant value to register F4
505** Repeat these steps for register F5
506** Write 0x01 to register F6
507*/
508 pci_write_32 ((u_int32_t *) &comet->xlpg_fdata_sel, 0x00); /* XLPG Fuse Data Select */
509
510 pci_write_32 ((u_int32_t *) &comet->xlpg_atest_pctl, 0x01); /* XLPG Analog Test
511 * Positive control */
512 pci_write_32 ((u_int32_t *) &comet->xlpg_atest_pctl, 0x01);
513
514 temp = pci_read_32 ((u_int32_t *) &comet->xlpg_atest_pctl) & 0xfe;
515 pci_write_32 ((u_int32_t *) &comet->xlpg_atest_pctl, temp);
516
517 pci_write_32 ((u_int32_t *) &comet->xlpg_atest_nctl, 0x01); /* XLPG Analog Test
518 * Negative control */
519 pci_write_32 ((u_int32_t *) &comet->xlpg_atest_nctl, 0x01);
520
521 temp = pci_read_32 ((u_int32_t *) &comet->xlpg_atest_nctl) & 0xfe;
522 pci_write_32 ((u_int32_t *) &comet->xlpg_atest_nctl, temp);
523 pci_write_32 ((u_int32_t *) &comet->xlpg_fdata_sel, 0x01); /* XLPG */
524}
525
526
527/*
528** Name: SetCometOps
529** Description: Set up the selected Comet's clock edge drive for both
530** the transmit out the analog side and receive to the
531** backplane side.
532** Returns: Nothing
533*/
534#if 0
535STATIC void
536SetCometOps (comet_t * comet)
537{
538 volatile u_int8_t rd_value;
539
540 if (comet == mConfig.C4Func1Base + (COMET0_OFFSET >> 2))
541 {
542 rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_cfg); /* read the BRIF
543 * Configuration */
544 rd_value &= ~0x20;
545 pci_write_32 ((u_int32_t *) &comet->brif_cfg, (u_int32_t) rd_value);
546
547 rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_fpcfg); /* read the BRIF Frame
548 * Pulse Configuration */
549 rd_value &= ~0x20;
550 pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, (u_int8_t) rd_value);
551 } else
552 {
553 rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_cfg); /* read the BRIF
554 * Configuration */
555 rd_value |= 0x20;
556 pci_write_32 ((u_int32_t *) &comet->brif_cfg, (u_int32_t) rd_value);
557
558 rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_fpcfg); /* read the BRIF Frame
559 * Pulse Configuration */
560 rd_value |= 0x20;
561 pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, (u_int8_t) rd_value);
562 }
563}
564#endif
565
566/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/comet.h b/drivers/staging/cxt1e1/comet.h
new file mode 100644
index 00000000000..5cb3afda011
--- /dev/null
+++ b/drivers/staging/cxt1e1/comet.h
@@ -0,0 +1,366 @@
1/*
2 * $Id: comet.h,v 1.3 2005/09/28 00:10:07 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_COMET_H_
6#define _INC_COMET_H_
7
8/*-----------------------------------------------------------------------------
9 * comet.h -
10 *
11 * Copyright (C) 2005 SBE, Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * For further information, contact via email: support@sbei.com
24 * SBE, Inc. San Ramon, California U.S.A.
25 *-----------------------------------------------------------------------------
26 * RCS info:
27 * RCS revision: $Revision: 1.3 $
28 * Last changed on $Date: 2005/09/28 00:10:07 $
29 * Changed by $Author: rickd $
30 *-----------------------------------------------------------------------------
31 * $Log: comet.h,v $
32 * Revision 1.3 2005/09/28 00:10:07 rickd
33 * Add RCS header. Switch to structure usage.
34 *
35 * Revision 1.2 2005/04/28 23:43:03 rickd
36 * Add RCS tracking heading.
37 *
38 *-----------------------------------------------------------------------------
39 */
40
41#if defined(__FreeBSD__) || defined (__NetBSD__)
42#include <sys/types.h>
43#else
44#include <linux/types.h>
45#endif
46
47
48#define VINT32 volatile u_int32_t
49
50struct s_comet_reg
51{
52 VINT32 gbl_cfg; /* 00 Global Cfg */
53 VINT32 clkmon; /* 01 Clk Monitor */
54 VINT32 rx_opt; /* 02 RX Options */
55 VINT32 rx_line_cfg; /* 03 RX Line Interface Cfg */
56 VINT32 tx_line_cfg; /* 04 TX Line Interface Cfg */
57 VINT32 tx_frpass; /* 05 TX Framing & Bypass Options */
58 VINT32 tx_time; /* 06 TX Timing Options */
59 VINT32 intr_1; /* 07 Intr Source #1 */
60 VINT32 intr_2; /* 08 Intr Source #2 */
61 VINT32 intr_3; /* 09 Intr Source #3 */
62 VINT32 mdiag; /* 0A Master Diagnostics */
63 VINT32 mtest; /* 0B Master Test */
64 VINT32 adiag; /* 0C Analog Diagnostics */
65 VINT32 rev_id; /* 0D Rev/Chip Id/Global PMON Update */
66#define pmon rev_id
67 VINT32 reset; /* 0E Reset */
68 VINT32 prgd_phctl; /* 0F PRGD Positioning/Ctl & HDLC Ctl */
69 VINT32 cdrc_cfg; /* 10 CDRC Cfg */
70 VINT32 cdrc_ien; /* 11 CDRC Intr Enable */
71 VINT32 cdrc_ists; /* 12 CDRC Intr Sts */
72 VINT32 cdrc_alos; /* 13 CDRC Alternate Loss of Signal */
73
74 VINT32 rjat_ists; /* 14 RJAT Intr Sts */
75 VINT32 rjat_n1clk; /* 15 RJAT Reference Clk Divisor (N1) Ctl */
76 VINT32 rjat_n2clk; /* 16 RJAT Output Clk Divisor (N2) Ctl */
77 VINT32 rjat_cfg; /* 17 RJAT Cfg */
78
79 VINT32 tjat_ists; /* 18 TJAT Intr Sts */
80 VINT32 tjat_n1clk; /* 19 TJAT Reference Clk Divisor (N1) Ctl */
81 VINT32 tjat_n2clk; /* 1A TJAT Output Clk Divisor (N2) Ctl */
82 VINT32 tjat_cfg; /* 1B TJAT Cfg */
83
84 VINT32 rx_elst_cfg; /* 1C RX-ELST Cfg */
85 VINT32 rx_elst_ists; /* 1D RX-ELST Intr Sts */
86 VINT32 rx_elst_idle; /* 1E RX-ELST Idle Code */
87 VINT32 _rx_elst_res1f; /* 1F RX-ELST Reserved */
88
89 VINT32 tx_elst_cfg; /* 20 TX-ELST Cfg */
90 VINT32 tx_elst_ists; /* 21 TX-ELST Intr Sts */
91 VINT32 _tx_elst_res22; /* 22 TX-ELST Reserved */
92 VINT32 _tx_elst_res23; /* 23 TX-ELST Reserved */
93 VINT32 __res24; /* 24 Reserved */
94 VINT32 __res25; /* 25 Reserved */
95 VINT32 __res26; /* 26 Reserved */
96 VINT32 __res27; /* 27 Reserved */
97
98 VINT32 rxce1_ctl; /* 28 RXCE RX Data Link 1 Ctl */
99 VINT32 rxce1_bits; /* 29 RXCE RX Data Link 1 Bit Select */
100 VINT32 rxce2_ctl; /* 2A RXCE RX Data Link 2 Ctl */
101 VINT32 rxce2_bits; /* 2B RXCE RX Data Link 2 Bit Select */
102 VINT32 rxce3_ctl; /* 2C RXCE RX Data Link 3 Ctl */
103 VINT32 rxce3_bits; /* 2D RXCE RX Data Link 3 Bit Select */
104 VINT32 _rxce_res2E; /* 2E RXCE Reserved */
105 VINT32 _rxce_res2F; /* 2F RXCE Reserved */
106
107 VINT32 brif_cfg; /* 30 BRIF RX Backplane Cfg */
108 VINT32 brif_fpcfg; /* 31 BRIF RX Backplane Frame Pulse Cfg */
109 VINT32 brif_pfcfg; /* 32 BRIF RX Backplane Parity/F-Bit Cfg */
110 VINT32 brif_tsoff; /* 33 BRIF RX Backplane Time Slot Offset */
111 VINT32 brif_boff; /* 34 BRIF RX Backplane Bit Offset */
112 VINT32 _brif_res35; /* 35 BRIF RX Backplane Reserved */
113 VINT32 _brif_res36; /* 36 BRIF RX Backplane Reserved */
114 VINT32 _brif_res37; /* 37 BRIF RX Backplane Reserved */
115
116 VINT32 txci1_ctl; /* 38 TXCI TX Data Link 1 Ctl */
117 VINT32 txci1_bits; /* 39 TXCI TX Data Link 2 Bit Select */
118 VINT32 txci2_ctl; /* 3A TXCI TX Data Link 1 Ctl */
119 VINT32 txci2_bits; /* 3B TXCI TX Data Link 2 Bit Select */
120 VINT32 txci3_ctl; /* 3C TXCI TX Data Link 1 Ctl */
121 VINT32 txci3_bits; /* 3D TXCI TX Data Link 2 Bit Select */
122 VINT32 _txci_res3E; /* 3E TXCI Reserved */
123 VINT32 _txci_res3F; /* 3F TXCI Reserved */
124
125 VINT32 btif_cfg; /* 40 BTIF TX Backplane Cfg */
126 VINT32 btif_fpcfg; /* 41 BTIF TX Backplane Frame Pulse Cfg */
127 VINT32 btif_pcfgsts; /* 42 BTIF TX Backplane Parity Cfg & Sts */
128 VINT32 btif_tsoff; /* 43 BTIF TX Backplane Time Slot Offset */
129 VINT32 btif_boff; /* 44 BTIF TX Backplane Bit Offset */
130 VINT32 _btif_res45; /* 45 BTIF TX Backplane Reserved */
131 VINT32 _btif_res46; /* 46 BTIF TX Backplane Reserved */
132 VINT32 _btif_res47; /* 47 BTIF TX Backplane Reserved */
133 VINT32 t1_frmr_cfg; /* 48 T1 FRMR Cfg */
134 VINT32 t1_frmr_ien; /* 49 T1 FRMR Intr Enable */
135 VINT32 t1_frmr_ists; /* 4A T1 FRMR Intr Sts */
136 VINT32 __res_4B; /* 4B Reserved */
137 VINT32 ibcd_cfg; /* 4C IBCD Cfg */
138 VINT32 ibcd_ies; /* 4D IBCD Intr Enable/Sts */
139 VINT32 ibcd_act; /* 4E IBCD Activate Code */
140 VINT32 ibcd_deact; /* 4F IBCD Deactivate Code */
141
142 VINT32 sigx_cfg; /* 50 SIGX Cfg/Change of Signaling State */
143 VINT32 sigx_acc_cos; /* 51 SIGX uP Access Sts/Change of Signaling State */
144 VINT32 sigx_iac_cos; /* 52 SIGX Channel Indirect
145 * Addr/Ctl/Change of Signaling State */
146 VINT32 sigx_idb_cos; /* 53 SIGX Channel Indirect Data
147 * Buffer/Change of Signaling State */
148
149 VINT32 t1_xbas_cfg; /* 54 T1 XBAS Cfg */
150 VINT32 t1_xbas_altx; /* 55 T1 XBAS Alarm TX */
151 VINT32 t1_xibc_ctl; /* 56 T1 XIBC Ctl */
152 VINT32 t1_xibc_lbcode; /* 57 T1 XIBC Loopback Code */
153
154 VINT32 pmon_ies; /* 58 PMON Intr Enable/Sts */
155 VINT32 pmon_fberr; /* 59 PMON Framing Bit Err Cnt */
156 VINT32 pmon_feb_lsb; /* 5A PMON OFF/COFA/Far End Block Err Cnt (LSB) */
157 VINT32 pmon_feb_msb; /* 5B PMON OFF/COFA/Far End Block Err Cnt (MSB) */
158 VINT32 pmon_bed_lsb; /* 5C PMON Bit/Err/CRCE Cnt (LSB) */
159 VINT32 pmon_bed_msb; /* 5D PMON Bit/Err/CRCE Cnt (MSB) */
160 VINT32 pmon_lvc_lsb; /* 5E PMON LVC Cnt (LSB) */
161 VINT32 pmon_lvc_msb; /* 5F PMON LVC Cnt (MSB) */
162
163 VINT32 t1_almi_cfg; /* 60 T1 ALMI Cfg */
164 VINT32 t1_almi_ien; /* 61 T1 ALMI Intr Enable */
165 VINT32 t1_almi_ists; /* 62 T1 ALMI Intr Sts */
166 VINT32 t1_almi_detsts; /* 63 T1 ALMI Alarm Detection Sts */
167
168 VINT32 _t1_pdvd_res64; /* 64 T1 PDVD Reserved */
169 VINT32 t1_pdvd_ies; /* 65 T1 PDVD Intr Enable/Sts */
170 VINT32 _t1_xboc_res66; /* 66 T1 XBOC Reserved */
171 VINT32 t1_xboc_code; /* 67 T1 XBOC Code */
172 VINT32 _t1_xpde_res68; /* 68 T1 XPDE Reserved */
173 VINT32 t1_xpde_ies; /* 69 T1 XPDE Intr Enable/Sts */
174
175 VINT32 t1_rboc_ena; /* 6A T1 RBOC Enable */
176 VINT32 t1_rboc_sts; /* 6B T1 RBOC Code Sts */
177
178 VINT32 t1_tpsc_cfg; /* 6C TPSC Cfg */
179 VINT32 t1_tpsc_sts; /* 6D TPSC uP Access Sts */
180 VINT32 t1_tpsc_ciaddr; /* 6E TPSC Channel Indirect
181 * Addr/Ctl */
182 VINT32 t1_tpsc_cidata; /* 6F TPSC Channel Indirect Data
183 * Buffer */
184 VINT32 t1_rpsc_cfg; /* 70 RPSC Cfg */
185 VINT32 t1_rpsc_sts; /* 71 RPSC uP Access Sts */
186 VINT32 t1_rpsc_ciaddr; /* 72 RPSC Channel Indirect
187 * Addr/Ctl */
188 VINT32 t1_rpsc_cidata; /* 73 RPSC Channel Indirect Data
189 * Buffer */
190 VINT32 __res74; /* 74 Reserved */
191 VINT32 __res75; /* 75 Reserved */
192 VINT32 __res76; /* 76 Reserved */
193 VINT32 __res77; /* 77 Reserved */
194
195 VINT32 t1_aprm_cfg; /* 78 T1 APRM Cfg/Ctl */
196 VINT32 t1_aprm_load; /* 79 T1 APRM Manual Load */
197 VINT32 t1_aprm_ists; /* 7A T1 APRM Intr Sts */
198 VINT32 t1_aprm_1sec_2; /* 7B T1 APRM One Second Content Octet 2 */
199 VINT32 t1_aprm_1sec_3; /* 7C T1 APRM One Second Content Octet 3 */
200 VINT32 t1_aprm_1sec_4; /* 7D T1 APRM One Second Content Octet 4 */
201 VINT32 t1_aprm_1sec_5; /* 7E T1 APRM One Second Content MSB (Octect 5) */
202 VINT32 t1_aprm_1sec_6; /* 7F T1 APRM One Second Content MSB (Octect 6) */
203
204 VINT32 e1_tran_cfg; /* 80 E1 TRAN Cfg */
205 VINT32 e1_tran_txalarm; /* 81 E1 TRAN TX Alarm/Diagnostic Ctl */
206 VINT32 e1_tran_intctl; /* 82 E1 TRAN International Ctl */
207 VINT32 e1_tran_extrab; /* 83 E1 TRAN Extra Bits Ctl */
208 VINT32 e1_tran_ien; /* 84 E1 TRAN Intr Enable */
209 VINT32 e1_tran_ists; /* 85 E1 TRAN Intr Sts */
210 VINT32 e1_tran_nats; /* 86 E1 TRAN National Bit Codeword
211 * Select */
212 VINT32 e1_tran_nat; /* 87 E1 TRAN National Bit Codeword */
213 VINT32 __res88; /* 88 Reserved */
214 VINT32 __res89; /* 89 Reserved */
215 VINT32 __res8A; /* 8A Reserved */
216 VINT32 __res8B; /* 8B Reserved */
217
218 VINT32 _t1_frmr_res8C; /* 8C T1 FRMR Reserved */
219 VINT32 _t1_frmr_res8D; /* 8D T1 FRMR Reserved */
220 VINT32 __res8E; /* 8E Reserved */
221 VINT32 __res8F; /* 8F Reserved */
222
223 VINT32 e1_frmr_aopts; /* 90 E1 FRMR Frame Alignment Options */
224 VINT32 e1_frmr_mopts; /* 91 E1 FRMR Maintenance Mode Options */
225 VINT32 e1_frmr_ien; /* 92 E1 FRMR Framing Sts Intr Enable */
226 VINT32 e1_frmr_mien; /* 93 E1 FRMR Maintenance/Alarm Sts Intr Enable */
227 VINT32 e1_frmr_ists; /* 94 E1 FRMR Framing Sts Intr Indication */
228 VINT32 e1_frmr_mists; /* 95 E1 FRMR Maintenance/Alarm Sts Indication Enable */
229 VINT32 e1_frmr_sts; /* 96 E1 FRMR Framing Sts */
230 VINT32 e1_frmr_masts; /* 97 E1 FRMR Maintenance/Alarm Sts */
231 VINT32 e1_frmr_nat_bits; /* 98 E1 FRMR International/National Bits */
232 VINT32 e1_frmr_crc_lsb; /* 99 E1 FRMR CRC Err Cnt - LSB */
233 VINT32 e1_frmr_crc_msb; /* 9A E1 FRMR CRC Err Cnt - MSB */
234 VINT32 e1_frmr_nat_ien; /* 9B E1 FRMR National Bit Codeword Intr Enables */
235 VINT32 e1_frmr_nat_ists; /* 9C E1 FRMR National Bit Codeword Intr/Sts */
236 VINT32 e1_frmr_nat; /* 9D E1 FRMR National Bit Codewords */
237 VINT32 e1_frmr_fp_ien; /* 9E E1 FRMR Frame Pulse/Alarm Intr Enables */
238 VINT32 e1_frmr_fp_ists; /* 9F E1 FRMR Frame Pulse/Alarm Intr/Sts */
239
240 VINT32 __resA0; /* A0 Reserved */
241 VINT32 __resA1; /* A1 Reserved */
242 VINT32 __resA2; /* A2 Reserved */
243 VINT32 __resA3; /* A3 Reserved */
244 VINT32 __resA4; /* A4 Reserved */
245 VINT32 __resA5; /* A5 Reserved */
246 VINT32 __resA6; /* A6 Reserved */
247 VINT32 __resA7; /* A7 Reserved */
248
249 VINT32 tdpr1_cfg; /* A8 TDPR #1 Cfg */
250 VINT32 tdpr1_utl; /* A9 TDPR #1 Upper TX Threshold */
251 VINT32 tdpr1_ltl; /* AA TDPR #1 Lower TX Threshold */
252 VINT32 tdpr1_ien; /* AB TDPR #1 Intr Enable */
253 VINT32 tdpr1_ists; /* AC TDPR #1 Intr Sts/UDR Clear */
254 VINT32 tdpr1_data; /* AD TDPR #1 TX Data */
255 VINT32 __resAE; /* AE Reserved */
256 VINT32 __resAF; /* AF Reserved */
257 VINT32 tdpr2_cfg; /* B0 TDPR #2 Cfg */
258 VINT32 tdpr2_utl; /* B1 TDPR #2 Upper TX Threshold */
259 VINT32 tdpr2_ltl; /* B2 TDPR #2 Lower TX Threshold */
260 VINT32 tdpr2_ien; /* B3 TDPR #2 Intr Enable */
261 VINT32 tdpr2_ists; /* B4 TDPR #2 Intr Sts/UDR Clear */
262 VINT32 tdpr2_data; /* B5 TDPR #2 TX Data */
263 VINT32 __resB6; /* B6 Reserved */
264 VINT32 __resB7; /* B7 Reserved1 */
265 VINT32 tdpr3_cfg; /* B8 TDPR #3 Cfg */
266 VINT32 tdpr3_utl; /* B9 TDPR #3 Upper TX Threshold */
267 VINT32 tdpr3_ltl; /* BA TDPR #3 Lower TX Threshold */
268 VINT32 tdpr3_ien; /* BB TDPR #3 Intr Enable */
269 VINT32 tdpr3_ists; /* BC TDPR #3 Intr Sts/UDR Clear */
270 VINT32 tdpr3_data; /* BD TDPR #3 TX Data */
271 VINT32 __resBE; /* BE Reserved */
272 VINT32 __resBF; /* BF Reserved */
273
274 VINT32 rdlc1_cfg; /* C0 RDLC #1 Cfg */
275 VINT32 rdlc1_intctl; /* C1 RDLC #1 Intr Ctl */
276 VINT32 rdlc1_sts; /* C2 RDLC #1 Sts */
277 VINT32 rdlc1_data; /* C3 RDLC #1 Data */
278 VINT32 rdlc1_paddr; /* C4 RDLC #1 Primary Addr Match */
279 VINT32 rdlc1_saddr; /* C5 RDLC #1 Secondary Addr Match */
280 VINT32 __resC6; /* C6 Reserved */
281 VINT32 __resC7; /* C7 Reserved */
282 VINT32 rdlc2_cfg; /* C8 RDLC #2 Cfg */
283 VINT32 rdlc2_intctl; /* C9 RDLC #2 Intr Ctl */
284 VINT32 rdlc2_sts; /* CA RDLC #2 Sts */
285 VINT32 rdlc2_data; /* CB RDLC #2 Data */
286 VINT32 rdlc2_paddr; /* CC RDLC #2 Primary Addr Match */
287 VINT32 rdlc2_saddr; /* CD RDLC #2 Secondary Addr Match */
288 VINT32 __resCE; /* CE Reserved */
289 VINT32 __resCF; /* CF Reserved */
290 VINT32 rdlc3_cfg; /* D0 RDLC #3 Cfg */
291 VINT32 rdlc3_intctl; /* D1 RDLC #3 Intr Ctl */
292 VINT32 rdlc3_sts; /* D2 RDLC #3 Sts */
293 VINT32 rdlc3_data; /* D3 RDLC #3 Data */
294 VINT32 rdlc3_paddr; /* D4 RDLC #3 Primary Addr Match */
295 VINT32 rdlc3_saddr; /* D5 RDLC #3 Secondary Addr Match */
296
297 VINT32 csu_cfg; /* D6 CSU Cfg */
298 VINT32 _csu_resD7; /* D7 CSU Reserved */
299
300 VINT32 rlps_idata3; /* D8 RLPS Indirect Data, 24-31 */
301 VINT32 rlps_idata2; /* D9 RLPS Indirect Data, 16-23 */
302 VINT32 rlps_idata1; /* DA RLPS Indirect Data, 8-15 */
303 VINT32 rlps_idata0; /* DB RLPS Indirect Data, 0-7 */
304 VINT32 rlps_eqvr; /* DC RLPS Equalizer Voltage Reference
305 * (E1 missing) */
306 VINT32 _rlps_resDD; /* DD RLPS Reserved */
307 VINT32 _rlps_resDE; /* DE RLPS Reserved */
308 VINT32 _rlps_resDF; /* DF RLPS Reserved */
309
310 VINT32 prgd_ctl; /* E0 PRGD Ctl */
311 VINT32 prgd_ies; /* E1 PRGD Intr Enable/Sts */
312 VINT32 prgd_shift_len; /* E2 PRGD Shift Length */
313 VINT32 prgd_tap; /* E3 PRGD Tap */
314 VINT32 prgd_errin; /* E4 PRGD Err Insertion */
315 VINT32 _prgd_resE5; /* E5 PRGD Reserved */
316 VINT32 _prgd_resE6; /* E6 PRGD Reserved */
317 VINT32 _prgd_resE7; /* E7 PRGD Reserved */
318 VINT32 prgd_patin1; /* E8 PRGD Pattern Insertion #1 */
319 VINT32 prgd_patin2; /* E9 PRGD Pattern Insertion #2 */
320 VINT32 prgd_patin3; /* EA PRGD Pattern Insertion #3 */
321 VINT32 prgd_patin4; /* EB PRGD Pattern Insertion #4 */
322 VINT32 prgd_patdet1; /* EC PRGD Pattern Detector #1 */
323 VINT32 prgd_patdet2; /* ED PRGD Pattern Detector #2 */
324 VINT32 prgd_patdet3; /* EE PRGD Pattern Detector #3 */
325 VINT32 prgd_patdet4; /* EF PRGD Pattern Detector #4 */
326
327 VINT32 xlpg_cfg; /* F0 XLPG Line Driver Cfg */
328 VINT32 xlpg_ctlsts; /* F1 XLPG Ctl/Sts */
329 VINT32 xlpg_pwave_addr; /* F2 XLPG Pulse Waveform Storage Write Addr */
330 VINT32 xlpg_pwave_data; /* F3 XLPG Pulse Waveform Storage Data */
331 VINT32 xlpg_atest_pctl; /* F4 XLPG Analog Test Positive Ctl */
332 VINT32 xlpg_atest_nctl; /* F5 XLPG Analog Test Negative Ctl */
333 VINT32 xlpg_fdata_sel; /* F6 XLPG Fuse Data Select */
334 VINT32 _xlpg_resF7; /* F7 XLPG Reserved */
335
336 VINT32 rlps_cfgsts; /* F8 RLPS Cfg & Sts */
337 VINT32 rlps_alos_thresh; /* F9 RLPS ALOS Detection/Clearance Threshold */
338 VINT32 rlps_alos_dper; /* FA RLPS ALOS Detection Period */
339 VINT32 rlps_alos_cper; /* FB RLPS ALOS Clearance Period */
340 VINT32 rlps_eq_iaddr; /* FC RLPS Equalization Indirect Addr */
341 VINT32 rlps_eq_rwsel; /* FD RLPS Equalization Read/WriteB Select */
342 VINT32 rlps_eq_ctlsts; /* FE RLPS Equalizer Loop Sts & Ctl */
343 VINT32 rlps_eq_cfg; /* FF RLPS Equalizer Cfg */
344};
345
346typedef struct s_comet_reg comet_t;
347
348/* 00AH: MDIAG Register bit definitions */
349#define COMET_MDIAG_ID5 0x40
350#define COMET_MDIAG_LBMASK 0x3F
351#define COMET_MDIAG_PAYLB 0x20
352#define COMET_MDIAG_LINELB 0x10
353#define COMET_MDIAG_RAIS 0x08
354#define COMET_MDIAG_DDLB 0x04
355#define COMET_MDIAG_TXMFP 0x02
356#define COMET_MDIAG_TXLOS 0x01
357#define COMET_MDIAG_LBOFF 0x00
358
359#undef VINT32
360
361#ifdef __KERNEL__
362extern void
363init_comet (void *, comet_t *, u_int32_t, int, u_int8_t);
364#endif
365
366#endif /* _INC_COMET_H_ */
diff --git a/drivers/staging/cxt1e1/comet_tables.c b/drivers/staging/cxt1e1/comet_tables.c
new file mode 100644
index 00000000000..db1293c71a6
--- /dev/null
+++ b/drivers/staging/cxt1e1/comet_tables.c
@@ -0,0 +1,561 @@
1/*
2 * $Id: comet_tables.c,v 1.2 2005/10/17 23:55:27 rickd PMCC4_3_1B $
3 */
4
5/*-----------------------------------------------------------------------------
6 * comet_tables.c - waveform tables for the PM4351 'COMET'
7 *
8 * Copyright (C) 2003-2005 SBE, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * For further information, contact via email: support@sbei.com
21 * SBE, Inc. San Ramon, California U.S.A.
22 *-----------------------------------------------------------------------------
23 * RCS info:
24 * RCS revision: $Revision: 1.2 $
25 * Last changed on $Date: 2005/10/17 23:55:27 $
26 * Changed by $Author: rickd $
27 *-----------------------------------------------------------------------------
28 * $Log: comet_tables.c,v $
29 * Revision 1.2 2005/10/17 23:55:27 rickd
30 * Note that 75 Ohm transmit waveform is not supported on PMCC4.
31 *
32 * Revision 1.1 2005/09/28 00:10:05 rickd
33 * Cosmetic alignment of tables for readability.
34 *
35 * Revision 1.0 2005/05/10 22:47:53 rickd
36 * Initial revision
37 *
38 *-----------------------------------------------------------------------------
39 */
40
41char SBEid_pmcc4_comet_tblc[] =
42 "@(#)comet_tables.c - $Revision: 1.2 $ (c) Copyright 2004-2005 SBE, Inc.";
43
44
45#include <linux/types.h>
46
47/*****************************************************************************
48*
49* Array names:
50*
51* TWVLongHaul0DB
52* TWVLongHaul7_5DB
53* TWVLongHaul15DB
54* TWVLongHaul22_5DB
55* TWVShortHaul0
56* TWVShortHaul1
57* TWVShortHaul2
58* TWVShortHaul3
59* TWVShortHaul4
60* TWVShortHaul5
61* TWV_E1_120Ohm
62* TWV_E1_75Ohm <not supported>
63* T1_Equalizer
64* E1_Equalizer
65*
66*****************************************************************************/
67
68u_int8_t TWVLongHaul0DB[25][5] =/* T1 Long Haul 0 DB */
69{
70 {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
71 {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
72 {0x20, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
73 {0x32, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
74 {0x3E, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
75 {0x3D, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
76 {0x3C, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
77 {0x3B, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
78 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
79 {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
80 {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
81 {0x38, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
82 {0x37, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
83 {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
84 {0x34, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
85 {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
86 {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
87 {0x4C, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
88 {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
89 {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
90 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
91 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
92 {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
93 {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
94 {0x0C} /* PMC's suggested value */
95/* {0x14} Output Amplitude */
96};
97
98u_int8_t TWVLongHaul7_5DB[25][5] = /* T1 Long Haul 7.5 DB */
99{
100 {0x00, 0x10, 0x00, 0x00, 0x00}, /* Sample 0 */
101 {0x01, 0x0E, 0x00, 0x00, 0x00}, /* Sample 1 */
102 {0x02, 0x0C, 0x00, 0x00, 0x00}, /* Sample 2 */
103 {0x04, 0x0A, 0x00, 0x00, 0x00}, /* Sample 3 */
104 {0x08, 0x08, 0x00, 0x00, 0x00}, /* Sample 4 */
105 {0x0C, 0x06, 0x00, 0x00, 0x00}, /* Sample 5 */
106 {0x10, 0x04, 0x00, 0x00, 0x00}, /* Sample 6 */
107 {0x16, 0x02, 0x00, 0x00, 0x00}, /* Sample 7 */
108 {0x1A, 0x01, 0x00, 0x00, 0x00}, /* Sample 8 */
109 {0x1E, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
110 {0x22, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
111 {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
112 {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
113 {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
114 {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
115 {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
116 {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
117 {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
118 {0x24, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
119 {0x20, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
120 {0x1C, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
121 {0x18, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
122 {0x14, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
123 {0x12, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
124 {0x07} /* PMC's suggested value */
125/* { 0x0A } Output Amplitude */
126};
127
128u_int8_t TWVLongHaul15DB[25][5] = /* T1 Long Haul 15 DB */
129{
130 {0x00, 0x2A, 0x09, 0x01, 0x00}, /* Sample 0 */
131 {0x00, 0x28, 0x08, 0x01, 0x00}, /* Sample 1 */
132 {0x00, 0x26, 0x08, 0x01, 0x00}, /* Sample 2 */
133 {0x00, 0x24, 0x07, 0x01, 0x00}, /* Sample 3 */
134 {0x01, 0x22, 0x07, 0x01, 0x00}, /* Sample 4 */
135 {0x02, 0x20, 0x06, 0x01, 0x00}, /* Sample 5 */
136 {0x04, 0x1E, 0x06, 0x01, 0x00}, /* Sample 6 */
137 {0x07, 0x1C, 0x05, 0x00, 0x00}, /* Sample 7 */
138 {0x0A, 0x1B, 0x05, 0x00, 0x00}, /* Sample 8 */
139 {0x0D, 0x19, 0x05, 0x00, 0x00}, /* Sample 9 */
140 {0x10, 0x18, 0x04, 0x00, 0x00}, /* Sample 10 */
141 {0x14, 0x16, 0x04, 0x00, 0x00}, /* Sample 11 */
142 {0x18, 0x15, 0x04, 0x00, 0x00}, /* Sample 12 */
143 {0x1B, 0x13, 0x03, 0x00, 0x00}, /* Sample 13 */
144 {0x1E, 0x12, 0x03, 0x00, 0x00}, /* Sample 14 */
145 {0x21, 0x10, 0x03, 0x00, 0x00}, /* Sample 15 */
146 {0x24, 0x0F, 0x03, 0x00, 0x00}, /* Sample 16 */
147 {0x27, 0x0D, 0x03, 0x00, 0x00}, /* Sample 17 */
148 {0x2A, 0x0D, 0x02, 0x00, 0x00}, /* Sample 18 */
149 {0x2D, 0x0B, 0x02, 0x00, 0x00}, /* Sample 19 */
150 {0x30, 0x0B, 0x02, 0x00, 0x00}, /* Sample 20 */
151 {0x30, 0x0A, 0x02, 0x00, 0x00}, /* Sample 21 */
152 {0x2E, 0x0A, 0x02, 0x00, 0x00}, /* Sample 22 */
153 {0x2C, 0x09, 0x02, 0x00, 0x00}, /* Sample 23 */
154 {0x03} /* Output Amplitude */
155};
156
157u_int8_t TWVLongHaul22_5DB[25][5] = /* T1 Long Haul 22.5 DB */
158{
159 {0x00, 0x1F, 0x16, 0x06, 0x01}, /* Sample 0 */
160 {0x00, 0x20, 0x15, 0x05, 0x01}, /* Sample 1 */
161 {0x00, 0x21, 0x15, 0x05, 0x01}, /* Sample 2 */
162 {0x00, 0x22, 0x14, 0x05, 0x01}, /* Sample 3 */
163 {0x00, 0x22, 0x13, 0x04, 0x00}, /* Sample 4 */
164 {0x00, 0x23, 0x12, 0x04, 0x00}, /* Sample 5 */
165 {0x01, 0x23, 0x12, 0x04, 0x00}, /* Sample 6 */
166 {0x01, 0x24, 0x11, 0x03, 0x00}, /* Sample 7 */
167 {0x01, 0x23, 0x10, 0x03, 0x00}, /* Sample 8 */
168 {0x02, 0x23, 0x10, 0x03, 0x00}, /* Sample 9 */
169 {0x03, 0x22, 0x0F, 0x03, 0x00}, /* Sample 10 */
170 {0x05, 0x22, 0x0E, 0x03, 0x00}, /* Sample 11 */
171 {0x07, 0x21, 0x0E, 0x02, 0x00}, /* Sample 12 */
172 {0x09, 0x20, 0x0D, 0x02, 0x00}, /* Sample 13 */
173 {0x0B, 0x1E, 0x0C, 0x02, 0x00}, /* Sample 14 */
174 {0x0E, 0x1D, 0x0C, 0x02, 0x00}, /* Sample 15 */
175 {0x10, 0x1B, 0x0B, 0x02, 0x00}, /* Sample 16 */
176 {0x13, 0x1B, 0x0A, 0x02, 0x00}, /* Sample 17 */
177 {0x15, 0x1A, 0x0A, 0x02, 0x00}, /* Sample 18 */
178 {0x17, 0x19, 0x09, 0x01, 0x00}, /* Sample 19 */
179 {0x19, 0x19, 0x08, 0x01, 0x00}, /* Sample 20 */
180 {0x1B, 0x18, 0x08, 0x01, 0x00}, /* Sample 21 */
181 {0x1D, 0x17, 0x07, 0x01, 0x00}, /* Sample 22 */
182 {0x1E, 0x17, 0x06, 0x01, 0x00}, /* Sample 23 */
183 {0x02} /* Output Amplitude */
184};
185
186u_int8_t TWVShortHaul0[25][5] = /* T1 Short Haul 0 - 110 ft */
187{
188 {0x00, 0x45, 0x00, 0x00, 0x00}, /* Sample 0 */
189 {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
190 {0x20, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
191 {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
192 {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
193 {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
194 {0x3C, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
195 {0x3B, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
196 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
197 {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
198 {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
199 {0x38, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
200 {0x37, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
201 {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
202 {0x34, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
203 {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
204 {0x59, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
205 {0x55, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
206 {0x50, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
207 {0x4D, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
208 {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
209 {0x48, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
210 {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
211 {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
212 {0x0C} /* Output Amplitude */
213};
214
215u_int8_t TWVShortHaul1[25][5] = /* T1 Short Haul 110 - 220 ft */
216{
217 {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
218 {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
219 {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
220 {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
221 {0x36, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
222 {0x34, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
223 {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
224 {0x2F, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
225 {0x2E, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
226 {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
227 {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
228 {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
229 {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
230 {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
231 {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
232 {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
233 {0x68, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
234 {0x54, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
235 {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
236 {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
237 {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
238 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
239 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
240 {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
241 {0x10} /* Output Amplitude */
242};
243
244u_int8_t TWVShortHaul2[25][5] = /* T1 Short Haul 220 - 330 ft */
245{
246 {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
247 {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
248 {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
249 {0x3A, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
250 {0x3A, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
251 {0x38, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
252 {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
253 {0x2F, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
254 {0x2E, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
255 {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
256 {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
257 {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
258 {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
259 {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
260 {0x23, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
261 {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
262 {0x6C, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
263 {0x60, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
264 {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
265 {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
266 {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
267 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
268 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
269 {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
270 {0x11} /* Output Amplitude */
271};
272
273u_int8_t TWVShortHaul3[25][5] = /* T1 Short Haul 330 - 440 ft */
274{
275 {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
276 {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
277 {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
278 {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
279 {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
280 {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
281 {0x2F, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
282 {0x2E, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
283 {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
284 {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
285 {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
286 {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
287 {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
288 {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
289 {0x19, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
290 {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
291 {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
292 {0x60, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
293 {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
294 {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
295 {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
296 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
297 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
298 {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
299 {0x12} /* Output Amplitude */
300};
301
302u_int8_t TWVShortHaul4[25][5] = /* T1 Short Haul 440 - 550 ft */
303{
304 {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
305 {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
306 {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
307 {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
308 {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
309 {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
310 {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
311 {0x2B, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
312 {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
313 {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
314 {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
315 {0x27, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
316 {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
317 {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
318 {0x24, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
319 {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
320 {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
321 {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
322 {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
323 {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
324 {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
325 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
326 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
327 {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
328 {0x14} /* Output Amplitude */
329};
330
331u_int8_t TWVShortHaul5[25][5] = /* T1 Short Haul 550 - 660 ft */
332{
333 {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
334 {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
335 {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
336 {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
337 {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
338 {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
339 {0x3F, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
340 {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
341 {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
342 {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
343 {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
344 {0x27, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
345 {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
346 {0x25, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
347 {0x24, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
348 {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
349 {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
350 {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
351 {0x5F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
352 {0x50, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
353 {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
354 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
355 {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
356 {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
357 {0x15} /* Output Amplitude */
358};
359
360u_int8_t TWV_E1_120Ohm[25][5] = /* E1 120 Ohm */
361{
362 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 0 */
363 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 1 */
364 {0x0A, 0x00, 0x00, 0x00, 0x00}, /* Sample 2 */
365 {0x3F, 0x00, 0x00, 0x00, 0x00}, /* Sample 3 */
366 {0x3F, 0x00, 0x00, 0x00, 0x00}, /* Sample 4 */
367 {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 5 */
368 {0x38, 0x00, 0x00, 0x00, 0x00}, /* Sample 6 */
369 {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 7 */
370 {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
371 {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
372 {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
373 {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
374 {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
375 {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
376 {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
377 {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
378 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
379 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
380 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
381 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
382 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
383 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
384 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
385 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
386 {0x0C} /* PMC's suggested value */
387/* { 0x10 } Output Amplitude */
388};
389
390
391
392u_int8_t TWV_E1_75Ohm[25][5] = /* E1 75 Ohm */
393{
394#ifdef PMCC4_DOES_NOT_SUPPORT
395 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 0 */
396 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 1 */
397 {0x0A, 0x00, 0x00, 0x00, 0x00}, /* Sample 2 */
398 {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 3 */
399 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 4 */
400 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 5 */
401 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 6 */
402 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 7 */
403 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
404 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
405 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
406 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
407 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
408 {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
409 {0x32, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
410 {0x14, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
411 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
412 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
413 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
414 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
415 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
416 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
417 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
418 {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
419#endif
420 {0x0C} /* Output Amplitude */
421};
422
423
424u_int32_t T1_Equalizer[256] = /* T1 Receiver Equalizer */
425{
426 0x03FE1840, 0x03F61840, 0x03EE1840, 0x03E61840, /* 000 - 003 */
427 0x03DE1840, 0x03D61840, 0x03D61840, 0x03D61840, /* 004 - 007 */
428 0x03CE1840, 0x03CE1840, 0x03CE1840, 0x03CE1840, /* 008 - 011 */
429 0x03C61840, 0x03C61840, 0x03C61840, 0x0BBE1840, /* 012 - 015 */
430 0x0BBE1840, 0x0BBE1840, 0x0BBE1840, 0x0BB61840, /* 016 - 019 */
431 0x0BB61840, 0x0BB61840, 0x0BB61840, 0x13AE1838, /* 020 - 023 */
432 0x13AE183C, 0x13AE1840, 0x13AE1840, 0x13AE1840, /* 024 - 027 */
433 0x13AE1840, 0x1BB618B8, 0x1BAE18B8, 0x1BAE18BC, /* 028 - 031 */
434 0x1BAE18C0, 0x1BAE18C0, 0x23A618C0, 0x23A618C0, /* 032 - 035 */
435 0x23A618C0, 0x23A618C0, 0x23A618C0, 0x239E18C0, /* 036 - 039 */
436 0x239E18C0, 0x239E18C0, 0x239E18C0, 0x239E18C0, /* 040 - 043 */
437 0x2B9618C0, 0x2B9618C0, 0x2B9618C0, 0x33961940, /* 044 - 047 */
438 0x37961940, 0x37961940, 0x37961940, 0x3F9E19C0, /* 048 - 051 */
439 0x3F9E19C0, 0x3F9E19C0, 0x3FA61A40, 0x3FA61A40, /* 052 - 055 */
440 0x3FA61A40, 0x3FA61A40, 0x3F9619C0, 0x3F9619C0, /* 056 - 059 */
441 0x3F9619C0, 0x3F9619C0, 0x479E1A40, 0x479E1A40, /* 060 - 063 */
442 0x479E1A40, 0x47961A40, 0x47961A40, 0x47961A40, /* 064 - 067 */
443 0x47961A40, 0x4F8E1A40, 0x4F8E1A40, 0x4F8E1A40, /* 068 - 071 */
444 0x4F8E1A40, 0x4F8E1A40, 0x57861A40, 0x57861A40, /* 072 - 075 */
445 0x57861A40, 0x57861A40, 0x57861A40, 0x5F861AC0, /* 076 - 079 */
446 0x5F861AC0, 0x5F861AC0, 0x5F861AC0, 0x5F861AC0, /* 080 - 083 */
447 0x5F861AC0, 0x5F7E1AC0, 0x5F7E1AC0, 0x5F7E1AC0, /* 084 - 087 */
448 0x5F7E1AC0, 0x5F7E1AC0, 0x677E2AC0, 0x677E2AC0, /* 088 - 091 */
449 0x677E2AC0, 0x677E2AC0, 0x67762AC0, 0x67762AC0, /* 092 - 095 */
450 0x67762AC0, 0x67762AC0, 0x67762AC0, 0x6F6E2AC0, /* 096 - 099 */
451 0x6F6E2AC0, 0x6F6E2AC0, 0x6F6E2AC0, 0x776E3AC0, /* 100 - 103 */
452 0x776E3AC0, 0x776E3AC0, 0x776E3AC0, 0x7F663AC0, /* 104 - 107 */
453 0x7F663AC0, 0x7F664AC0, 0x7F664AC0, 0x7F664AC0, /* 108 - 111 */
454 0x7F664AC0, 0x87665AC0, 0x87665AC0, 0x87665AC0, /* 112 - 115 */
455 0x87665AC0, 0x87665AC0, 0x875E5AC0, 0x875E5AC0, /* 116 - 119 */
456 0x875E5AC0, 0x875E5AC0, 0x875E5AC0, 0x8F5E6AC0, /* 120 - 123 */
457 0x8F5E6AC0, 0x8F5E6AC0, 0x8F5E6AC0, 0x975E7AC0, /* 124 - 127 */
458 0x975E7AC0, 0x975E7AC0, 0x975E7AC0, 0x9F5E8AC0, /* 128 - 131 */
459 0x9F5E8AC0, 0x9F5E8AC0, 0x9F5E8AC0, 0x9F5E8AC0, /* 132 - 135 */
460 0xA7569AC0, 0xA7569AC0, 0xA7569AC0, 0xA7569AC0, /* 136 - 139 */
461 0xA756AAC0, 0xA756AAC0, 0xA756AAC0, 0xAF4EAAC0, /* 140 - 143 */
462 0xAF4EAAC0, 0xAF4EAAC0, 0xAF4EAAC0, 0xAF4EAAC0, /* 144 - 147 */
463 0xB746AAC0, 0xB746AAC0, 0xB746AAC0, 0xB746AAC0, /* 148 - 151 */
464 0xB746AAC0, 0xB746AAC0, 0xB746AAC0, 0xB746BAC0, /* 152 - 155 */
465 0xB746BAC0, 0xB746BAC0, 0xBF4EBB40, 0xBF4EBB40, /* 156 - 159 */
466 0xBF4EBB40, 0xBF4EBB40, 0xBF4EBB40, 0xBF4EBB40, /* 160 - 163 */
467 0xBF4EBB40, 0xBF4EBB40, 0xBF4EBB40, 0xBE46CB40, /* 164 - 167 */
468 0xBE46CB40, 0xBE46CB40, 0xBE46CB40, 0xBE46CB40, /* 168 - 171 */
469 0xBE46CB40, 0xBE46DB40, 0xBE46DB40, 0xBE46DB40, /* 172 - 175 */
470 0xC63ECB40, 0xC63ECB40, 0xC63EDB40, 0xC63EDB40, /* 176 - 179 */
471 0xC63EDB40, 0xC644DB40, 0xC644DB40, 0xC644DB40, /* 180 - 183 */
472 0xC644DB40, 0xC63CDB40, 0xC63CDB40, 0xC63CDB40, /* 184 - 187 */
473 0xC63CDB40, 0xD634DB40, 0xD634DB40, 0xD634DB40, /* 188 - 191 */
474 0xD634DB40, 0xD634DB40, 0xDE2CDB3C, 0xDE2CDB3C, /* 192 - 195 */
475 0xDE2CDB3C, 0xE62CDB40, 0xE62CDB40, 0xE62CDB40, /* 196 - 199 */
476 0xE62CDB40, 0xE62CDB40, 0xE62CEB40, 0xE62CEB40, /* 200 - 203 */
477 0xE62CEB40, 0xEE2CFB40, 0xEE2CFB40, 0xEE2CFB40, /* 204 - 207 */
478 0xEE2D0B40, 0xEE2D0B40, 0xEE2D0B40, 0xEE2D0B40, /* 208 - 211 */
479 0xEE2D0B40, 0xF5250B38, 0xF5250B3C, 0xF5250B40, /* 212 - 215 */
480 0xF5251B40, 0xF5251B40, 0xF5251B40, 0xF5251B40, /* 216 - 219 */
481 0xF5251B40, 0xFD252B40, 0xFD252B40, 0xFD252B40, /* 220 - 223 */
482 0xFD252B40, 0xFD252740, 0xFD252740, 0xFD252740, /* 224 - 227 */
483 0xFD252340, 0xFD252340, 0xFD252340, 0xFD253340, /* 228 - 231 */
484 0xFD253340, 0xFD253340, 0xFD253340, 0xFD253340, /* 232 - 235 */
485 0xFD253340, 0xFD253340, 0xFD253340, 0xFC254340, /* 236 - 239 */
486 0xFD254340, 0xFD254340, 0xFD254344, 0xFC254348, /* 240 - 243 */
487 0xFC25434C, 0xFD2543BC, 0xFD2543C0, 0xFC2543C0, /* 244 - 247 */
488 0xFC2343C0, 0xFC2343C0, 0xFD2343C0, 0xFC2143C0, /* 248 - 251 */
489 0xFC2143C0, 0xFC2153C0, 0xFD2153C0, 0xFC2153C0 /* 252 - 255 */
490};
491
492
493u_int32_t E1_Equalizer[256] = /* E1 Receiver Equalizer */
494{
495 0x07DE182C, 0x07DE182C, 0x07D6182C, 0x07D6182C, /* 000 - 003 */
496 0x07D6182C, 0x07CE182C, 0x07CE182C, 0x07CE182C, /* 004 - 007 */
497 0x07C6182C, 0x07C6182C, 0x07C6182C, 0x07BE182C, /* 008 - 011 */
498 0x07BE182C, 0x07BE182C, 0x07BE182C, 0x07BE182C, /* 012 - 015 */
499 0x07B6182C, 0x07B6182C, 0x07B6182C, 0x07B6182C, /* 016 - 019 */
500 0x07B6182C, 0x07AE182C, 0x07AE182C, 0x07AE182C, /* 020 - 023 */
501 0x07AE182C, 0x07AE182C, 0x07B618AC, 0x07AE18AC, /* 024 - 027 */
502 0x07AE18AC, 0x07AE18AC, 0x07AE18AC, 0x07A618AC, /* 028 - 031 */
503 0x07A618AC, 0x07A618AC, 0x07A618AC, 0x079E18AC, /* 032 - 035 */
504 0x07A6192C, 0x07A6192C, 0x07A6192C, 0x0FA6192C, /* 036 - 039 */
505 0x0FA6192C, 0x0F9E192C, 0x0F9E192C, 0x0F9E192C, /* 040 - 043 */
506 0x179E192C, 0x17A619AC, 0x179E19AC, 0x179E19AC, /* 044 - 047 */
507 0x179619AC, 0x1F9619AC, 0x1F9619AC, 0x1F8E19AC, /* 048 - 051 */
508 0x1F8E19AC, 0x1F8E19AC, 0x278E19AC, 0x278E1A2C, /* 052 - 055 */
509 0x278E1A2C, 0x278E1A2C, 0x278E1A2C, 0x2F861A2C, /* 056 - 059 */
510 0x2F861A2C, 0x2F861A2C, 0x2F7E1A2C, 0x2F7E1A2C, /* 060 - 063 */
511 0x2F7E1A2C, 0x377E1A2C, 0x377E1AAC, 0x377E1AAC, /* 064 - 067 */
512 0x377E1AAC, 0x377E1AAC, 0x3F7E2AAC, 0x3F7E2AAC, /* 068 - 071 */
513 0x3F762AAC, 0x3F862B2C, 0x3F7E2B2C, 0x477E2B2C, /* 072 - 075 */
514 0x477E2F2C, 0x477E2F2C, 0x477E2F2C, 0x47762F2C, /* 076 - 079 */
515 0x4F762F2C, 0x4F762F2C, 0x4F6E2F2C, 0x4F6E2F2C, /* 080 - 083 */
516 0x4F6E2F2C, 0x576E2F2C, 0x576E2F2C, 0x576E3F2C, /* 084 - 087 */
517 0x576E3F2C, 0x576E3F2C, 0x5F6E3F2C, 0x5F6E4F2C, /* 088 - 091 */
518 0x5F6E4F2C, 0x5F6E4F2C, 0x5F664F2C, 0x67664F2C, /* 092 - 095 */
519 0x67664F2C, 0x675E4F2C, 0x675E4F2C, 0x67664F2C, /* 096 - 099 */
520 0x67664F2C, 0x67665F2C, 0x6F6E5F2C, 0x6F6E6F2C, /* 100 - 103 */
521 0x6F6E6F2C, 0x6F6E7F2C, 0x6F6E7F2C, 0x6F6E7F2C, /* 104 - 107 */
522 0x77667F2C, 0x77667F2C, 0x775E6F2C, 0x775E7F2C, /* 108 - 111 */
523 0x775E7F2C, 0x7F5E7F2C, 0x7F5E8F2C, 0x7F5E8F2C, /* 112 - 115 */
524 0x7F5E8F2C, 0x87568F2C, 0x87568F2C, 0x87568F2C, /* 116 - 119 */
525 0x874E8F2C, 0x874E8F2C, 0x874E8F2C, 0x8F4E9F2C, /* 120 - 123 */
526 0x8F4E9F2C, 0x8F4EAF2C, 0x8F4EAF2C, 0x8F4EAF2C, /* 124 - 127 */
527 0x974EAF2C, 0x974EAF2C, 0x974EAB2C, 0x974EAB2C, /* 128 - 131 */
528 0x974EAB2C, 0x9F4EAB2C, 0x9F4EBB2C, 0x9F4EBB2C, /* 132 - 135 */
529 0x9F4EBB2C, 0x9F4ECB2C, 0xA74ECB2C, 0xA74ECB2C, /* 136 - 139 */
530 0xA746CB2C, 0xA746CB2C, 0xA746CB2C, 0xA746DB2C, /* 140 - 143 */
531 0xAF46DB2C, 0xAF46EB2C, 0xAF46EB2C, 0xAF4EEB2C, /* 144 - 147 */
532 0xAE4EEB2C, 0xAE4EEB2C, 0xB546FB2C, 0xB554FB2C, /* 148 - 151 */
533 0xB54CEB2C, 0xB554FB2C, 0xB554FB2C, 0xBD54FB2C, /* 152 - 155 */
534 0xBD4CFB2C, 0xBD4CFB2C, 0xBD4CFB2C, 0xBD44EB2C, /* 156 - 159 */
535 0xC544FB2C, 0xC544FB2C, 0xC544FB2C, 0xC5450B2C, /* 160 - 163 */
536 0xC5450B2C, 0xC5450B2C, 0xCD450B2C, 0xCD450B2C, /* 164 - 167 */
537 0xCD3D0B2C, 0xCD3D0B2C, 0xCD3D0B2C, 0xD53D0B2C, /* 168 - 171 */
538 0xD53D0B2C, 0xD53D1B2C, 0xD53D1B2C, 0xD53D1B2C, /* 172 - 175 */
539 0xDD3D1B2C, 0xDD3D1B2C, 0xDD351B2C, 0xDD351B2C, /* 176 - 179 */
540 0xDD351B2C, 0xE5351B2C, 0xE5351B2C, 0xE52D1B2C, /* 180 - 183 */
541 0xE52D1B2C, 0xE52D3B2C, 0xED2D4B2C, 0xED2D1BA8, /* 184 - 187 */
542 0xED2D1BAC, 0xED2D17AC, 0xED2D17AC, 0xED2D27AC, /* 188 - 191 */
543 0xF52D27AC, 0xF52D27AC, 0xF52D2BAC, 0xF52D2BAC, /* 192 - 195 */
544 0xF52D2BAC, 0xFD2D2BAC, 0xFD2B2BAC, 0xFD2B2BAC, /* 196 - 199 */
545 0xFD2B2BAC, 0xFD2B2BAC, 0xFD232BAC, 0xFD232BAC, /* 200 - 203 */
546 0xFD232BAC, 0xFD212BAC, 0xFD212BAC, 0xFD292BAC, /* 204 - 207 */
547 0xFD292BAC, 0xFD2927AC, 0xFD2937AC, 0xFD2923AC, /* 208 - 211 */
548 0xFD2923AC, 0xFD2923AC, 0xFD2923AC, 0xFD2123AC, /* 212 - 215 */
549 0xFD2123AC, 0xFD2123AC, 0xFD2133AC, 0xFD2133AC, /* 216 - 219 */
550 0xFD2133AC, 0xFD2143AC, 0xFD2143AC, 0xFD2143AC, /* 220 - 223 */
551 0xFC2143AC, 0xFC2143AC, 0xFC1943AC, 0xFC1943AC, /* 224 - 227 */
552 0xFC1943AC, 0xFC1943AC, 0xFC1953AC, 0xFC1953AC, /* 228 - 231 */
553 0xFC1953AC, 0xFC1953AC, 0xFC1963AC, 0xFC1963AC, /* 232 - 235 */
554 0xFC1963AC, 0xFC1973AC, 0xFC1973AC, 0xFC1973AC, /* 236 - 239 */
555 0xFC1973AC, 0xFC1973AC, 0xFC1983AC, 0xFC1983AC, /* 240 - 243 */
556 0xFC1983AC, 0xFC1983AC, 0xFC1983AC, 0xFC1993AC, /* 244 - 247 */
557 0xFC1993AC, 0xFC1993AC, 0xFC19A3AC, 0xFC19A3AC, /* 248 - 251 */
558 0xFC19B3AC, 0xFC19B3AC, 0xFC19B3AC, 0xFC19B3AC /* 252 - 255 */
559};
560
561/*** End-of-Files ***/
diff --git a/drivers/staging/cxt1e1/comet_tables.h b/drivers/staging/cxt1e1/comet_tables.h
new file mode 100644
index 00000000000..80424a26a16
--- /dev/null
+++ b/drivers/staging/cxt1e1/comet_tables.h
@@ -0,0 +1,85 @@
1/*
2 * $Id: comet_tables.h,v 1.5 2006/01/02 22:37:31 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_COMET_TBLS_H_
6#define _INC_COMET_TBLS_H_
7
8/*-----------------------------------------------------------------------------
9 * comet_tables.h - Waveform Tables for the PM4351 'COMET'
10 *
11 * Copyright (C) 2005 SBE, Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * For further information, contact via email: support@sbei.com
24 * SBE, Inc. San Ramon, California U.S.A.
25 *-----------------------------------------------------------------------------
26 * RCS info:
27 * RCS revision: $Revision: 1.5 $
28 * Last changed on $Date: 2006/01/02 22:37:31 $
29 * Changed by $Author: rickd $
30 *-----------------------------------------------------------------------------
31 * $Log: comet_tables.h,v $
32 * Revision 1.5 2006/01/02 22:37:31 rickd
33 * Double indexed arrays need sizings to avoid CC errors under
34 * gcc 4.0.0
35 *
36 * Revision 1.4 2005/10/17 23:55:28 rickd
37 * The 75 Ohm transmit waveform is not supported on PMCC4.
38 *
39 * Revision 1.3 2005/09/28 00:10:08 rickd
40 * Add GNU License info. Structures moved to -C- file.
41 *
42 * Revision 1.2 2005/04/28 23:43:04 rickd
43 * Add RCS tracking heading.
44 *
45 *-----------------------------------------------------------------------------
46 */
47
48
49/*****************************************************************************
50*
51* Array names:
52*
53* TWVLongHaul0DB
54* TWVLongHaul7_5DB
55* TWVLongHaul15DB
56* TWVLongHaul22_5DB
57* TWVShortHaul0
58* TWVShortHaul1
59* TWVShortHaul2
60* TWVShortHaul3
61* TWVShortHaul4
62* TWVShortHaul5
63* TWV_E1_120Ohm
64* TWV_E1_75Ohm <not supported>
65* T1_Equalizer
66* E1_Equalizer
67*
68*****************************************************************************/
69
70extern u_int8_t TWVLongHaul0DB[25][5]; /* T1 Long Haul 0 DB */
71extern u_int8_t TWVLongHaul7_5DB[25][5]; /* T1 Long Haul 7.5 DB */
72extern u_int8_t TWVLongHaul15DB[25][5]; /* T1 Long Haul 15 DB */
73extern u_int8_t TWVLongHaul22_5DB[25][5]; /* T1 Long Haul 22.5 DB */
74extern u_int8_t TWVShortHaul0[25][5]; /* T1 Short Haul 0-110 ft */
75extern u_int8_t TWVShortHaul1[25][5]; /* T1 Short Haul 110-220 ft */
76extern u_int8_t TWVShortHaul2[25][5]; /* T1 Short Haul 220-330 ft */
77extern u_int8_t TWVShortHaul3[25][5]; /* T1 Short Haul 330-440 ft */
78extern u_int8_t TWVShortHaul4[25][5]; /* T1 Short Haul 440-550 ft */
79extern u_int8_t TWVShortHaul5[25][5]; /* T1 Short Haul 550-660 ft */
80extern u_int8_t TWV_E1_75Ohm[25][5]; /* E1 75 Ohm */
81extern u_int8_t TWV_E1_120Ohm[25][5]; /* E1 120 Ohm */
82extern u_int32_t T1_Equalizer[256]; /* T1 Receiver Equalizer */
83extern u_int32_t E1_Equalizer[256]; /* E1 Receiver Equalizer */
84
85#endif /* _INC_COMET_TBLS_H_ */
diff --git a/drivers/staging/cxt1e1/functions.c b/drivers/staging/cxt1e1/functions.c
new file mode 100644
index 00000000000..c95c62dfb04
--- /dev/null
+++ b/drivers/staging/cxt1e1/functions.c
@@ -0,0 +1,366 @@
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 ***/
diff --git a/drivers/staging/cxt1e1/hwprobe.c b/drivers/staging/cxt1e1/hwprobe.c
new file mode 100644
index 00000000000..0f9d6539a9a
--- /dev/null
+++ b/drivers/staging/cxt1e1/hwprobe.c
@@ -0,0 +1,400 @@
1/* Copyright (C) 2007 One Stop Systems
2 * Copyright (C) 2003-2005 SBE, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/netdevice.h>
16#include <linux/hdlc.h>
17#include <linux/if_arp.h>
18#include <asm/uaccess.h>
19#include <linux/rtnetlink.h>
20#include <linux/pci.h>
21#include "pmcc4_sysdep.h"
22#include "sbecom_inline_linux.h"
23#include "libsbew.h"
24#include "pmcc4_private.h"
25#include "pmcc4.h"
26#include "pmcc4_ioctls.h"
27#include "pmc93x6_eeprom.h"
28#ifdef CONFIG_PROC_FS
29#include "sbeproc.h"
30#endif
31
32#ifdef SBE_INCLUDE_SYMBOLS
33#define STATIC
34#else
35#define STATIC static
36#endif
37
38extern int log_level;
39extern int error_flag;
40extern int drvr_state;
41
42/* forward references */
43void c4_stopwd (ci_t *);
44struct net_device * __init c4_add_dev (hdw_info_t *, int, unsigned long, unsigned long, int, int);
45
46
47struct s_hdw_info hdw_info[MAX_BOARDS];
48
49
50void __init
51show_two (hdw_info_t * hi, int brdno)
52{
53 ci_t *ci;
54 struct pci_dev *pdev;
55 char *bid;
56 char *bp, banner[80];
57 char sn[6];
58
59 bp = banner;
60 memset (banner, 0, 80); /* clear print buffer */
61
62 ci = (ci_t *)(netdev_priv(hi->ndev));
63 bid = sbeid_get_bdname (ci);
64 switch (hi->promfmt)
65 {
66 case PROM_FORMAT_TYPE1:
67 memcpy (sn, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
68 break;
69 case PROM_FORMAT_TYPE2:
70 memcpy (sn, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
71 break;
72 default:
73 memset (sn, 0, 6);
74 break;
75 }
76
77 sprintf (banner, "%s: %s S/N %06X, MUSYCC Rev %02X",
78 hi->devname, bid,
79 ((sn[3] << 16) & 0xff0000) |
80 ((sn[4] << 8) & 0x00ff00) |
81 (sn[5] & 0x0000ff),
82 (u_int8_t) hi->revid[0]);
83
84 printk ("%s\n", banner);
85
86 pdev = hi->pdev[0];
87 printk ("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
88 hi->devname, "MUSYCC",
89 (unsigned long) hi->addr_mapped[0], hi->addr[0],
90 hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn),
91 (u_int8_t) PCI_FUNC (pdev->devfn), pdev->irq);
92
93 pdev = hi->pdev[1];
94 printk ("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
95 hi->devname, "EBUS ",
96 (unsigned long) hi->addr_mapped[1], hi->addr[1],
97 hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn),
98 (u_int8_t) PCI_FUNC (pdev->devfn), pdev->irq);
99}
100
101
102void __init
103hdw_sn_get (hdw_info_t * hi, int brdno)
104{
105 /* obtain hardware EEPROM information */
106 long addr;
107
108 addr = (long) hi->addr_mapped[1] + EEPROM_OFFSET;
109
110 /* read EEPROM with largest known format size... */
111 pmc_eeprom_read_buffer (addr, 0, (char *) hi->mfg_info.data, sizeof (FLD_TYPE2));
112
113#if 0
114 {
115 unsigned char *ucp = (unsigned char *) &hi->mfg_info.data;
116
117 printk ("eeprom[00]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
118 *(ucp + 0), *(ucp + 1), *(ucp + 2), *(ucp + 3), *(ucp + 4), *(ucp + 5), *(ucp + 6), *(ucp + 7));
119 printk ("eeprom[08]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
120 *(ucp + 8), *(ucp + 9), *(ucp + 10), *(ucp + 11), *(ucp + 12), *(ucp + 13), *(ucp + 14), *(ucp + 15));
121 printk ("eeprom[16]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
122 *(ucp + 16), *(ucp + 17), *(ucp + 18), *(ucp + 19), *(ucp + 20), *(ucp + 21), *(ucp + 22), *(ucp + 23));
123 printk ("eeprom[24]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
124 *(ucp + 24), *(ucp + 25), *(ucp + 26), *(ucp + 27), *(ucp + 28), *(ucp + 29), *(ucp + 30), *(ucp + 31));
125 printk ("eeprom[32]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
126 *(ucp + 32), *(ucp + 33), *(ucp + 34), *(ucp + 35), *(ucp + 36), *(ucp + 37), *(ucp + 38), *(ucp + 39));
127 printk ("eeprom[40]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
128 *(ucp + 40), *(ucp + 41), *(ucp + 42), *(ucp + 43), *(ucp + 44), *(ucp + 45), *(ucp + 46), *(ucp + 47));
129 }
130#endif
131#if 0
132 printk ("sn: %x %x %x %x %x %x\n",
133 hi->mfg_info.Serial[0],
134 hi->mfg_info.Serial[1],
135 hi->mfg_info.Serial[2],
136 hi->mfg_info.Serial[3],
137 hi->mfg_info.Serial[4],
138 hi->mfg_info.Serial[5]);
139#endif
140
141 if ((hi->promfmt = pmc_verify_cksum (&hi->mfg_info.data)) == PROM_FORMAT_Unk)
142 {
143 /* bad crc, data is suspect */
144 if (log_level >= LOG_WARN)
145 printk ("%s: EEPROM cksum error\n", hi->devname);
146 hi->mfg_info_sts = EEPROM_CRCERR;
147 } else
148 hi->mfg_info_sts = EEPROM_OK;
149}
150
151
152void __init
153prep_hdw_info (void)
154{
155 hdw_info_t *hi;
156 int i;
157
158 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
159 {
160 hi->pci_busno = 0xff;
161 hi->pci_slot = 0xff;
162 hi->pci_pin[0] = 0;
163 hi->pci_pin[1] = 0;
164 hi->ndev = 0;
165 hi->addr[0] = 0L;
166 hi->addr[1] = 0L;
167 hi->addr_mapped[0] = 0L;
168 hi->addr_mapped[1] = 0L;
169 }
170}
171
172void
173cleanup_ioremap (void)
174{
175 hdw_info_t *hi;
176 int i;
177
178 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
179 {
180 if (hi->pci_slot == 0xff)
181 break;
182 if (hi->addr_mapped[0])
183 {
184 iounmap ((void *) (hi->addr_mapped[0]));
185 release_mem_region ((long) hi->addr[0], hi->len[0]);
186 hi->addr_mapped[0] = 0;
187 }
188 if (hi->addr_mapped[1])
189 {
190 iounmap ((void *) (hi->addr_mapped[1]));
191 release_mem_region ((long) hi->addr[1], hi->len[1]);
192 hi->addr_mapped[1] = 0;
193 }
194 }
195}
196
197
198void
199cleanup_devs (void)
200{
201 hdw_info_t *hi;
202 int i;
203
204 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
205 {
206 if (hi->pci_slot == 0xff || !hi->ndev)
207 break;
208 c4_stopwd(netdev_priv(hi->ndev));
209#ifdef CONFIG_PROC_FS
210 sbecom_proc_brd_cleanup(netdev_priv(hi->ndev));
211#endif
212 unregister_netdev (hi->ndev);
213 free_irq (hi->pdev[0]->irq, hi->ndev);
214#ifdef CONFIG_SBE_PMCC4_NCOMM
215 free_irq (hi->pdev[1]->irq, hi->ndev);
216#endif
217 OS_kfree (hi->ndev);
218 }
219}
220
221
222STATIC int __init
223c4_hdw_init (struct pci_dev * pdev, int found)
224{
225 hdw_info_t *hi;
226 int i;
227 int fun, slot;
228 unsigned char busno = 0xff;
229
230 /* our MUSYCC chip supports two functions, 0 & 1 */
231 if ((fun = PCI_FUNC (pdev->devfn)) > 1)
232 {
233 printk (KERN_WARNING "%s: unexpected devfun: 0x%x\n", THIS_MODULE->name, pdev->devfn);
234 return 0;
235 }
236 if (pdev->bus) /* obtain bus number */
237 busno = pdev->bus->number;
238 else
239 busno = 0; /* default for system PCI inconsistency */
240 slot = pdev->devfn & ~0x07;
241
242 /*
243 * Functions 0 & 1 for a given board (identified by same bus(busno) and
244 * slot(slot)) are placed into the same 'hardware' structure. The first
245 * part of the board's functionality will be placed into an unpopulated
246 * element, identified by "slot==(0xff)". The second part of a board's
247 * functionality will match the previously loaded slot/busno.
248 */
249 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
250 {
251 /*
252 * match with board's first found interface, otherwise this is first
253 * found
254 */
255 if ((hi->pci_slot == 0xff) || /* new board */
256 ((hi->pci_slot == slot) && (hi->bus == pdev->bus)))
257 break; /* found for-loop exit */
258 }
259 if (i == MAX_BOARDS) /* no match in above loop means MAX
260 * exceeded */
261 {
262 printk (KERN_WARNING "%s: exceeded number of allowed devices (>%d)?\n",
263 THIS_MODULE->name, MAX_BOARDS);
264 return 0;
265 }
266 if (pdev->bus)
267 hi->pci_busno = pdev->bus->number;
268 else
269 hi->pci_busno = 0; /* default for system PCI inconsistency */
270 hi->pci_slot = slot;
271 pci_read_config_byte (pdev, PCI_INTERRUPT_PIN, &hi->pci_pin[fun]);
272 pci_read_config_byte (pdev, PCI_REVISION_ID, &hi->revid[fun]);
273 hi->bus = pdev->bus;
274 hi->addr[fun] = pci_resource_start (pdev, 0);
275 hi->len[fun] = pci_resource_end (pdev, 0) - hi->addr[fun] + 1;
276 hi->pdev[fun] = pdev;
277
278 {
279 /*
280 * create device name from module name, plus add the appropriate
281 * board number
282 */
283 char *cp = hi->devname;
284
285 strcpy (cp, THIS_MODULE->name);
286 cp += strlen (cp); /* reposition */
287 *cp++ = '-';
288 *cp++ = '0' + (found / 2); /* there are two found interfaces per
289 * board */
290 *cp = 0; /* termination */
291 }
292
293 return 1;
294}
295
296
297status_t __init
298c4hw_attach_all (void)
299{
300 hdw_info_t *hi;
301 struct pci_dev *pdev = NULL;
302 int found = 0, i, j;
303
304 error_flag = 0;
305 prep_hdw_info ();
306 /*** scan PCI bus for all possible boards */
307#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
308 while ((pdev = pci_get_device (PCI_VENDOR_ID_CONEXANT,
309 PCI_DEVICE_ID_CN8474,
310 pdev)))
311#else
312 while ((pdev = pci_find_device (PCI_VENDOR_ID_CONEXANT,
313 PCI_DEVICE_ID_CN8474,
314 pdev)))
315#endif
316 {
317 if (c4_hdw_init (pdev, found))
318 found++;
319 }
320 if (!found)
321 {
322 printk (KERN_WARNING "%s: No boards found.\n", THIS_MODULE->name);
323 return ENODEV;
324 }
325 /* sanity check for consistant hardware found */
326 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
327 {
328 if (hi->pci_slot != 0xff && (!hi->addr[0] || !hi->addr[1]))
329 {
330 printk (KERN_WARNING "%s: something very wrong with pci_get_device.\n", hi->devname);
331 return EIO;
332 }
333 }
334 /* bring board's memory regions on/line */
335 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
336 {
337 if (hi->pci_slot == 0xff)
338 break;
339 for (j = 0; j < 2; j++)
340 {
341 if (request_mem_region (hi->addr[j], hi->len[j], hi->devname) == 0)
342 {
343 printk (KERN_WARNING "%s: memory in use, addr=0x%lx, len=0x%lx ?\n",
344 hi->devname, hi->addr[j], hi->len[j]);
345 cleanup_ioremap ();
346 return ENOMEM;
347 }
348 hi->addr_mapped[j] = (unsigned long) ioremap (hi->addr[j], hi->len[j]);
349 if (!hi->addr_mapped[j])
350 {
351 printk (KERN_WARNING "%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n",
352 hi->devname, hi->addr[j], hi->len[j]);
353 cleanup_ioremap ();
354 return ENOMEM;
355 }
356#ifdef SBE_MAP_DEBUG
357 printk (KERN_WARNING "%s: io remapped from phys %x to virt %x\n",
358 hi->devname, (u_int32_t) hi->addr[j], (u_int32_t) hi->addr_mapped[j]);
359#endif
360 }
361 }
362
363 drvr_state = SBE_DRVR_AVAILABLE;
364
365 /* Have now memory mapped all boards. Now allow board's access to system */
366 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
367 {
368 if (hi->pci_slot == 0xff)
369 break;
370 if (pci_enable_device (hi->pdev[0]) ||
371 pci_enable_device (hi->pdev[1]))
372 {
373 drvr_state = SBE_DRVR_DOWN;
374 printk (KERN_WARNING "%s: failed to enable card %d slot %d\n",
375 hi->devname, i, hi->pci_slot);
376 cleanup_devs ();
377 cleanup_ioremap ();
378 return EIO;
379 }
380 pci_set_master (hi->pdev[0]);
381 pci_set_master (hi->pdev[1]);
382 if (!(hi->ndev = c4_add_dev (hi, i, (long) hi->addr_mapped[0],
383 (long) hi->addr_mapped[1],
384 hi->pdev[0]->irq,
385 hi->pdev[1]->irq)))
386 {
387 drvr_state = SBE_DRVR_DOWN;
388 cleanup_ioremap ();
389 /* NOTE: c4_add_dev() does its own device cleanup */
390#if 0
391 cleanup_devs ();
392#endif
393 return error_flag; /* error_flag set w/in add_dev() */
394 }
395 show_two (hi, i); /* displays found information */
396 }
397 return 0;
398}
399
400/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/libsbew.h b/drivers/staging/cxt1e1/libsbew.h
new file mode 100644
index 00000000000..5c99646cd10
--- /dev/null
+++ b/drivers/staging/cxt1e1/libsbew.h
@@ -0,0 +1,581 @@
1/*
2 * $Id: libsbew.h,v 2.1 2005/10/27 18:54:19 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_LIBSBEW_H_
6#define _INC_LIBSBEW_H_
7
8/*-----------------------------------------------------------------------------
9 * libsbew.h - common library elements, charge across mulitple boards
10 *
11 * This file contains common Ioctl structures and contents definitions.
12 *
13 * Copyright (C) 2004-2005 SBE, Inc.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * For further information, contact via email: support@sbei.com
26 * SBE, Inc. San Ramon, California U.S.A.
27 *-----------------------------------------------------------------------------
28 * RCS info:
29 * RCS revision: $Revision: 2.1 $
30 * Last changed on $Date: 2005/10/27 18:54:19 $
31 * Changed by $Author: rickd $
32 *-----------------------------------------------------------------------------
33 * $Log: libsbew.h,v $
34 * Revision 2.1 2005/10/27 18:54:19 rickd
35 * Add E1PLAIN support.
36 *
37 * Revision 2.0 2005/09/28 00:10:08 rickd
38 * Customized for PMCC4 comet-per-port design.
39 *
40 * Revision 1.15 2005/03/29 00:51:31 rickd
41 * File imported from C1T3 port, Revision 1.15
42 *-----------------------------------------------------------------------------
43 */
44
45#ifndef __KERNEL__
46#include <sys/types.h>
47#endif
48
49#ifdef __cplusplus
50extern "C"
51{
52#endif
53
54/********************************/
55/** set driver logging level **/
56/********************************/
57
58/* routine/ioctl: wancfg_set_loglevel() - SBE_IOC_SET_LOGLEVEL */
59
60#define LOG_NONE 0
61#define LOG_ERROR 1
62#define LOG_SBEBUG3 3 /* hidden, for development/debug usage */
63#define LOG_LSCHANGE 5 /* line state change logging */
64#define LOG_LSIMMEDIATE 6 /* line state change logging w/o hysterisis */
65#define LOG_WARN 8
66#define LOG_MONITOR 10
67#define LOG_SBEBUG12 12 /* hidden, for development/debug usage */
68#define LOG_MONITOR2 14 /* hidden, for development/debug usage */
69#define LOG_DEBUG 16
70
71 /* TEMPORARY DEFINES *//* RLD DEBUG */
72#define c4_LOG_NONE LOG_NONE
73#define c4_LOG_ERROR LOG_ERROR
74#define c4_LOG_WARN LOG_WARN
75#define c4_LOG_sTrace LOG_MONITOR /* do some trace logging into
76 * functions */
77#define c4_LOG_DEBUG LOG_DEBUG
78#define c4_LOG_MAX LOG_DEBUG
79
80
81
82/******************************/
83/** get driver information **/
84/******************************/
85
86/* routine/ioctl: wancfg_get_drvinfo() - SBE_IOC_GET_DRVINFO */
87
88#define REL_STRLEN 80
89 struct sbe_drv_info
90 {
91 int rel_strlen;
92 char release[REL_STRLEN];
93 };
94
95
96/*****************************/
97/** get board information **/
98/*****************************/
99
100/* routine/ioctl: wancfg_get_brdinfo() - SBE_IOC_GET_BRDINFO */
101
102#define CHNM_STRLEN 16
103 struct sbe_brd_info
104 {
105 u_int32_t brd_id; /* SBE's unique PCI VENDOR/DEVID */
106 u_int32_t brd_sn;
107 int brd_chan_cnt; /* number of channels being used */
108 int brd_port_cnt; /* number of ports being used */
109 unsigned char brdno; /* our board number */
110 unsigned char brd_pci_speed; /* PCI speed, 33/66Mhz */
111 u_int8_t brd_mac_addr[6];
112 char first_iname[CHNM_STRLEN]; /* first assigned channel's
113 * interface name */
114 char last_iname[CHNM_STRLEN]; /* last assigned channel's
115 * interface name */
116 u_int8_t brd_hdw_id; /* on/board unique hdw ID */
117 u_int8_t reserved8[3]; /* alignment preservation */
118 u_int32_t reserved32[3]; /* size preservation */
119 };
120
121/* These IDs are sometimes available thru pci_ids.h, but not currently. */
122
123#define PCI_VENDOR_ID_SBE 0x1176
124#define PCI_DEVICE_ID_WANPMC_C4T1E1 0x0701 /* BID 0x0X, BTYP 0x0X */
125#define PCI_DEVICE_ID_WANPTMC_C4T1E1 0x0702 /* BID 0x41 */
126#define PCI_DEVICE_ID_WANADAPT_HC4T1E1 0x0703 /* BID 0x44 */
127#define PCI_DEVICE_ID_WANPTMC_256T3_T1 0x0704 /* BID 0x42 (T1 Version) */
128#define PCI_DEVICE_ID_WANPCI_C4T1E1 0x0705 /* BID 0x1X, BTYP 0x0X */
129#define PCI_DEVICE_ID_WANPMC_C1T3 0x0706 /* BID 0x45 */
130#define PCI_DEVICE_ID_WANPCI_C2T1E1 0x0707 /* BID 0x1X, BTYP 0x2X */
131#define PCI_DEVICE_ID_WANPCI_C1T1E1 0x0708 /* BID 0x1X, BTYP 0x1X */
132#define PCI_DEVICE_ID_WANPMC_C2T1E1 0x0709 /* BID 0x0X, BTYP 0x2X */
133#define PCI_DEVICE_ID_WANPMC_C1T1E1 0x070A /* BID 0x0X, BTYP 0x1X */
134#define PCI_DEVICE_ID_WANPTMC_256T3_E1 0x070B /* BID 0x46 (E1 Version) */
135#define PCI_DEVICE_ID_WANPTMC_C24TE1 0x070C /* BID 0x47 */
136#define PCI_DEVICE_ID_WANPMC_C4T1E1_L 0x070D /* BID 0x2X, BTYPE 0x0X w/FP
137 * LEDs */
138#define PCI_DEVICE_ID_WANPMC_C2T1E1_L 0x070E /* BID 0x2X, BTYPE 0x2X w/FP
139 * LEDs */
140#define PCI_DEVICE_ID_WANPMC_C1T1E1_L 0x070F /* BID 0x2X, BTYPE 0x1X w/FP
141 * LEDs */
142#define PCI_DEVICE_ID_WANPMC_2SSI 0x0801
143#define PCI_DEVICE_ID_WANPCI_4SSI 0x0802
144#define PCI_DEVICE_ID_WANPMC_2T3E3 0x0900 /* BID 0x43 */
145#define SBE_BOARD_ID(v,id) ((v<<16) | id)
146
147#define BINFO_PCI_SPEED_unk 0
148#define BINFO_PCI_SPEED_33 1
149#define BINFO_PCI_SPEED_66 2
150
151/***************************/
152/** obtain interface ID **/
153/***************************/
154
155/* routine/ioctl: wancfg_get_iid() - SBE_IOC_IID_GET */
156
157 struct sbe_iid_info
158 {
159 u_int32_t channum; /* channel requested */
160 char iname[CHNM_STRLEN]; /* channel's interface name */
161 };
162
163/**************************************/
164/** get board address information **/
165/**************************************/
166
167/* routine/ioctl: wancfg_get_brdaddr() - SBE_IOC_BRDADDR_GET */
168
169 struct sbe_brd_addr
170 {
171 unsigned char func; /* select PCI address space function */
172 unsigned char brdno; /* returns brdno requested */
173 unsigned char irq;
174 unsigned char size; /* returns size of address */
175#define BRDADDR_SIZE_64 1
176#define BRDADDR_SIZE_32 2
177 int reserved1; /* mod64 align, reserved for future use */
178
179 union
180 {
181 unsigned long virt64; /* virtual/mapped address */
182 u_int32_t virt32[2];
183 } v;
184 union
185 {
186 unsigned long phys64; /* physical bus address */
187 u_int32_t phys32[2];
188 } p;
189 int reserved2[4]; /* reserved for future use */
190 };
191
192/**********************************/
193/** read/write board registers **/
194/**********************************/
195
196/* routine/ioctl: wancfg_read_vec() - SBE_IOC_READ_VEC */
197/* routine/ioctl: wancfg_write_vec() - SBE_IOC_WRITE_VEC */
198
199 struct sbecom_wrt_vec
200 {
201 u_int32_t reg;
202 u_int32_t data;
203 };
204
205#define C1T3_CHIP_MSCC_32 0x01000000
206#define C1T3_CHIP_TECT3_8 0x02000000
207#define C1T3_CHIP_CPLD_8 0x03000000
208#define C1T3_CHIP_EEPROM_8 0x04000000
209
210#define W256T3_CHIP_MUSYCC_32 0x02000000
211#define W256T3_CHIP_TEMUX_8 0x10000000
212#define W256T3_CHIP_T8110_8 0x20000000
213#define W256T3_CHIP_T8110_32 0x22000000
214#define W256T3_CHIP_CPLD_8 0x30000000
215#define W256T3_CHIP_EEPROM_8 0x40000000
216
217
218/**********************************/
219/** read write port parameters **/
220/**********************************/
221
222/* routine/ioctl: wancfg_getset_port_param() - SBE_IOC_PORT_GET */
223/* routine/ioctl: wancfg_set_port_param() - SBE_IOC_PORT_SET */
224
225/* NOTE: this structure supports hardware which supports individual per/port control */
226
227struct sbecom_port_param
228{
229 u_int8_t portnum;
230 u_int8_t port_mode; /* variations of T1 or E1 mode */
231 u_int8_t portStatus;
232 u_int8_t portP; /* more port parameters (clock source - 0x80;
233 * and LBO - 0xf; */
234 /* bits 0x70 are reserved for future use ) */
235#ifdef SBE_PMCC4_ENABLE
236 u_int32_t hypersize; /* RLD DEBUG - add this in until I learn how to make this entry obsolete */
237#endif
238 int reserved[3-1]; /* reserved for future use */
239 int _res[4];
240};
241
242#define CFG_CLK_PORT_MASK 0x80 /* Loop timing */
243#define CFG_CLK_PORT_INTERNAL 0x80 /* Loop timing */
244#define CFG_CLK_PORT_EXTERNAL 0x00 /* Loop timing */
245
246#define CFG_LBO_MASK 0x0F
247#define CFG_LBO_unk 0 /* <not defined> */
248#define CFG_LBO_LH0 1 /* T1 Long Haul (default) */
249#define CFG_LBO_LH7_5 2 /* T1 Long Haul */
250#define CFG_LBO_LH15 3 /* T1 Long Haul */
251#define CFG_LBO_LH22_5 4 /* T1 Long Haul */
252#define CFG_LBO_SH110 5 /* T1 Short Haul */
253#define CFG_LBO_SH220 6 /* T1 Short Haul */
254#define CFG_LBO_SH330 7 /* T1 Short Haul */
255#define CFG_LBO_SH440 8 /* T1 Short Haul */
256#define CFG_LBO_SH550 9 /* T1 Short Haul */
257#define CFG_LBO_SH660 10 /* T1 Short Haul */
258#define CFG_LBO_E75 11 /* E1 75 Ohm */
259#define CFG_LBO_E120 12 /* E1 120 Ohm (default) */
260
261
262/*************************************/
263/** read write channel parameters **/
264/*************************************/
265
266/* routine/ioctl: wancfg_getset_chan_param() - SBE_IOC_CHAN_GET */
267/* routine/ioctl: wancfg_set_chan_param() - SBE_IOC_CHAN_SET */
268
269/* NOTE: this structure supports hardware which supports individual per/channel control */
270
271 struct sbecom_chan_param
272 {
273 u_int32_t channum; /* 0: */
274#ifdef SBE_PMCC4_ENABLE
275 u_int32_t card; /* RLD DEBUG - add this in until I learn how to make this entry obsolete */
276 u_int32_t port; /* RLD DEBUG - add this in until I learn how to make this entry obsolete */
277 u_int8_t bitmask[32];
278#endif
279 u_int32_t intr_mask; /* 4: interrupt mask, specify ored
280 * (SS7_)INTR_* to disable */
281 u_int8_t status; /* 8: channel transceiver status (TX_ENABLED,
282 * RX_ENABLED) */
283 u_int8_t chan_mode; /* 9: protocol mode */
284 u_int8_t idlecode; /* A: idle code, in (FLAG_7E, FLAG_FF,
285 * FLAG_00) */
286 u_int8_t pad_fill_count; /* B: pad fill count (1-127), 0 - pad
287 * fill disabled */
288 u_int8_t data_inv; /* C: channel data inversion selection */
289 u_int8_t mode_56k; /* D: 56kbps mode */
290 u_int8_t reserved[2 + 8]; /* E: */
291 };
292
293/* SS7 interrupt signals <intr_mask> */
294#define SS7_INTR_SFILT 0x00000020
295#define SS7_INTR_SDEC 0x00000040
296#define SS7_INTR_SINC 0x00000080
297#define SS7_INTR_SUERR 0x00000100
298/* Other interrupts that can be masked */
299#define INTR_BUFF 0x00000002
300#define INTR_EOM 0x00000004
301#define INTR_MSG 0x00000008
302#define INTR_IDLE 0x00000010
303
304/* transceiver status flags <status> */
305#define TX_ENABLED 0x01
306#define RX_ENABLED 0x02
307
308/* Protocol modes <mode> */
309#define CFG_CH_PROTO_TRANS 0
310#define CFG_CH_PROTO_SS7 1
311#define CFG_CH_PROTO_HDLC_FCS16 2
312#define CFG_CH_PROTO_HDLC_FCS32 3
313#define CFG_CH_PROTO_ISLP_MODE 4
314
315/* Possible idle code assignments <idlecode> */
316#define CFG_CH_FLAG_7E 0
317#define CFG_CH_FLAG_FF 1
318#define CFG_CH_FLAG_00 2
319
320/* data inversion selection <data_inv> */
321#define CFG_CH_DINV_NONE 0x00
322#define CFG_CH_DINV_RX 0x01
323#define CFG_CH_DINV_TX 0x02
324
325
326/* Posssible resettable chipsets/functions */
327#define RESET_DEV_TEMUX 1
328#define RESET_DEV_TECT3 RESET_DEV_TEMUX
329#define RESET_DEV_PLL 2
330
331
332/*********************************************/
333/** read reset channel thruput statistics **/
334/*********************************************/
335
336/* routine/ioctl: wancfg_get_chan_stats() - SBE_IOC_CHAN_GET_STAT */
337/* routine/ioctl: wancfg_del_chan_stats() - SBE_IOC_CHAN_DEL_STAT */
338/* routine/ioctl: wancfg_get_card_chan_stats() - SBE_IOC_CARD_CHAN_STAT */
339
340 struct sbecom_chan_stats
341 {
342 unsigned long rx_packets; /* total packets received */
343 unsigned long tx_packets; /* total packets transmitted */
344 unsigned long rx_bytes; /* total bytes received */
345 unsigned long tx_bytes; /* total bytes transmitted */
346 unsigned long rx_errors;/* bad packets received */
347 unsigned long tx_errors;/* packet transmit problems */
348 unsigned long rx_dropped; /* no space in linux buffers */
349 unsigned long tx_dropped; /* no space available in linux */
350
351 /* detailed rx_errors: */
352 unsigned long rx_length_errors;
353 unsigned long rx_over_errors; /* receiver ring buff overflow */
354 unsigned long rx_crc_errors; /* recved pkt with crc error */
355 unsigned long rx_frame_errors; /* recv'd frame alignment error */
356 unsigned long rx_fifo_errors; /* recv'r fifo overrun */
357 unsigned long rx_missed_errors; /* receiver missed packet */
358
359 /* detailed tx_errors */
360 unsigned long tx_aborted_errors;
361 unsigned long tx_fifo_errors;
362 unsigned long tx_pending;
363 };
364
365
366/****************************************/
367/** read write card level parameters **/
368/****************************************/
369
370 /* NOTE: this structure supports hardware which supports per/card control */
371
372 struct sbecom_card_param
373 {
374 u_int8_t framing_type; /* 0: CBP or M13 */
375 u_int8_t loopback; /* 1: one of LOOPBACK_* */
376 u_int8_t line_build_out; /* 2: boolean */
377 u_int8_t receive_eq; /* 3: boolean */
378 u_int8_t transmit_ones; /* 4: boolean */
379 u_int8_t clock; /* 5: 0 - internal, i>0 - external (recovered
380 * from framer i) */
381 u_int8_t h110enable; /* 6: */
382 u_int8_t disable_leds; /* 7: */
383 u_int8_t reserved1; /* 8: available - old 256t3 hypersized, but
384 * never used */
385 u_int8_t rear_io; /* 9: rear I/O off/on */
386 u_int8_t disable_tx; /* A: disable TX off/on */
387 u_int8_t mute_los; /* B: mute LOS off/on */
388 u_int8_t los_threshold; /* C: LOS threshold norm/low
389 * (default: norm) */
390 u_int8_t ds1_mode; /* D: DS1 mode T1/E1 (default: T1) */
391 u_int8_t ds3_unchan; /* E: DS3 unchannelized mode off/on */
392 u_int8_t reserved[1 + 16]; /* reserved for expansion - must be
393 * ZERO filled */
394 };
395
396/* framing types <framing_type> */
397#define FRAMING_M13 0
398#define FRAMING_CBP 1
399
400/* card level loopback options <loopback> */
401#define CFG_CARD_LOOPBACK_NONE 0x00
402#define CFG_CARD_LOOPBACK_DIAG 0x01
403#define CFG_CARD_LOOPBACK_LINE 0x02
404#define CFG_CARD_LOOPBACK_PAYLOAD 0x03
405
406/* line level loopback options <loopback> */
407#define CFG_LIU_LOOPBACK_NONE 0x00
408#define CFG_LIU_LOOPBACK_ANALOG 0x10
409#define CFG_LIU_LOOPBACK_DIGITAL 0x11
410#define CFG_LIU_LOOPBACK_REMOTE 0x12
411
412/* card level clock options <clock> */
413#define CFG_CLK_INTERNAL 0x00
414#define CFG_CLK_EXTERNAL 0x01
415
416/* legacy 256T3 loopback values */
417#define LOOPBACK_NONE 0
418#define LOOPBACK_LIU_ANALOG 1
419#define LOOPBACK_LIU_DIGITAL 2
420#define LOOPBACK_FRAMER_DS3 3
421#define LOOPBACK_FRAMER_T1 4
422#define LOOPBACK_LIU_REMOTE 5
423
424/* DS1 mode <ds1_mode> */
425#define CFG_DS1_MODE_MASK 0x0f
426#define CFG_DS1_MODE_T1 0x00
427#define CFG_DS1_MODE_E1 0x01
428#define CFG_DS1_MODE_CHANGE 0x80
429
430/* DS3 unchannelized values <ds1_unchan> */
431#define CFG_DS3_UNCHAN_MASK 0x01
432#define CFG_DS3_UNCHAN_OFF 0x00
433#define CFG_DS3_UNCHAN_ON 0x01
434
435
436/************************************/
437/** read write framer parameters **/
438/************************************/
439
440/* routine/ioctl: wancfg_get_framer() - SBE_IOC_FRAMER_GET */
441/* routine/ioctl: wancfg_set_framer() - SBE_IOC_FRAMER_SET */
442
443 struct sbecom_framer_param
444 {
445 u_int8_t framer_num;
446 u_int8_t frame_type; /* SF, ESF, E1PLAIN, E1CAS, E1CRC, E1CRC+CAS */
447 u_int8_t loopback_type; /* DIGITAL, LINE, PAYLOAD */
448 u_int8_t auto_alarms;/* auto alarms */
449 u_int8_t reserved[12]; /* reserved for expansion - must be
450 * ZERO filled */
451 };
452
453/* frame types <frame_type> */
454#define CFG_FRAME_NONE 0
455#define CFG_FRAME_SF 1 /* T1 B8ZS */
456#define CFG_FRAME_ESF 2 /* T1 B8ZS */
457#define CFG_FRAME_E1PLAIN 3 /* HDB3 w/o CAS,CRC */
458#define CFG_FRAME_E1CAS 4 /* HDB3 */
459#define CFG_FRAME_E1CRC 5 /* HDB3 */
460#define CFG_FRAME_E1CRC_CAS 6 /* HDB3 */
461#define CFG_FRAME_SF_AMI 7 /* T1 AMI */
462#define CFG_FRAME_ESF_AMI 8 /* T1 AMI */
463#define CFG_FRAME_E1PLAIN_AMI 9 /* E1 AMI w/o CAS,CRC */
464#define CFG_FRAME_E1CAS_AMI 10 /* E1 AMI */
465#define CFG_FRAME_E1CRC_AMI 11 /* E1 AMI */
466#define CFG_FRAME_E1CRC_CAS_AMI 12 /* E1 AMI */
467
468#define IS_FRAME_ANY_T1(field) \
469 (((field) == CFG_FRAME_NONE) || \
470 ((field) == CFG_FRAME_SF) || \
471 ((field) == CFG_FRAME_ESF) || \
472 ((field) == CFG_FRAME_SF_AMI) || \
473 ((field) == CFG_FRAME_ESF_AMI))
474
475#define IS_FRAME_ANY_T1ESF(field) \
476 (((field) == CFG_FRAME_ESF) || \
477 ((field) == CFG_FRAME_ESF_AMI))
478
479#define IS_FRAME_ANY_E1(field) \
480 (((field) == CFG_FRAME_E1PLAIN) || \
481 ((field) == CFG_FRAME_E1CAS) || \
482 ((field) == CFG_FRAME_E1CRC) || \
483 ((field) == CFG_FRAME_E1CRC_CAS) || \
484 ((field) == CFG_FRAME_E1PLAIN_AMI) || \
485 ((field) == CFG_FRAME_E1CAS_AMI) || \
486 ((field) == CFG_FRAME_E1CRC_AMI) || \
487 ((field) == CFG_FRAME_E1CRC_CAS_AMI))
488
489#define IS_FRAME_ANY_AMI(field) \
490 (((field) == CFG_FRAME_SF_AMI) || \
491 ((field) == CFG_FRAME_ESF_AMI) || \
492 ((field) == CFG_FRAME_E1PLAIN_AMI) || \
493 ((field) == CFG_FRAME_E1CAS_AMI) || \
494 ((field) == CFG_FRAME_E1CRC_AMI) || \
495 ((field) == CFG_FRAME_E1CRC_CAS_AMI))
496
497/* frame level loopback options <loopback_type> */
498#define CFG_FRMR_LOOPBACK_NONE 0
499#define CFG_FRMR_LOOPBACK_DIAG 1
500#define CFG_FRMR_LOOPBACK_LINE 2
501#define CFG_FRMR_LOOPBACK_PAYLOAD 3
502
503
504/****************************************/
505/** read reset card error statistics **/
506/****************************************/
507
508/* routine/ioctl: wancfg_get_card_stats() - SBE_IOC_CARD_GET_STAT */
509/* routine/ioctl: wancfg_del_card_stats() - SBE_IOC_CARD_DEL_STAT */
510
511 struct temux_card_stats
512 {
513 struct temux_stats
514 {
515 /* TEMUX DS3 PMON counters */
516 u_int32_t lcv;
517 u_int32_t err_framing;
518 u_int32_t febe;
519 u_int32_t err_cpbit;
520 u_int32_t err_parity;
521 /* TEMUX DS3 FRMR status */
522 u_int8_t los;
523 u_int8_t oof;
524 u_int8_t red;
525 u_int8_t yellow;
526 u_int8_t idle;
527 u_int8_t ais;
528 u_int8_t cbit;
529 /* TEMUX DS3 FEAC receiver */
530 u_int8_t feac;
531 u_int8_t feac_last;
532 } t;
533 u_int32_t tx_pending; /* total */
534 };
535
536/**************************************************************/
537
538 struct wancfg
539 {
540 int cs, ds;
541 char *p;
542 };
543 typedef struct wancfg wcfg_t;
544
545 extern wcfg_t *wancfg_init (char *, char *);
546 extern int wancfg_card_blink (wcfg_t *, int);
547 extern int wancfg_ctl (wcfg_t *, int, void *, int, void *, int);
548 extern int wancfg_del_card_stats (wcfg_t *);
549 extern int wancfg_del_chan_stats (wcfg_t *, int);
550 extern int wancfg_enable_ports (wcfg_t *, int);
551 extern int wancfg_free (wcfg_t *);
552 extern int wancfg_get_brdaddr (wcfg_t *, struct sbe_brd_addr *);
553 extern int wancfg_get_brdinfo (wcfg_t *, struct sbe_brd_info *);
554 extern int wancfg_get_card (wcfg_t *, struct sbecom_card_param *);
555 extern int wancfg_get_card_chan_stats (wcfg_t *, struct sbecom_chan_stats *);
556 extern int wancfg_get_card_sn (wcfg_t *);
557 extern int wancfg_get_card_stats (wcfg_t *, struct temux_card_stats *);
558 extern int wancfg_get_chan (wcfg_t *, int, struct sbecom_chan_param *);
559 extern int wancfg_get_chan_stats (wcfg_t *, int, struct sbecom_chan_stats *);
560 extern int wancfg_get_drvinfo (wcfg_t *, int, struct sbe_drv_info *);
561 extern int wancfg_get_framer (wcfg_t *, int, struct sbecom_framer_param *);
562 extern int wancfg_get_iid (wcfg_t *, int, struct sbe_iid_info *);
563 extern int wancfg_get_sn (wcfg_t *, unsigned int *);
564 extern int wancfg_read (wcfg_t *, int, struct sbecom_wrt_vec *);
565 extern int wancfg_reset_device (wcfg_t *, int);
566 extern int wancfg_set_card (wcfg_t *, struct sbecom_card_param *);
567 extern int wancfg_set_chan (wcfg_t *, int, struct sbecom_chan_param *);
568 extern int wancfg_set_framer (wcfg_t *, int, struct sbecom_framer_param *);
569 extern int wancfg_set_loglevel (wcfg_t *, uint);
570 extern int wancfg_write (wcfg_t *, int, struct sbecom_wrt_vec *);
571
572#ifdef NOT_YET_COMMON
573 extern int wancfg_get_tsioc (wcfg_t *, struct wanc1t3_ts_hdr *, struct wanc1t3_ts_param *);
574 extern int wancfg_set_tsioc (wcfg_t *, struct wanc1t3_ts_param *);
575#endif
576
577#ifdef __cplusplus
578}
579#endif
580
581#endif /*** _INC_LIBSBEW_H_ ***/
diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c
new file mode 100644
index 00000000000..23e184da972
--- /dev/null
+++ b/drivers/staging/cxt1e1/linux.c
@@ -0,0 +1,1354 @@
1/* Copyright (C) 2007-2008 One Stop Systems
2 * Copyright (C) 2003-2006 SBE, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/types.h>
16#include <linux/netdevice.h>
17#include <linux/hdlc.h>
18#include <linux/if_arp.h>
19#include <linux/init.h>
20#include <asm/uaccess.h>
21#include <linux/rtnetlink.h>
22#include <linux/skbuff.h>
23#include "pmcc4_sysdep.h"
24#include "sbecom_inline_linux.h"
25#include "libsbew.h"
26#include "pmcc4.h"
27#include "pmcc4_ioctls.h"
28#include "pmcc4_private.h"
29#include "sbeproc.h"
30
31/*****************************************************************************************
32 * Error out early if we have compiler trouble.
33 *
34 * (This section is included from the kernel's init/main.c as a friendly
35 * spiderman recommendation...)
36 *
37 * Versions of gcc older than that listed below may actually compile and link
38 * okay, but the end product can have subtle run time bugs. To avoid associated
39 * bogus bug reports, we flatly refuse to compile with a gcc that is known to be
40 * too old from the very beginning.
41 */
42#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
43#error Sorry, your GCC is too old. It builds incorrect kernels.
44#endif
45
46#if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 0
47#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended.
48#endif
49
50/*****************************************************************************************/
51
52#ifdef SBE_INCLUDE_SYMBOLS
53#define STATIC
54#else
55#define STATIC static
56#endif
57
58#define CHANNAME "hdlc"
59
60/*******************************************************************/
61/* forward references */
62status_t c4_chan_work_init (mpi_t *, mch_t *);
63void musycc_wq_chan_restart (void *);
64status_t __init c4_init (ci_t *, u_char *, u_char *);
65status_t __init c4_init2 (ci_t *);
66ci_t *__init c4_new (void *);
67int __init c4hw_attach_all (void);
68void __init hdw_sn_get (hdw_info_t *, int);
69
70#ifdef CONFIG_SBE_PMCC4_NCOMM
71irqreturn_t c4_ebus_intr_th_handler (void *);
72
73#endif
74int c4_frame_rw (ci_t *, struct sbecom_port_param *);
75status_t c4_get_port (ci_t *, int);
76int c4_loop_port (ci_t *, int, u_int8_t);
77int c4_musycc_rw (ci_t *, struct c4_musycc_param *);
78int c4_new_chan (ci_t *, int, int, void *);
79status_t c4_set_port (ci_t *, int);
80int c4_pld_rw (ci_t *, struct sbecom_port_param *);
81void cleanup_devs (void);
82void cleanup_ioremap (void);
83status_t musycc_chan_down (ci_t *, int);
84irqreturn_t musycc_intr_th_handler (void *);
85int musycc_start_xmit (ci_t *, int, void *);
86
87extern char pmcc4_OSSI_release[];
88extern ci_t *CI;
89extern struct s_hdw_info hdw_info[];
90
91#if defined(CONFIG_SBE_HDLC_V7) || defined(CONFIG_SBE_WAN256T3_HDLC_V7) || \
92 defined(CONFIG_SBE_HDLC_V7_MODULE) || defined(CONFIG_SBE_WAN256T3_HDLC_V7_MODULE)
93#define _v7_hdlc_ 1
94#else
95#define _v7_hdlc_ 0
96#endif
97
98#if _v7_hdlc_
99#define V7(x) (x ## _v7)
100extern int hdlc_netif_rx_v7 (hdlc_device *, struct sk_buff *);
101extern int register_hdlc_device_v7 (hdlc_device *);
102extern int unregister_hdlc_device_v7 (hdlc_device *);
103
104#else
105#define V7(x) x
106#endif
107
108int error_flag; /* module load error reporting */
109int log_level = LOG_ERROR;
110int log_level_default = LOG_ERROR;
111module_param(log_level, int, 0444);
112
113int max_mru = MUSYCC_MRU;
114int max_mru_default = MUSYCC_MRU;
115module_param(max_mru, int, 0444);
116
117int max_mtu = MUSYCC_MTU;
118int max_mtu_default = MUSYCC_MTU;
119module_param(max_mtu, int, 0444);
120
121int max_txdesc_used = MUSYCC_TXDESC_MIN;
122int max_txdesc_default = MUSYCC_TXDESC_MIN;
123module_param(max_txdesc_used, int, 0444);
124
125int max_rxdesc_used = MUSYCC_RXDESC_MIN;
126int max_rxdesc_default = MUSYCC_RXDESC_MIN;
127module_param(max_rxdesc_used, int, 0444);
128
129/****************************************************************************/
130/****************************************************************************/
131/****************************************************************************/
132
133void *
134getuserbychan (int channum)
135{
136 mch_t *ch;
137
138 ch = c4_find_chan (channum);
139 return ch ? ch->user : 0;
140}
141
142
143#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
144#define DEV_TO_PRIV(dev) ( * (struct c4_priv **) ((hdlc_device*)(dev)+1))
145#else
146
147char *
148get_hdlc_name (hdlc_device * hdlc)
149{
150 struct c4_priv *priv = hdlc->priv;
151 struct net_device *dev = getuserbychan (priv->channum);
152
153 return dev->name;
154}
155#endif
156
157
158static status_t
159mkret (int bsd)
160{
161 if (bsd > 0)
162 return -bsd;
163 else
164 return bsd;
165}
166
167/***************************************************************************/
168#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
169#include <linux/workqueue.h>
170
171/***
172 * One workqueue (wq) per port (since musycc allows simultaneous group
173 * commands), with individual data for each channel:
174 *
175 * mpi_t -> struct workqueue_struct *wq_port; (dynamically allocated using
176 * create_workqueue())
177 *
178 * With work structure (work) statically allocated for each channel:
179 *
180 * mch_t -> struct work_struct ch_work; (statically allocated using ???)
181 *
182 ***/
183
184
185/*
186 * Called by the start transmit routine when a channel TX_ENABLE is to be
187 * issued. This queues the transmission start request among other channels
188 * within a port's group.
189 */
190void
191c4_wk_chan_restart (mch_t * ch)
192{
193 mpi_t *pi = ch->up;
194
195#ifdef RLD_RESTART_DEBUG
196 printk (">> c4_wk_chan_restart: queueing Port %d Chan %d, mch_t @ %p\n", pi->portnum, ch->channum, ch);
197#endif
198
199 /* create new entry w/in workqueue for this channel and let'er rip */
200
201 /** queue_work (struct workqueue_struct *queue,
202 ** struct work_struct *work);
203 **/
204 queue_work (pi->wq_port, &ch->ch_work);
205}
206
207status_t
208c4_wk_chan_init (mpi_t * pi, mch_t * ch)
209{
210 /*
211 * this will be used to restart a stopped channel
212 */
213
214 /** INIT_WORK (struct work_struct *work,
215 ** void (*function)(void *),
216 ** void *data);
217 **/
218 INIT_WORK(&ch->ch_work, (void *)musycc_wq_chan_restart);
219 return 0; /* success */
220}
221
222status_t
223c4_wq_port_init (mpi_t * pi)
224{
225
226 char name[16], *np; /* NOTE: name of the queue limited by system
227 * to 10 characters */
228
229 if (pi->wq_port)
230 return 0; /* already initialized */
231
232 np = name;
233 memset (name, 0, 16);
234 sprintf (np, "%s%d", pi->up->devname, pi->portnum); /* IE pmcc4-01) */
235
236#ifdef RLD_RESTART_DEBUG
237 printk (">> c4_wq_port_init: creating workqueue <%s> for Port %d.\n", name, pi->portnum); /* RLD DEBUG */
238#endif
239 if (!(pi->wq_port = create_singlethread_workqueue (name)))
240 return ENOMEM;
241 return 0; /* success */
242}
243
244void
245c4_wq_port_cleanup (mpi_t * pi)
246{
247 /*
248 * PORT POINT: cannot call this if WQ is statically allocated w/in
249 * structure since it calls kfree(wq);
250 */
251 if (pi->wq_port)
252 {
253 destroy_workqueue (pi->wq_port); /* this also calls
254 * flush_workqueue() */
255 pi->wq_port = 0;
256 }
257}
258#endif
259
260/***************************************************************************/
261
262irqreturn_t
263c4_linux_interrupt (int irq, void *dev_instance)
264{
265 struct net_device *ndev = dev_instance;
266
267 return musycc_intr_th_handler(netdev_priv(ndev));
268}
269
270
271#ifdef CONFIG_SBE_PMCC4_NCOMM
272irqreturn_t
273c4_ebus_interrupt (int irq, void *dev_instance)
274{
275 struct net_device *ndev = dev_instance;
276
277 return c4_ebus_intr_th_handler(netdev_priv(ndev));
278}
279#endif
280
281
282static int
283void_open (struct net_device * ndev)
284{
285 printk ("%s: trying to open master device !\n", ndev->name);
286 return -1;
287}
288
289
290#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
291#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
292
293/** Linux 2.4.18-19 **/
294STATIC int
295chan_open (hdlc_device * hdlc)
296{
297 status_t ret;
298
299 if ((ret = c4_chan_up (DEV_TO_PRIV (hdlc)->ci, DEV_TO_PRIV (hdlc)->channum)))
300 return -ret;
301 MOD_INC_USE_COUNT;
302 netif_start_queue (hdlc_to_dev (hdlc));
303 return 0; /* no error = success */
304}
305
306#else
307
308/** Linux 2.4.20 and higher **/
309STATIC int
310chan_open (struct net_device * ndev)
311{
312 hdlc_device *hdlc = dev_to_hdlc (ndev);
313 status_t ret;
314
315 hdlc->proto = IF_PROTO_HDLC;
316 if ((ret = hdlc_open (hdlc)))
317 {
318 printk ("%s: hdlc_open failure, err %d.\n", THIS_MODULE->name, ret);
319 return ret;
320 }
321 if ((ret = c4_chan_up (DEV_TO_PRIV (hdlc)->ci, DEV_TO_PRIV (hdlc)->channum)))
322 return -ret;
323 MOD_INC_USE_COUNT;
324 netif_start_queue (hdlc_to_dev (hdlc));
325 return 0; /* no error = success */
326}
327#endif
328
329#else
330
331/** Linux 2.6 **/
332STATIC int
333chan_open (struct net_device * ndev)
334{
335 hdlc_device *hdlc = dev_to_hdlc (ndev);
336 const struct c4_priv *priv = hdlc->priv;
337 int ret;
338
339 if ((ret = hdlc_open (ndev)))
340 {
341 printk ("%s: hdlc_open failure, err %d.\n", THIS_MODULE->name, ret);
342 return ret;
343 }
344 if ((ret = c4_chan_up (priv->ci, priv->channum)))
345 return -ret;
346 try_module_get (THIS_MODULE);
347 netif_start_queue (ndev);
348 return 0; /* no error = success */
349}
350#endif
351
352
353#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
354#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
355
356/** Linux 2.4.18-19 **/
357STATIC void
358chan_close (hdlc_device * hdlc)
359{
360 netif_stop_queue (hdlc_to_dev (hdlc));
361 musycc_chan_down ((ci_t *) 0, DEV_TO_PRIV (hdlc)->channum);
362 MOD_DEC_USE_COUNT;
363}
364#else
365
366/** Linux 2.4.20 and higher **/
367STATIC int
368chan_close (struct net_device * ndev)
369{
370 hdlc_device *hdlc = dev_to_hdlc (ndev);
371
372 netif_stop_queue (hdlc_to_dev (hdlc));
373 musycc_chan_down ((ci_t *) 0, DEV_TO_PRIV (hdlc)->channum);
374 hdlc_close (hdlc);
375 MOD_DEC_USE_COUNT;
376 return 0;
377}
378#endif
379
380#else
381
382/** Linux 2.6 **/
383STATIC int
384chan_close (struct net_device * ndev)
385{
386 hdlc_device *hdlc = dev_to_hdlc (ndev);
387 const struct c4_priv *priv = hdlc->priv;
388
389 netif_stop_queue (ndev);
390 musycc_chan_down ((ci_t *) 0, priv->channum);
391 hdlc_close (ndev);
392 module_put (THIS_MODULE);
393 return 0;
394}
395#endif
396
397
398#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
399
400/** Linux 2.4.18-19 **/
401STATIC int
402chan_ioctl (hdlc_device * hdlc, struct ifreq * ifr, int cmd)
403{
404 if (cmd == HDLCSCLOCK)
405 {
406 ifr->ifr_ifru.ifru_ivalue = LINE_DEFAULT;
407 return 0;
408 }
409 return -EINVAL;
410}
411#endif
412
413
414#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
415STATIC int
416chan_dev_ioctl (struct net_device * hdlc, struct ifreq * ifr, int cmd)
417{
418 if (cmd == HDLCSCLOCK)
419 {
420 ifr->ifr_ifru.ifru_ivalue = LINE_DEFAULT;
421 return 0;
422 }
423 return -EINVAL;
424}
425#else
426STATIC int
427chan_dev_ioctl (struct net_device * dev, struct ifreq * ifr, int cmd)
428{
429 return hdlc_ioctl (dev, ifr, cmd);
430}
431
432
433STATIC int
434#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
435chan_attach_noop (hdlc_device * hdlc, unsigned short foo_1, unsigned short foo_2)
436#else
437chan_attach_noop (struct net_device * ndev, unsigned short foo_1, unsigned short foo_2)
438#endif
439{
440 return 0; /* our driver has nothing to do here, show's
441 * over, go home */
442}
443#endif
444
445
446STATIC struct net_device_stats *
447chan_get_stats (struct net_device * ndev)
448{
449 mch_t *ch;
450 struct net_device_stats *nstats;
451 struct sbecom_chan_stats *stats;
452 int channum;
453
454#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
455 channum = DEV_TO_PRIV (ndev)->channum;
456#else
457 {
458 struct c4_priv *priv;
459
460 priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv;
461 channum = priv->channum;
462 }
463#endif
464
465 ch = c4_find_chan (channum);
466 if (ch == NULL)
467 return NULL;
468
469 nstats = &ndev->stats;
470 stats = &ch->s;
471
472 memset (nstats, 0, sizeof (struct net_device_stats));
473 nstats->rx_packets = stats->rx_packets;
474 nstats->tx_packets = stats->tx_packets;
475 nstats->rx_bytes = stats->rx_bytes;
476 nstats->tx_bytes = stats->tx_bytes;
477 nstats->rx_errors = stats->rx_length_errors +
478 stats->rx_over_errors +
479 stats->rx_crc_errors +
480 stats->rx_frame_errors +
481 stats->rx_fifo_errors +
482 stats->rx_missed_errors;
483 nstats->tx_errors = stats->tx_dropped +
484 stats->tx_aborted_errors +
485 stats->tx_fifo_errors;
486 nstats->rx_dropped = stats->rx_dropped;
487 nstats->tx_dropped = stats->tx_dropped;
488
489 nstats->rx_length_errors = stats->rx_length_errors;
490 nstats->rx_over_errors = stats->rx_over_errors;
491 nstats->rx_crc_errors = stats->rx_crc_errors;
492 nstats->rx_frame_errors = stats->rx_frame_errors;
493 nstats->rx_fifo_errors = stats->rx_fifo_errors;
494 nstats->rx_missed_errors = stats->rx_missed_errors;
495
496 nstats->tx_aborted_errors = stats->tx_aborted_errors;
497 nstats->tx_fifo_errors = stats->tx_fifo_errors;
498
499 return nstats;
500}
501
502
503static ci_t *
504get_ci_by_dev (struct net_device * ndev)
505{
506 return (ci_t *)(netdev_priv(ndev));
507}
508
509
510#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
511STATIC int
512c4_linux_xmit (hdlc_device * hdlc, struct sk_buff * skb)
513{
514 int rval;
515
516 rval = musycc_start_xmit (DEV_TO_PRIV (hdlc)->ci, DEV_TO_PRIV (hdlc)->channum, skb);
517 return -rval;
518}
519#else /* new */
520STATIC int
521c4_linux_xmit (struct sk_buff * skb, struct net_device * ndev)
522{
523 const struct c4_priv *priv;
524 int rval;
525
526#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
527 priv = DEV_TO_PRIV (ndev);
528#else
529 hdlc_device *hdlc = dev_to_hdlc (ndev);
530
531 priv = hdlc->priv;
532#endif
533
534 rval = musycc_start_xmit (priv->ci, priv->channum, skb);
535 return -rval;
536}
537#endif /* GENERIC_HDLC_VERSION */
538
539static const struct net_device_ops chan_ops = {
540 .ndo_open = chan_open,
541 .ndo_stop = chan_close,
542 .ndo_start_xmit = c4_linux_xmit,
543 .ndo_do_ioctl = chan_dev_ioctl,
544 .ndo_get_stats = chan_get_stats,
545};
546
547STATIC struct net_device *
548create_chan (struct net_device * ndev, ci_t * ci,
549 struct sbecom_chan_param * cp)
550{
551 hdlc_device *hdlc;
552 struct net_device *dev;
553 hdw_info_t *hi;
554 int ret;
555
556 if (c4_find_chan (cp->channum))
557 return 0; /* channel already exists */
558
559 {
560 struct c4_priv *priv;
561
562 /* allocate then fill in private data structure */
563 priv = OS_kmalloc (sizeof (struct c4_priv));
564 if (!priv)
565 {
566 printk (KERN_WARNING "%s: no memory for net_device !\n", ci->devname);
567 return 0;
568 }
569 dev = alloc_hdlcdev (priv);
570 if (!dev)
571 {
572 printk (KERN_WARNING "%s: no memory for hdlc_device !\n", ci->devname);
573 OS_kfree (priv);
574 return 0;
575 }
576 priv->ci = ci;
577 priv->channum = cp->channum;
578 }
579
580 hdlc = dev_to_hdlc (dev);
581
582 dev->base_addr = 0; /* not I/O mapped */
583 dev->irq = ndev->irq;
584 dev->type = ARPHRD_RAWHDLC;
585 *dev->name = 0; /* default ifconfig name = "hdlc" */
586
587 hi = (hdw_info_t *) ci->hdw_info;
588 if (hi->mfg_info_sts == EEPROM_OK)
589 {
590 switch (hi->promfmt)
591 {
592 case PROM_FORMAT_TYPE1:
593 memcpy (dev->dev_addr, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
594 break;
595 case PROM_FORMAT_TYPE2:
596 memcpy (dev->dev_addr, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
597 break;
598 default:
599 memset (dev->dev_addr, 0, 6);
600 break;
601 }
602 } else
603 {
604 memset (dev->dev_addr, 0, 6);
605 }
606
607 hdlc->xmit = c4_linux_xmit;
608
609 dev->netdev_ops = &chan_ops;
610 /*
611 * The native hdlc stack calls this 'attach' routine during
612 * hdlc_raw_ioctl(), passing parameters for line encoding and parity.
613 * Since hdlc_raw_ioctl() stack does not interrogate whether an 'attach'
614 * routine is actually registered or not, we supply a dummy routine which
615 * does nothing (since encoding and parity are setup for our driver via a
616 * special configuration application).
617 */
618
619 hdlc->attach = chan_attach_noop;
620
621 rtnl_unlock (); /* needed due to Ioctl calling sequence */
622 ret = register_hdlc_device (dev);
623 /* NOTE: <stats> setting must occur AFTER registration in order to "take" */
624 dev->tx_queue_len = MAX_DEFAULT_IFQLEN;
625
626 rtnl_lock (); /* needed due to Ioctl calling sequence */
627 if (ret)
628 {
629 if (log_level >= LOG_WARN)
630 printk ("%s: create_chan[%d] registration error = %d.\n",
631 ci->devname, cp->channum, ret);
632 free_netdev (dev); /* cleanup */
633 return 0; /* failed to register */
634 }
635 return dev;
636}
637
638
639/* the idea here is to get port information and pass it back (using pointer) */
640STATIC status_t
641do_get_port (struct net_device * ndev, void *data)
642{
643 int ret;
644 ci_t *ci; /* ci stands for card information */
645 struct sbecom_port_param pp;/* copy data to kernel land */
646
647 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
648 return -EFAULT;
649 if (pp.portnum >= MUSYCC_NPORTS)
650 return -EFAULT;
651 ci = get_ci_by_dev (ndev);
652 if (!ci)
653 return -EINVAL; /* get card info */
654
655 ret = mkret (c4_get_port (ci, pp.portnum));
656 if (ret)
657 return ret;
658 if (copy_to_user (data, &ci->port[pp.portnum].p,
659 sizeof (struct sbecom_port_param)))
660 return -EFAULT;
661 return 0;
662}
663
664/* this function copys the user data and then calls the real action function */
665STATIC status_t
666do_set_port (struct net_device * ndev, void *data)
667{
668 ci_t *ci; /* ci stands for card information */
669 struct sbecom_port_param pp;/* copy data to kernel land */
670
671 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
672 return -EFAULT;
673 if (pp.portnum >= MUSYCC_NPORTS)
674 return -EFAULT;
675 ci = get_ci_by_dev (ndev);
676 if (!ci)
677 return -EINVAL; /* get card info */
678
679 if (pp.portnum >= ci->max_port) /* sanity check */
680 return ENXIO;
681
682 memcpy (&ci->port[pp.portnum].p, &pp, sizeof (struct sbecom_port_param));
683 return mkret (c4_set_port (ci, pp.portnum));
684}
685
686/* work the port loopback mode as per directed */
687STATIC status_t
688do_port_loop (struct net_device * ndev, void *data)
689{
690 struct sbecom_port_param pp;
691 ci_t *ci;
692
693 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
694 return -EFAULT;
695 ci = get_ci_by_dev (ndev);
696 if (!ci)
697 return -EINVAL;
698 return mkret (c4_loop_port (ci, pp.portnum, pp.port_mode));
699}
700
701/* set the specified register with the given value / or just read it */
702STATIC status_t
703do_framer_rw (struct net_device * ndev, void *data)
704{
705 struct sbecom_port_param pp;
706 ci_t *ci;
707 int ret;
708
709 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
710 return -EFAULT;
711 ci = get_ci_by_dev (ndev);
712 if (!ci)
713 return -EINVAL;
714 ret = mkret (c4_frame_rw (ci, &pp));
715 if (ret)
716 return ret;
717 if (copy_to_user (data, &pp, sizeof (struct sbecom_port_param)))
718 return -EFAULT;
719 return 0;
720}
721
722/* set the specified register with the given value / or just read it */
723STATIC status_t
724do_pld_rw (struct net_device * ndev, void *data)
725{
726 struct sbecom_port_param pp;
727 ci_t *ci;
728 int ret;
729
730 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
731 return -EFAULT;
732 ci = get_ci_by_dev (ndev);
733 if (!ci)
734 return -EINVAL;
735 ret = mkret (c4_pld_rw (ci, &pp));
736 if (ret)
737 return ret;
738 if (copy_to_user (data, &pp, sizeof (struct sbecom_port_param)))
739 return -EFAULT;
740 return 0;
741}
742
743/* set the specified register with the given value / or just read it */
744STATIC status_t
745do_musycc_rw (struct net_device * ndev, void *data)
746{
747 struct c4_musycc_param mp;
748 ci_t *ci;
749 int ret;
750
751 if (copy_from_user (&mp, data, sizeof (struct c4_musycc_param)))
752 return -EFAULT;
753 ci = get_ci_by_dev (ndev);
754 if (!ci)
755 return -EINVAL;
756 ret = mkret (c4_musycc_rw (ci, &mp));
757 if (ret)
758 return ret;
759 if (copy_to_user (data, &mp, sizeof (struct c4_musycc_param)))
760 return -EFAULT;
761 return 0;
762}
763
764STATIC status_t
765do_get_chan (struct net_device * ndev, void *data)
766{
767 struct sbecom_chan_param cp;
768 int ret;
769
770 if (copy_from_user (&cp, data,
771 sizeof (struct sbecom_chan_param)))
772 return -EFAULT;
773
774 if ((ret = mkret (c4_get_chan (cp.channum, &cp))))
775 return ret;
776
777 if (copy_to_user (data, &cp, sizeof (struct sbecom_chan_param)))
778 return -EFAULT;
779 return 0;
780}
781
782STATIC status_t
783do_set_chan (struct net_device * ndev, void *data)
784{
785 struct sbecom_chan_param cp;
786 int ret;
787 ci_t *ci;
788
789 if (copy_from_user (&cp, data, sizeof (struct sbecom_chan_param)))
790 return -EFAULT;
791 ci = get_ci_by_dev (ndev);
792 if (!ci)
793 return -EINVAL;
794 switch (ret = mkret (c4_set_chan (cp.channum, &cp)))
795 {
796 case 0:
797 return 0;
798 default:
799 return ret;
800 }
801}
802
803STATIC status_t
804do_create_chan (struct net_device * ndev, void *data)
805{
806 ci_t *ci;
807 struct net_device *dev;
808 struct sbecom_chan_param cp;
809 int ret;
810
811 if (copy_from_user (&cp, data, sizeof (struct sbecom_chan_param)))
812 return -EFAULT;
813 ci = get_ci_by_dev (ndev);
814 if (!ci)
815 return -EINVAL;
816 dev = create_chan (ndev, ci, &cp);
817 if (!dev)
818 return -EBUSY;
819 ret = mkret (c4_new_chan (ci, cp.port, cp.channum, dev));
820 if (ret)
821 {
822#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
823 rtnl_unlock (); /* needed due to Ioctl calling sequence */
824 V7 (unregister_hdlc_device) (dev_to_hdlc (dev));
825 rtnl_lock (); /* needed due to Ioctl calling sequence */
826 OS_kfree (DEV_TO_PRIV (dev));
827 OS_kfree (dev);
828#else
829 rtnl_unlock (); /* needed due to Ioctl calling sequence */
830 unregister_hdlc_device (dev);
831 rtnl_lock (); /* needed due to Ioctl calling sequence */
832 free_netdev (dev);
833#endif
834 }
835 return ret;
836}
837
838STATIC status_t
839do_get_chan_stats (struct net_device * ndev, void *data)
840{
841 struct c4_chan_stats_wrap ccs;
842 int ret;
843
844 if (copy_from_user (&ccs, data,
845 sizeof (struct c4_chan_stats_wrap)))
846 return -EFAULT;
847 switch (ret = mkret (c4_get_chan_stats (ccs.channum, &ccs.stats)))
848 {
849 case 0:
850 break;
851 default:
852 return ret;
853 }
854 if (copy_to_user (data, &ccs,
855 sizeof (struct c4_chan_stats_wrap)))
856 return -EFAULT;
857 return 0;
858}
859STATIC status_t
860do_set_loglevel (struct net_device * ndev, void *data)
861{
862 unsigned int log_level;
863
864 if (copy_from_user (&log_level, data, sizeof (int)))
865 return -EFAULT;
866 sbecom_set_loglevel (log_level);
867 return 0;
868}
869
870STATIC status_t
871do_deluser (struct net_device * ndev, int lockit)
872{
873 if (ndev->flags & IFF_UP)
874 return -EBUSY;
875
876 {
877 ci_t *ci;
878 mch_t *ch;
879 const struct c4_priv *priv;
880 int channum;
881
882#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
883 priv = DEV_TO_PRIV (ndev);
884#else
885 priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv;
886#endif
887 ci = priv->ci;
888 channum = priv->channum;
889
890 ch = c4_find_chan (channum);
891 if (ch == NULL)
892 return -ENOENT;
893 ch->user = 0; /* will be freed, below */
894 }
895
896#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
897 if (lockit)
898 rtnl_unlock (); /* needed if Ioctl calling sequence */
899 V7 (unregister_hdlc_device) (dev_to_hdlc (ndev));
900 if (lockit)
901 rtnl_lock (); /* needed if Ioctl calling sequence */
902 OS_kfree (DEV_TO_PRIV (ndev));
903 OS_kfree (ndev);
904#else
905 if (lockit)
906 rtnl_unlock (); /* needed if Ioctl calling sequence */
907 unregister_hdlc_device (ndev);
908 if (lockit)
909 rtnl_lock (); /* needed if Ioctl calling sequence */
910 free_netdev (ndev);
911#endif
912 return 0;
913}
914
915int
916do_del_chan (struct net_device * musycc_dev, void *data)
917{
918 struct sbecom_chan_param cp;
919 char buf[sizeof (CHANNAME) + 3];
920 struct net_device *dev;
921 int ret;
922
923 if (copy_from_user (&cp, data,
924 sizeof (struct sbecom_chan_param)))
925 return -EFAULT;
926 sprintf (buf, CHANNAME "%d", cp.channum);
927 if (!(dev = dev_get_by_name (&init_net, buf)))
928 return -ENOENT;
929 dev_put (dev);
930 ret = do_deluser (dev, 1);
931 if (ret)
932 return ret;
933 return c4_del_chan (cp.channum);
934}
935int c4_reset_board (void *);
936
937int
938do_reset (struct net_device * musycc_dev, void *data)
939{
940 const struct c4_priv *priv;
941 int i;
942
943 for (i = 0; i < 128; i++)
944 {
945 struct net_device *ndev;
946 char buf[sizeof (CHANNAME) + 3];
947
948 sprintf (buf, CHANNAME "%d", i);
949 if (!(ndev = dev_get_by_name(&init_net, buf)))
950 continue;
951 priv = dev_to_hdlc (ndev)->priv;
952
953 if ((unsigned long) (priv->ci) ==
954 (unsigned long) (netdev_priv(musycc_dev)))
955 {
956 ndev->flags &= ~IFF_UP;
957 dev_put (ndev);
958 netif_stop_queue (ndev);
959 do_deluser (ndev, 1);
960 } else
961 dev_put (ndev);
962 }
963 return 0;
964}
965
966int
967do_reset_chan_stats (struct net_device * musycc_dev, void *data)
968{
969 struct sbecom_chan_param cp;
970
971 if (copy_from_user (&cp, data,
972 sizeof (struct sbecom_chan_param)))
973 return -EFAULT;
974 return mkret (c4_del_chan_stats (cp.channum));
975}
976
977STATIC status_t
978c4_ioctl (struct net_device * ndev, struct ifreq * ifr, int cmd)
979{
980 ci_t *ci;
981 void *data;
982 int iocmd, iolen;
983 status_t ret;
984 static struct data
985 {
986 union
987 {
988 u_int8_t c;
989 u_int32_t i;
990 struct sbe_brd_info bip;
991 struct sbe_drv_info dip;
992 struct sbe_iid_info iip;
993 struct sbe_brd_addr bap;
994 struct sbecom_chan_stats stats;
995 struct sbecom_chan_param param;
996 struct temux_card_stats cards;
997 struct sbecom_card_param cardp;
998 struct sbecom_framer_param frp;
999 } u;
1000 } arg;
1001
1002
1003 if (!capable (CAP_SYS_ADMIN))
1004 return -EPERM;
1005 if (cmd != SIOCDEVPRIVATE + 15)
1006 return -EINVAL;
1007 if (!(ci = get_ci_by_dev (ndev)))
1008 return -EINVAL;
1009 if (ci->state != C_RUNNING)
1010 return -ENODEV;
1011 if (copy_from_user (&iocmd, ifr->ifr_data, sizeof (iocmd)))
1012 return -EFAULT;
1013#if 0
1014 if (copy_from_user (&len, ifr->ifr_data + sizeof (iocmd), sizeof (len)))
1015 return -EFAULT;
1016#endif
1017
1018#if 0
1019 printk ("c4_ioctl: iocmd %x, dir %x type %x nr %x iolen %d.\n", iocmd,
1020 _IOC_DIR (iocmd), _IOC_TYPE (iocmd), _IOC_NR (iocmd),
1021 _IOC_SIZE (iocmd));
1022#endif
1023 iolen = _IOC_SIZE (iocmd);
1024 data = ifr->ifr_data + sizeof (iocmd);
1025 if (copy_from_user (&arg, data, iolen))
1026 return -EFAULT;
1027
1028 ret = 0;
1029 switch (iocmd)
1030 {
1031 case SBE_IOC_PORT_GET:
1032 //printk (">> SBE_IOC_PORT_GET Ioctl...\n");
1033 ret = do_get_port (ndev, data);
1034 break;
1035 case SBE_IOC_PORT_SET:
1036 //printk (">> SBE_IOC_PORT_SET Ioctl...\n");
1037 ret = do_set_port (ndev, data);
1038 break;
1039 case SBE_IOC_CHAN_GET:
1040 //printk (">> SBE_IOC_CHAN_GET Ioctl...\n");
1041 ret = do_get_chan (ndev, data);
1042 break;
1043 case SBE_IOC_CHAN_SET:
1044 //printk (">> SBE_IOC_CHAN_SET Ioctl...\n");
1045 ret = do_set_chan (ndev, data);
1046 break;
1047 case C4_DEL_CHAN:
1048 //printk (">> C4_DEL_CHAN Ioctl...\n");
1049 ret = do_del_chan (ndev, data);
1050 break;
1051 case SBE_IOC_CHAN_NEW:
1052 ret = do_create_chan (ndev, data);
1053 break;
1054 case SBE_IOC_CHAN_GET_STAT:
1055 ret = do_get_chan_stats (ndev, data);
1056 break;
1057 case SBE_IOC_LOGLEVEL:
1058 ret = do_set_loglevel (ndev, data);
1059 break;
1060 case SBE_IOC_RESET_DEV:
1061 ret = do_reset (ndev, data);
1062 break;
1063 case SBE_IOC_CHAN_DEL_STAT:
1064 ret = do_reset_chan_stats (ndev, data);
1065 break;
1066 case C4_LOOP_PORT:
1067 ret = do_port_loop (ndev, data);
1068 break;
1069 case C4_RW_FRMR:
1070 ret = do_framer_rw (ndev, data);
1071 break;
1072 case C4_RW_MSYC:
1073 ret = do_musycc_rw (ndev, data);
1074 break;
1075 case C4_RW_PLD:
1076 ret = do_pld_rw (ndev, data);
1077 break;
1078 case SBE_IOC_IID_GET:
1079 ret = (iolen == sizeof (struct sbe_iid_info)) ? c4_get_iidinfo (ci, &arg.u.iip) : -EFAULT;
1080 if (ret == 0) /* no error, copy data */
1081 if (copy_to_user (data, &arg, iolen))
1082 return -EFAULT;
1083 break;
1084 default:
1085 //printk (">> c4_ioctl: EINVAL - unknown iocmd <%x>\n", iocmd);
1086 ret = -EINVAL;
1087 break;
1088 }
1089 return mkret (ret);
1090}
1091
1092static const struct net_device_ops c4_ops = {
1093 .ndo_open = void_open,
1094 .ndo_start_xmit = c4_linux_xmit,
1095 .ndo_do_ioctl = c4_ioctl,
1096};
1097
1098static void c4_setup(struct net_device *dev)
1099{
1100 dev->type = ARPHRD_VOID;
1101 dev->netdev_ops = &c4_ops;
1102}
1103
1104struct net_device *__init
1105c4_add_dev (hdw_info_t * hi, int brdno, unsigned long f0, unsigned long f1,
1106 int irq0, int irq1)
1107{
1108 struct net_device *ndev;
1109 ci_t *ci;
1110
1111 ndev = alloc_netdev(sizeof(ci_t), SBE_IFACETMPL, c4_setup);
1112 if (!ndev)
1113 {
1114 printk (KERN_WARNING "%s: no memory for struct net_device !\n", hi->devname);
1115 error_flag = ENOMEM;
1116 return 0;
1117 }
1118 ci = (ci_t *)(netdev_priv(ndev));
1119 ndev->irq = irq0;
1120
1121 ci->hdw_info = hi;
1122 ci->state = C_INIT; /* mark as hardware not available */
1123 ci->next = c4_list;
1124 c4_list = ci;
1125 ci->brdno = ci->next ? ci->next->brdno + 1 : 0;
1126
1127 if (CI == 0)
1128 CI = ci; /* DEBUG, only board 0 usage */
1129
1130 strcpy (ci->devname, hi->devname);
1131 ci->release = &pmcc4_OSSI_release[0];
1132
1133 /* tasklet */
1134#if defined(SBE_ISR_TASKLET)
1135 tasklet_init (&ci->ci_musycc_isr_tasklet,
1136 (void (*) (unsigned long)) musycc_intr_bh_tasklet,
1137 (unsigned long) ci);
1138
1139 if (atomic_read (&ci->ci_musycc_isr_tasklet.count) == 0)
1140 tasklet_disable_nosync (&ci->ci_musycc_isr_tasklet);
1141#elif defined(SBE_ISR_IMMEDIATE)
1142 ci->ci_musycc_isr_tq.routine = (void *) (unsigned long) musycc_intr_bh_tasklet;
1143 ci->ci_musycc_isr_tq.data = ci;
1144#endif
1145
1146
1147 if (register_netdev (ndev) ||
1148 (c4_init (ci, (u_char *) f0, (u_char *) f1) != SBE_DRVR_SUCCESS))
1149 {
1150 OS_kfree (netdev_priv(ndev));
1151 OS_kfree (ndev);
1152 error_flag = ENODEV;
1153 return 0;
1154 }
1155 /*************************************************************
1156 * int request_irq(unsigned int irq,
1157 * void (*handler)(int, void *, struct pt_regs *),
1158 * unsigned long flags, const char *dev_name, void *dev_id);
1159 * wherein:
1160 * irq -> The interrupt number that is being requested.
1161 * handler -> Pointer to handling function being installed.
1162 * flags -> A bit mask of options related to interrupt management.
1163 * dev_name -> String used in /proc/interrupts to show owner of interrupt.
1164 * dev_id -> Pointer (for shared interrupt lines) to point to its own
1165 * private data area (to identify which device is interrupting).
1166 *
1167 * extern void free_irq(unsigned int irq, void *dev_id);
1168 **************************************************************/
1169
1170 if (request_irq (irq0, &c4_linux_interrupt,
1171#if defined(SBE_ISR_TASKLET)
1172 IRQF_DISABLED | IRQF_SHARED,
1173#elif defined(SBE_ISR_IMMEDIATE)
1174 IRQF_DISABLED | IRQF_SHARED,
1175#elif defined(SBE_ISR_INLINE)
1176 IRQF_SHARED,
1177#endif
1178 ndev->name, ndev))
1179 {
1180 printk (KERN_WARNING "%s: MUSYCC could not get irq: %d\n",
1181 ndev->name, irq0);
1182 unregister_netdev (ndev);
1183 OS_kfree (netdev_priv(ndev));
1184 OS_kfree (ndev);
1185 error_flag = EIO;
1186 return 0;
1187 }
1188#ifdef CONFIG_SBE_PMCC4_NCOMM
1189 if (request_irq (irq1, &c4_ebus_interrupt, IRQF_SHARED, ndev->name, ndev))
1190 {
1191 printk (KERN_WARNING "%s: EBUS could not get irq: %d\n",
1192 hi->devname, irq1);
1193 unregister_netdev (ndev);
1194 free_irq (irq0, ndev);
1195 OS_kfree (ndev->priv);
1196 OS_kfree (ndev);
1197 error_flag = EIO;
1198 return 0;
1199 }
1200#endif
1201
1202 /* setup board identification information */
1203
1204 {
1205 u_int32_t tmp;
1206
1207 hdw_sn_get (hi, brdno); /* also sets PROM format type (promfmt)
1208 * for later usage */
1209
1210 switch (hi->promfmt)
1211 {
1212 case PROM_FORMAT_TYPE1:
1213 memcpy (ndev->dev_addr, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
1214 memcpy (&tmp, (FLD_TYPE1 *) (hi->mfg_info.pft1.Id), 4); /* unaligned data
1215 * acquisition */
1216 ci->brd_id = cpu_to_be32 (tmp);
1217 break;
1218 case PROM_FORMAT_TYPE2:
1219 memcpy (ndev->dev_addr, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
1220 memcpy (&tmp, (FLD_TYPE2 *) (hi->mfg_info.pft2.Id), 4); /* unaligned data
1221 * acquisition */
1222 ci->brd_id = cpu_to_be32 (tmp);
1223 break;
1224 default:
1225 ci->brd_id = 0;
1226 memset (ndev->dev_addr, 0, 6);
1227 break;
1228 }
1229
1230#if 1
1231 sbeid_set_hdwbid (ci); /* requires bid to be preset */
1232#else
1233 sbeid_set_bdtype (ci); /* requires hdw_bid to be preset */
1234#endif
1235
1236 }
1237
1238#ifdef CONFIG_PROC_FS
1239 sbecom_proc_brd_init (ci);
1240#endif
1241#if defined(SBE_ISR_TASKLET)
1242 tasklet_enable (&ci->ci_musycc_isr_tasklet);
1243#endif
1244
1245
1246 if ((error_flag = c4_init2 (ci)) != SBE_DRVR_SUCCESS)
1247 {
1248#ifdef CONFIG_PROC_FS
1249 sbecom_proc_brd_cleanup (ci);
1250#endif
1251 unregister_netdev (ndev);
1252 free_irq (irq1, ndev);
1253 free_irq (irq0, ndev);
1254 OS_kfree (netdev_priv(ndev));
1255 OS_kfree (ndev);
1256 return 0; /* failure, error_flag is set */
1257 }
1258 return ndev;
1259}
1260
1261STATIC int __init
1262c4_mod_init (void)
1263{
1264 int rtn;
1265
1266 printk (KERN_WARNING "%s: %s\n", THIS_MODULE->name, pmcc4_OSSI_release);
1267 if ((rtn = c4hw_attach_all ()))
1268 return -rtn; /* installation failure - see system log */
1269
1270 /* housekeeping notifications */
1271 if (log_level != log_level_default)
1272 printk (KERN_INFO "%s NOTE: driver parameter <log_level> changed from default %d to %d.\n",
1273 THIS_MODULE->name, log_level_default, log_level);
1274 if (max_mru != max_mru_default)
1275 printk (KERN_INFO "%s NOTE: driver parameter <max_mru> changed from default %d to %d.\n",
1276 THIS_MODULE->name, max_mru_default, max_mru);
1277 if (max_mtu != max_mtu_default)
1278 printk (KERN_INFO "%s NOTE: driver parameter <max_mtu> changed from default %d to %d.\n",
1279 THIS_MODULE->name, max_mtu_default, max_mtu);
1280 if (max_rxdesc_used != max_rxdesc_default)
1281 {
1282 if (max_rxdesc_used > 2000)
1283 max_rxdesc_used = 2000; /* out-of-bounds reset */
1284 printk (KERN_INFO "%s NOTE: driver parameter <max_rxdesc_used> changed from default %d to %d.\n",
1285 THIS_MODULE->name, max_rxdesc_default, max_rxdesc_used);
1286 }
1287 if (max_txdesc_used != max_txdesc_default)
1288 {
1289 if (max_txdesc_used > 1000)
1290 max_txdesc_used = 1000; /* out-of-bounds reset */
1291 printk (KERN_INFO "%s NOTE: driver parameter <max_txdesc_used> changed from default %d to %d.\n",
1292 THIS_MODULE->name, max_txdesc_default, max_txdesc_used);
1293 }
1294 return 0; /* installation success */
1295}
1296
1297
1298 /*
1299 * find any still allocated hdlc registrations and unregister via call to
1300 * do_deluser()
1301 */
1302
1303STATIC void __exit
1304cleanup_hdlc (void)
1305{
1306 hdw_info_t *hi;
1307 ci_t *ci;
1308 struct net_device *ndev;
1309 int i, j, k;
1310
1311 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
1312 {
1313 if (hi->ndev) /* a board has been attached */
1314 {
1315 ci = (ci_t *)(netdev_priv(hi->ndev));
1316 for (j = 0; j < ci->max_port; j++)
1317 for (k = 0; k < MUSYCC_NCHANS; k++)
1318 if ((ndev = ci->port[j].chan[k]->user))
1319 {
1320 do_deluser (ndev, 0);
1321 }
1322 }
1323 }
1324}
1325
1326
1327STATIC void __exit
1328c4_mod_remove (void)
1329{
1330 cleanup_hdlc (); /* delete any missed channels */
1331 cleanup_devs ();
1332 c4_cleanup ();
1333 cleanup_ioremap ();
1334 printk (KERN_INFO "SBE %s - driver removed.\n", THIS_MODULE->name);
1335}
1336
1337module_init (c4_mod_init);
1338module_exit (c4_mod_remove);
1339
1340#ifndef SBE_INCLUDE_SYMBOLS
1341#ifndef CONFIG_SBE_WANC24_NCOMM
1342#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1343EXPORT_NO_SYMBOLS;
1344#endif
1345#endif
1346#endif
1347
1348MODULE_AUTHOR ("SBE Technical Services <support@sbei.com>");
1349MODULE_DESCRIPTION ("wanPCI-CxT1E1 Generic HDLC WAN Driver module");
1350#ifdef MODULE_LICENSE
1351MODULE_LICENSE ("GPL");
1352#endif
1353
1354/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c
new file mode 100644
index 00000000000..650c9c02f22
--- /dev/null
+++ b/drivers/staging/cxt1e1/musycc.c
@@ -0,0 +1,2180 @@
1/*
2 * $Id: musycc.c,v 2.1 2007/08/15 23:32:17 rickd PMCC4_3_1B $
3 */
4
5unsigned int max_intcnt = 0;
6unsigned int max_bh = 0;
7
8/*-----------------------------------------------------------------------------
9 * musycc.c -
10 *
11 * Copyright (C) 2007 One Stop Systems, Inc.
12 * Copyright (C) 2003-2006 SBE, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * For further information, contact via email: support@onestopsystems.com
25 * One Stop Systems, Inc. Escondido, California U.S.A.
26 *-----------------------------------------------------------------------------
27 * RCS info:
28 * RCS revision: $Revision: 2.1 $
29 * Last changed on $Date: 2007/08/15 23:32:17 $
30 * Changed by $Author: rickd $
31 *-----------------------------------------------------------------------------
32 * $Log: musycc.c,v $
33 * Revision 2.1 2007/08/15 23:32:17 rickd
34 * Use 'if 0' instead of GNU comment delimeter to avoid line wrap induced compiler errors.
35 *
36 * Revision 2.0 2007/08/15 22:13:20 rickd
37 * Update to printf pointer %p usage and correct some UINT to ULONG for
38 * 64bit comptibility.
39 *
40 * Revision 1.7 2006/04/21 00:56:40 rickd
41 * workqueue files now prefixed with <sbecom> prefix.
42 *
43 * Revision 1.6 2005/10/27 18:54:19 rickd
44 * Clean out old code. Default to HDLC_FCS16, not TRANS.
45 *
46 * Revision 1.5 2005/10/17 23:55:28 rickd
47 * Initial port of NCOMM support patches from original work found
48 * in pmc_c4t1e1 as updated by NCOMM. Ref: CONFIG_SBE_PMCC4_NCOMM.
49 *
50 * Revision 1.4 2005/10/13 20:35:25 rickd
51 * Cleanup warning for unused <flags> variable.
52 *
53 * Revision 1.3 2005/10/13 19:19:22 rickd
54 * Disable redundant driver removal cleanup code.
55 *
56 * Revision 1.2 2005/10/11 18:36:16 rickd
57 * Clean up warning messages caused by de-implemented some <flags> associated
58 * with spin_lock() removals.
59 *
60 * Revision 1.1 2005/10/05 00:45:28 rickd
61 * Re-enable xmit on flow-controlled and full channel to fix restart hang.
62 * Add some temp spin-lock debug code (rld_spin_owner).
63 *
64 * Revision 1.0 2005/09/28 00:10:06 rickd
65 * Initial release for C4T1E1 support. Lots of transparent
66 * mode updates.
67 *
68 *-----------------------------------------------------------------------------
69 */
70
71char SBEid_pmcc4_musyccc[] =
72"@(#)musycc.c - $Revision: 2.1 $ (c) Copyright 2004-2006 SBE, Inc.";
73
74
75#include <linux/types.h>
76#include "pmcc4_sysdep.h"
77#include <linux/kernel.h>
78#include <linux/errno.h>
79#include <linux/init.h>
80#include "sbecom_inline_linux.h"
81#include "libsbew.h"
82#include "pmcc4_private.h"
83#include "pmcc4.h"
84#include "musycc.h"
85
86#ifdef SBE_INCLUDE_SYMBOLS
87#define STATIC
88#else
89#define STATIC static
90#endif
91
92#define sd_find_chan(ci,ch) c4_find_chan(ch)
93
94
95/*******************************************************************/
96/* global driver variables */
97extern ci_t *c4_list;
98extern int drvr_state;
99extern int log_level;
100
101extern int max_mru;
102extern int max_mtu;
103extern int max_rxdesc_used;
104extern int max_txdesc_used;
105extern ci_t *CI; /* dummy pointr to board ZEROE's data - DEBUG
106 * USAGE */
107
108
109/*******************************************************************/
110/* forward references */
111void c4_fifo_free (mpi_t *, int);
112void c4_wk_chan_restart (mch_t *);
113void musycc_bh_tx_eom (mpi_t *, int);
114int musycc_chan_up (ci_t *, int);
115status_t __init musycc_init (ci_t *);
116STATIC void __init musycc_init_port (mpi_t *);
117void musycc_intr_bh_tasklet (ci_t *);
118void musycc_serv_req (mpi_t *, u_int32_t);
119void musycc_update_timeslots (mpi_t *);
120
121/*******************************************************************/
122
123#if 1
124STATIC int
125musycc_dump_rxbuffer_ring (mch_t * ch, int lockit)
126{
127 struct mdesc *m;
128 unsigned long flags = 0;
129
130 u_int32_t status;
131 int n;
132
133 if (lockit)
134 {
135 spin_lock_irqsave (&ch->ch_rxlock, flags);
136 }
137 if (ch->rxd_num == 0)
138 {
139 printk (" ZERO receive buffers allocated for this channel.");
140 } else
141 {
142 FLUSH_MEM_READ ();
143 m = &ch->mdr[ch->rxix_irq_srv];
144 for (n = ch->rxd_num; n; n--)
145 {
146 status = le32_to_cpu (m->status);
147 {
148 printk ("%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n",
149 (m == &ch->mdr[ch->rxix_irq_srv]) ? 'F' : ' ',
150 (unsigned long) m, n,
151 status,
152 m->data ? (status & HOST_RX_OWNED ? 'H' : 'M') : '-',
153 status & POLL_DISABLED ? 'P' : '-',
154 status & EOBIRQ_ENABLE ? 'b' : '-',
155 status & EOMIRQ_ENABLE ? 'm' : '-',
156 status & LENGTH_MASK,
157 le32_to_cpu (m->data), le32_to_cpu (m->next));
158#ifdef RLD_DUMP_BUFDATA
159 {
160 u_int32_t *dp;
161 int len = status & LENGTH_MASK;
162
163#if 1
164 if (m->data && (status & HOST_RX_OWNED))
165#else
166 if (m->data) /* always dump regardless of valid RX
167 * data */
168#endif
169 {
170 dp = (u_int32_t *) OS_phystov ((void *) (le32_to_cpu (m->data)));
171 if (len >= 0x10)
172 printk (" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len,
173 *dp, *(dp + 1), *(dp + 2), *(dp + 3));
174 else if (len >= 0x08)
175 printk (" %x[%x]: %08X %08X\n", (u_int32_t) dp, len,
176 *dp, *(dp + 1));
177 else
178 printk (" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp);
179 }
180 }
181#endif
182 }
183 m = m->snext;
184 }
185 } /* -for- */
186 printk ("\n");
187
188 if (lockit)
189 {
190 spin_unlock_irqrestore (&ch->ch_rxlock, flags);
191 }
192 return 0;
193}
194#endif
195
196#if 1
197STATIC int
198musycc_dump_txbuffer_ring (mch_t * ch, int lockit)
199{
200 struct mdesc *m;
201 unsigned long flags = 0;
202 u_int32_t status;
203 int n;
204
205 if (lockit)
206 {
207 spin_lock_irqsave (&ch->ch_txlock, flags);
208 }
209 if (ch->txd_num == 0)
210 {
211 printk (" ZERO transmit buffers allocated for this channel.");
212 } else
213 {
214 FLUSH_MEM_READ ();
215 m = ch->txd_irq_srv;
216 for (n = ch->txd_num; n; n--)
217 {
218 status = le32_to_cpu (m->status);
219 {
220 printk ("%c%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n",
221 (m == ch->txd_usr_add) ? 'F' : ' ',
222 (m == ch->txd_irq_srv) ? 'L' : ' ',
223 (unsigned long) m, n,
224 status,
225 m->data ? (status & MUSYCC_TX_OWNED ? 'M' : 'H') : '-',
226 status & POLL_DISABLED ? 'P' : '-',
227 status & EOBIRQ_ENABLE ? 'b' : '-',
228 status & EOMIRQ_ENABLE ? 'm' : '-',
229 status & LENGTH_MASK,
230 le32_to_cpu (m->data), le32_to_cpu (m->next));
231#ifdef RLD_DUMP_BUFDATA
232 {
233 u_int32_t *dp;
234 int len = status & LENGTH_MASK;
235
236 if (m->data)
237 {
238 dp = (u_int32_t *) OS_phystov ((void *) (le32_to_cpu (m->data)));
239 if (len >= 0x10)
240 printk (" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len,
241 *dp, *(dp + 1), *(dp + 2), *(dp + 3));
242 else if (len >= 0x08)
243 printk (" %x[%x]: %08X %08X\n", (u_int32_t) dp, len,
244 *dp, *(dp + 1));
245 else
246 printk (" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp);
247 }
248 }
249#endif
250 }
251 m = m->snext;
252 }
253 } /* -for- */
254 printk ("\n");
255
256 if (lockit)
257 {
258 spin_unlock_irqrestore (&ch->ch_txlock, flags);
259 }
260 return 0;
261}
262#endif
263
264
265/*
266 * The following supports a backdoor debug facility which can be used to
267 * display the state of a board's channel.
268 */
269
270status_t
271musycc_dump_ring (ci_t * ci, unsigned int chan)
272{
273 mch_t *ch;
274
275 if (chan >= MAX_CHANS_USED)
276 {
277 return SBE_DRVR_FAIL; /* E2BIG */
278 }
279 {
280 int bh;
281
282 bh = atomic_read (&ci->bh_pending);
283 printk (">> bh_pend %d [%d] ihead %d itail %d [%d] th_cnt %d bh_cnt %d wdcnt %d note %d\n",
284 bh, max_bh, ci->iqp_headx, ci->iqp_tailx, max_intcnt,
285 ci->intlog.drvr_intr_thcount,
286 ci->intlog.drvr_intr_bhcount,
287 ci->wdcount, ci->wd_notify);
288 max_bh = 0; /* reset counter */
289 max_intcnt = 0; /* reset counter */
290 }
291
292 if (!(ch = sd_find_chan (dummy, chan)))
293 {
294 printk (">> musycc_dump_ring: channel %d not up.\n", chan);
295 return ENOENT;
296 }
297 printk (">> CI %p CHANNEL %3d @ %p: state %x status/p %x/%x\n", ci, chan, ch, ch->state,
298 ch->status, ch->p.status);
299 printk ("--------------------------------\nTX Buffer Ring - Channel %d, txd_num %d. (bd/ch pend %d %d), TXD required %d, txpkt %lu\n",
300 chan, ch->txd_num,
301 (u_int32_t) atomic_read (&ci->tx_pending), (u_int32_t) atomic_read (&ch->tx_pending), ch->txd_required, ch->s.tx_packets);
302 printk ("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n",
303 ch->user, ch->txd_irq_srv, ch->txd_usr_add,
304 sd_queue_stopped (ch->user),
305 ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode);
306 musycc_dump_txbuffer_ring (ch, 1);
307 printk ("RX Buffer Ring - Channel %d, rxd_num %d. IRQ_SRV[%d] 0x%p, start_rx %x rxpkt %lu\n",
308 chan, ch->rxd_num, ch->rxix_irq_srv,
309 &ch->mdr[ch->rxix_irq_srv], ch->ch_start_rx, ch->s.rx_packets);
310 musycc_dump_rxbuffer_ring (ch, 1);
311
312 return SBE_DRVR_SUCCESS;
313}
314
315
316status_t
317musycc_dump_rings (ci_t * ci, unsigned int start_chan)
318{
319 unsigned int chan;
320
321 for (chan = start_chan; chan < (start_chan + 5); chan++)
322 musycc_dump_ring (ci, chan);
323 return SBE_DRVR_SUCCESS;
324}
325
326
327/*
328 * NOTE on musycc_init_mdt(): These MUSYCC writes are only operational after
329 * a MUSYCC GROUP_INIT command has been issued.
330 */
331
332void
333musycc_init_mdt (mpi_t * pi)
334{
335 u_int32_t *addr, cfg;
336 int i;
337
338 /*
339 * This Idle Code insertion takes effect prior to channel's first
340 * transmitted message. After that, each message contains its own Idle
341 * Code information which is to be issued after the message is
342 * transmitted (Ref.MUSYCC 5.2.2.3: MCENBL bit in Group Configuration
343 * Descriptor).
344 */
345
346 addr = (u_int32_t *) ((u_long) pi->reg + MUSYCC_MDT_BASE03_ADDR);
347 cfg = CFG_CH_FLAG_7E << IDLE_CODE;
348
349 for (i = 0; i < 32; addr++, i++)
350 {
351 pci_write_32 (addr, cfg);
352 }
353}
354
355
356/* Set TX thp to the next unprocessed md */
357
358void
359musycc_update_tx_thp (mch_t * ch)
360{
361 struct mdesc *md;
362 unsigned long flags;
363
364 spin_lock_irqsave (&ch->ch_txlock, flags);
365 while (1)
366 {
367 md = ch->txd_irq_srv;
368 FLUSH_MEM_READ ();
369 if (!md->data)
370 {
371 /* No MDs with buffers to process */
372 spin_unlock_irqrestore (&ch->ch_txlock, flags);
373 return;
374 }
375 if ((le32_to_cpu (md->status)) & MUSYCC_TX_OWNED)
376 {
377 /* this is the MD to restart TX with */
378 break;
379 }
380 /*
381 * Otherwise, we have a valid, host-owned message descriptor which
382 * has been successfully transmitted and whose buffer can be freed,
383 * so... process this MD, it's owned by the host. (This might give
384 * as a new, updated txd_irq_srv.)
385 */
386 musycc_bh_tx_eom (ch->up, ch->gchan);
387 }
388 md = ch->txd_irq_srv;
389 ch->up->regram->thp[ch->gchan] = cpu_to_le32 (OS_vtophys (md));
390 FLUSH_MEM_WRITE ();
391
392 if (ch->tx_full)
393 {
394 ch->tx_full = 0;
395 ch->txd_required = 0;
396 sd_enable_xmit (ch->user); /* re-enable to catch flow controlled
397 * channel */
398 }
399 spin_unlock_irqrestore (&ch->ch_txlock, flags);
400
401#ifdef RLD_TRANS_DEBUG
402 printk ("++ musycc_update_tx_thp[%d]: setting thp = %p, sts %x\n", ch->channum, md, md->status);
403#endif
404}
405
406
407#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
408/*
409 * This is the workq task executed by the OS when our queue_work() is
410 * scheduled and run. It can fire off either RX or TX ACTIVATION depending
411 * upon the channel's ch_start_tx and ch_start_rx variables. This routine
412 * is implemented as a work queue so that the call to the service request is
413 * able to sleep, awaiting an interrupt acknowledgment response (SACK) from
414 * the hardware.
415 */
416
417void
418musycc_wq_chan_restart (void *arg) /* channel private structure */
419{
420 mch_t *ch;
421 mpi_t *pi;
422 struct mdesc *md;
423#if 0
424 unsigned long flags;
425#endif
426
427 ch = container_of(arg, struct c4_chan_info, ch_work);
428 pi = ch->up;
429
430#ifdef RLD_TRANS_DEBUG
431 printk ("wq_chan_restart[%d]: start_RT[%d/%d] status %x\n",
432 ch->channum, ch->ch_start_rx, ch->ch_start_tx, ch->status);
433
434#endif
435
436 /**********************************/
437 /** check for RX restart request **/
438 /**********************************/
439
440 if ((ch->ch_start_rx) && (ch->status & RX_ENABLED))
441 {
442
443 ch->ch_start_rx = 0;
444#if defined(RLD_TRANS_DEBUG) || defined(RLD_RXACT_DEBUG)
445 {
446 static int hereb4 = 7;
447
448 if (hereb4) /* RLD DEBUG */
449 {
450 hereb4--;
451#ifdef RLD_TRANS_DEBUG
452 md = &ch->mdr[ch->rxix_irq_srv];
453 printk ("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n",
454 ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status),
455 ch->s.rx_packets);
456#elif defined(RLD_RXACT_DEBUG)
457 md = &ch->mdr[ch->rxix_irq_srv];
458 printk ("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n",
459 ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status),
460 ch->s.rx_packets);
461 musycc_dump_rxbuffer_ring (ch, 1); /* RLD DEBUG */
462#endif
463 }
464 }
465#endif
466 musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | ch->gchan);
467 }
468 /**********************************/
469 /** check for TX restart request **/
470 /**********************************/
471
472 if ((ch->ch_start_tx) && (ch->status & TX_ENABLED))
473 {
474 /* find next unprocessed message, then set TX thp to it */
475 musycc_update_tx_thp (ch);
476
477#if 0
478 spin_lock_irqsave (&ch->ch_txlock, flags);
479#endif
480 md = ch->txd_irq_srv;
481 if (!md)
482 {
483#ifdef RLD_TRANS_DEBUG
484 printk ("-- musycc_wq_chan_restart[%d]: WARNING, starting NULL md\n", ch->channum);
485#endif
486#if 0
487 spin_unlock_irqrestore (&ch->ch_txlock, flags);
488#endif
489 } else if (md->data && ((le32_to_cpu (md->status)) & MUSYCC_TX_OWNED))
490 {
491 ch->ch_start_tx = 0;
492#if 0
493 spin_unlock_irqrestore (&ch->ch_txlock, flags); /* allow interrupts for service request */
494#endif
495#ifdef RLD_TRANS_DEBUG
496 printk ("++ musycc_wq_chan_restart() CHAN TX ACTIVATE: chan %d txd_irq_srv %p = sts %x, txpkt %lu\n",
497 ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status, ch->s.tx_packets);
498#endif
499 musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION | ch->gchan);
500 }
501#ifdef RLD_RESTART_DEBUG
502 else
503 {
504 /* retain request to start until retried and we have data to xmit */
505 printk ("-- musycc_wq_chan_restart[%d]: DELAYED due to md %p sts %x data %x, start_tx %x\n",
506 ch->channum, md,
507 le32_to_cpu (md->status),
508 le32_to_cpu (md->data), ch->ch_start_tx);
509 musycc_dump_txbuffer_ring (ch, 0);
510#if 0
511 spin_unlock_irqrestore (&ch->ch_txlock, flags); /* allow interrupts for service request */
512#endif
513 }
514#endif
515 }
516}
517#endif
518
519
520 /*
521 * Channel restart either fires of a workqueue request (2.6) or lodges a
522 * watchdog activation sequence (2.4).
523 */
524
525void
526musycc_chan_restart (mch_t * ch)
527{
528#ifdef RLD_RESTART_DEBUG
529 printk ("++ musycc_chan_restart[%d]: txd_irq_srv @ %p = sts %x\n",
530 ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status);
531#endif
532
533#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
534 /* 2.6 - find next unprocessed message, then set TX thp to it */
535#ifdef RLD_RESTART_DEBUG
536 printk (">> musycc_chan_restart: scheduling Chan %x workQ @ %p\n", ch->channum, &ch->ch_work);
537#endif
538 c4_wk_chan_restart (ch); /* work queue mechanism fires off: Ref:
539 * musycc_wq_chan_restart () */
540
541#else
542
543
544 /* 2.4 - find next unprocessed message, then set TX thp to it */
545#ifdef RLD_RESTART_DEBUG
546 printk (">> musycc_chan_restart: scheduling Chan %x start_tx %x\n", ch->channum, ch->ch_start_tx);
547#endif
548 /* restart transmission from background loop */
549 ch->up->up->wd_notify = WD_NOTIFY_1TX;
550#endif
551}
552
553
554#if 0
555void
556musycc_cleanup (ci_t * ci)
557{
558 mpi_t *pi;
559 int i, j;
560
561 /* free up driver resources */
562 ci->state = C_INIT; /* mark as hardware not available */
563
564 for (i = 0; i < ci->max_ports; i++)
565 {
566 pi = &ci->port[i];
567#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
568 c4_wq_port_cleanup (pi);
569#endif
570 for (j = 0; j < MUSYCC_NCHANS; j++)
571 {
572 if (pi->chan[j])
573 OS_kfree (pi->chan[j]); /* free mch_t struct */
574 }
575 OS_kfree (pi->regram_saved);
576 }
577#if 0
578 /* obsolete - watchdog is now static w/in ci_t */
579 OS_free_watchdog (ci->wd);
580#endif
581 OS_kfree (ci->iqd_p_saved);
582 OS_kfree (ci);
583}
584#endif
585
586void
587rld_put_led (mpi_t * pi, u_int32_t ledval)
588{
589 static u_int32_t led = 0;
590
591 if (ledval == 0)
592 led = 0;
593 else
594 led |= ledval;
595
596 pci_write_32 ((u_int32_t *) &pi->up->cpldbase->leds, led); /* RLD DEBUG TRANHANG */
597}
598
599
600#define MUSYCC_SR_RETRY_CNT 9
601
602void
603musycc_serv_req (mpi_t * pi, u_int32_t req)
604{
605 volatile u_int32_t r;
606 int rcnt;
607
608 /*
609 * PORT NOTE: Semaphore protect service loop guarantees only a single
610 * operation at a time. Per MUSYCC Manual - "Issuing service requests to
611 * the same channel group without first receiving ACK from each request
612 * may cause the host to lose track of which service request has been
613 * acknowledged."
614 */
615
616 SD_SEM_TAKE (&pi->sr_sem_busy, "serv"); /* only 1 thru here, per
617 * group */
618
619 if (pi->sr_last == req)
620 {
621#ifdef RLD_TRANS_DEBUG
622 printk (">> same SR, Port %d Req %x\n", pi->portnum, req);
623#endif
624
625 /*
626 * The most likely repeated request is the channel activation command
627 * which follows the occurrence of a Transparent mode TX ONR or a
628 * BUFF error. If the previous command was a CHANNEL ACTIVATE,
629 * precede it with a NOOP command in order maintain coherent control
630 * of this current (re)ACTIVATE.
631 */
632
633 r = (pi->sr_last & ~SR_GCHANNEL_MASK);
634 if ((r == (SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION)) ||
635 (r == (SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION)))
636 {
637#ifdef RLD_TRANS_DEBUG
638 printk (">> same CHAN ACT SR, Port %d Req %x => issue SR_NOOP CMD\n", pi->portnum, req);
639#endif
640 SD_SEM_GIVE (&pi->sr_sem_busy); /* allow this next request */
641 musycc_serv_req (pi, SR_NOOP);
642 SD_SEM_TAKE (&pi->sr_sem_busy, "serv"); /* relock & continue w/
643 * original req */
644 } else if (req == SR_NOOP)
645 {
646 /* no need to issue back-to-back SR_NOOP commands at this time */
647#ifdef RLD_TRANS_DEBUG
648 printk (">> same Port SR_NOOP skipped, Port %d\n", pi->portnum);
649#endif
650 SD_SEM_GIVE (&pi->sr_sem_busy); /* allow this next request */
651 return;
652 }
653 }
654 rcnt = 0;
655 pi->sr_last = req;
656rewrite:
657 pci_write_32 ((u_int32_t *) &pi->reg->srd, req);
658 FLUSH_MEM_WRITE ();
659
660 /*
661 * Per MUSYCC Manual, Section 6.1,2 - "When writing an SCR service
662 * request, the host must ensure at least one PCI bus clock cycle has
663 * elapsed before writing another service request. To meet this minimum
664 * elapsed service request write timing interval, it is recommended that
665 * the host follow any SCR write with another operation which reads from
666 * the same address."
667 */
668 r = pci_read_32 ((u_int32_t *) &pi->reg->srd); /* adhere to write
669 * timing imposition */
670
671
672 if ((r != req) && (req != SR_CHIP_RESET) && (++rcnt <= MUSYCC_SR_RETRY_CNT))
673 {
674 if (log_level >= LOG_MONITOR)
675 printk ("%s: %d - reissue srv req/last %x/%x (hdw reads %x), Chan %d.\n",
676 pi->up->devname, rcnt, req, pi->sr_last, r,
677 (pi->portnum * MUSYCC_NCHANS) + (req & 0x1f));
678 OS_uwait_dummy (); /* this delay helps reduce reissue counts
679 * (reason not yet researched) */
680 goto rewrite;
681 }
682 if (rcnt > MUSYCC_SR_RETRY_CNT)
683 {
684 printk (KERN_WARNING "%s: failed service request (#%d)= %x, group %d.\n",
685 pi->up->devname, MUSYCC_SR_RETRY_CNT, req, pi->portnum);
686 SD_SEM_GIVE (&pi->sr_sem_busy); /* allow any next request */
687 return;
688 }
689 if (req == SR_CHIP_RESET)
690 {
691 /*
692 * PORT NOTE: the CHIP_RESET command is NOT ack'd by the MUSYCC, thus
693 * the upcoming delay is used. Though the MUSYCC documentation
694 * suggests a read-after-write would supply the required delay, it's
695 * unclear what CPU/BUS clock speeds might have been assumed when
696 * suggesting this 'lack of ACK' workaround. Thus the use of uwait.
697 */
698 OS_uwait (100000, "icard"); /* 100ms */
699 } else
700 {
701 FLUSH_MEM_READ ();
702 SD_SEM_TAKE (&pi->sr_sem_wait, "sakack"); /* sleep until SACK
703 * interrupt occurs */
704 }
705 SD_SEM_GIVE (&pi->sr_sem_busy); /* allow any next request */
706}
707
708
709#ifdef SBE_PMCC4_ENABLE
710void
711musycc_update_timeslots (mpi_t * pi)
712{
713 int i, ch;
714 char e1mode = IS_FRAME_ANY_E1 (pi->p.port_mode);
715
716 for (i = 0; i < 32; i++)
717 {
718 int usedby = 0, last = 0, ts, j, bits[8];
719
720 u_int8_t lastval = 0;
721
722 if (((i == 0) && e1mode) || /* disable if E1 mode */
723 ((i == 16) && ((pi->p.port_mode == CFG_FRAME_E1CRC_CAS) || (pi->p.port_mode == CFG_FRAME_E1CRC_CAS_AMI)))
724 || ((i > 23) && (!e1mode))) /* disable if T1 mode */
725 {
726 pi->tsm[i] = 0xff; /* make tslot unavailable for this mode */
727 } else
728 {
729 pi->tsm[i] = 0x00; /* make tslot available for assignment */
730 }
731 for (j = 0; j < 8; j++)
732 bits[j] = -1;
733 for (ch = 0; ch < MUSYCC_NCHANS; ch++)
734 {
735 if ((pi->chan[ch]->state == UP) && (pi->chan[ch]->p.bitmask[i]))
736 {
737 usedby++;
738 last = ch;
739 lastval = pi->chan[ch]->p.bitmask[i];
740 for (j = 0; j < 8; j++)
741 if (lastval & (1 << j))
742 bits[j] = ch;
743 pi->tsm[i] |= lastval;
744 }
745 }
746 if (!usedby)
747 ts = 0;
748 else if ((usedby == 1) && (lastval == 0xff))
749 ts = (4 << 5) | last;
750 else if ((usedby == 1) && (lastval == 0x7f))
751 ts = (5 << 5) | last;
752 else
753 {
754 int idx;
755
756 if (bits[0] < 0)
757 ts = (6 << 5) | (idx = last);
758 else
759 ts = (7 << 5) | (idx = bits[0]);
760 for (j = 1; j < 8; j++)
761 {
762 pi->regram->rscm[idx * 8 + j] = (bits[j] < 0) ? 0 : (0x80 | bits[j]);
763 pi->regram->tscm[idx * 8 + j] = (bits[j] < 0) ? 0 : (0x80 | bits[j]);
764 }
765 }
766 pi->regram->rtsm[i] = ts;
767 pi->regram->ttsm[i] = ts;
768 }
769 FLUSH_MEM_WRITE ();
770
771 musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_RX_DIRECTION);
772 musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_TX_DIRECTION);
773 musycc_serv_req (pi, SR_SUBCHANNEL_MAP | SR_RX_DIRECTION);
774 musycc_serv_req (pi, SR_SUBCHANNEL_MAP | SR_TX_DIRECTION);
775}
776#endif
777
778
779#ifdef SBE_WAN256T3_ENABLE
780void
781musycc_update_timeslots (mpi_t * pi)
782{
783 mch_t *ch;
784
785 u_int8_t ts, hmask, tsen;
786 int gchan;
787 int i;
788
789#ifdef SBE_PMCC4_ENABLE
790 hmask = (0x1f << pi->up->p.hypersize) & 0x1f;
791#endif
792#ifdef SBE_WAN256T3_ENABLE
793 hmask = (0x1f << hyperdummy) & 0x1f;
794#endif
795 for (i = 0; i < 128; i++)
796 {
797 gchan = ((pi->portnum * MUSYCC_NCHANS) + (i & hmask)) % MUSYCC_NCHANS;
798 ch = pi->chan[gchan];
799 if (ch->p.mode_56k)
800 tsen = MODE_56KBPS;
801 else
802 tsen = MODE_64KBPS; /* also the default */
803 ts = ((pi->portnum % 4) == (i / 32)) ? (tsen << 5) | (i & hmask) : 0;
804 pi->regram->rtsm[i] = ts;
805 pi->regram->ttsm[i] = ts;
806 }
807 FLUSH_MEM_WRITE ();
808 musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_RX_DIRECTION);
809 musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_TX_DIRECTION);
810}
811#endif
812
813
814 /*
815 * This routine converts a generic library channel configuration parameter
816 * into a hardware specific register value (IE. MUSYCC CCD Register).
817 */
818u_int32_t
819musycc_chan_proto (int proto)
820{
821 int reg;
822
823 switch (proto)
824 {
825 case CFG_CH_PROTO_TRANS: /* 0 */
826 reg = MUSYCC_CCD_TRANS;
827 break;
828 case CFG_CH_PROTO_SS7: /* 1 */
829 reg = MUSYCC_CCD_SS7;
830 break;
831 default:
832 case CFG_CH_PROTO_ISLP_MODE: /* 4 */
833 case CFG_CH_PROTO_HDLC_FCS16: /* 2 */
834 reg = MUSYCC_CCD_HDLC_FCS16;
835 break;
836 case CFG_CH_PROTO_HDLC_FCS32: /* 3 */
837 reg = MUSYCC_CCD_HDLC_FCS32;
838 break;
839 }
840
841 return reg;
842}
843
844#ifdef SBE_WAN256T3_ENABLE
845STATIC void __init
846musycc_init_port (mpi_t * pi)
847{
848 pci_write_32 ((u_int32_t *) &pi->reg->gbp, OS_vtophys (pi->regram));
849
850 pi->regram->grcd =
851 __constant_cpu_to_le32 (MUSYCC_GRCD_RX_ENABLE |
852 MUSYCC_GRCD_TX_ENABLE |
853 MUSYCC_GRCD_SF_ALIGN |
854 MUSYCC_GRCD_SUBCHAN_DISABLE |
855 MUSYCC_GRCD_OOFMP_DISABLE |
856 MUSYCC_GRCD_COFAIRQ_DISABLE |
857 MUSYCC_GRCD_MC_ENABLE |
858 (MUSYCC_GRCD_POLLTH_32 << MUSYCC_GRCD_POLLTH_SHIFT));
859
860 pi->regram->pcd =
861 __constant_cpu_to_le32 (MUSYCC_PCD_E1X4_MODE |
862 MUSYCC_PCD_TXDATA_RISING |
863 MUSYCC_PCD_TX_DRIVEN);
864
865 /* Message length descriptor */
866 pi->regram->mld = __constant_cpu_to_le32 (max_mru | (max_mru << 16));
867 FLUSH_MEM_WRITE ();
868
869 musycc_serv_req (pi, SR_GROUP_INIT | SR_RX_DIRECTION);
870 musycc_serv_req (pi, SR_GROUP_INIT | SR_TX_DIRECTION);
871
872 musycc_init_mdt (pi);
873
874 musycc_update_timeslots (pi);
875}
876#endif
877
878
879status_t __init
880musycc_init (ci_t * ci)
881{
882 char *regaddr; /* temp for address boundary calculations */
883 int i, gchan;
884
885 OS_sem_init (&ci->sem_wdbusy, SEM_AVAILABLE); /* watchdog exclusion */
886
887 /*
888 * Per MUSYCC manual, Section 6.3.4 - "The host must allocate a dword
889 * aligned memory segment for interrupt queue pointers."
890 */
891
892#define INT_QUEUE_BOUNDARY 4
893
894 regaddr = OS_kmalloc ((INT_QUEUE_SIZE + 1) * sizeof (u_int32_t));
895 if (regaddr == 0)
896 return ENOMEM;
897 ci->iqd_p_saved = regaddr; /* save orig value for free's usage */
898 ci->iqd_p = (u_int32_t *) ((unsigned long) (regaddr + INT_QUEUE_BOUNDARY - 1) &
899 (~(INT_QUEUE_BOUNDARY - 1))); /* this calculates
900 * closest boundary */
901
902 for (i = 0; i < INT_QUEUE_SIZE; i++)
903 {
904 ci->iqd_p[i] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY);
905 }
906
907 for (i = 0; i < ci->max_port; i++)
908 {
909 mpi_t *pi = &ci->port[i];
910
911 /*
912 * Per MUSYCC manual, Section 6.3.2 - "The host must allocate a 2KB
913 * bound memory segment for Channel Group 0."
914 */
915
916#define GROUP_BOUNDARY 0x800
917
918 regaddr = OS_kmalloc (sizeof (struct musycc_groupr) + GROUP_BOUNDARY);
919 if (regaddr == 0)
920 {
921 for (gchan = 0; gchan < i; gchan++)
922 {
923 pi = &ci->port[gchan];
924 OS_kfree (pi->reg);
925 pi->reg = 0;
926 }
927 return ENOMEM;
928 }
929 pi->regram_saved = regaddr; /* save orig value for free's usage */
930 pi->regram = (struct musycc_groupr *) ((unsigned long) (regaddr + GROUP_BOUNDARY - 1) &
931 (~(GROUP_BOUNDARY - 1))); /* this calculates
932 * closest boundary */
933 }
934
935 /* any board centric MUSYCC commands will use group ZERO as its "home" */
936 ci->regram = ci->port[0].regram;
937 musycc_serv_req (&ci->port[0], SR_CHIP_RESET);
938
939 pci_write_32 ((u_int32_t *) &ci->reg->gbp, OS_vtophys (ci->regram));
940 pci_flush_write (ci);
941#ifdef CONFIG_SBE_PMCC4_NCOMM
942 ci->regram->__glcd = __constant_cpu_to_le32 (GCD_MAGIC);
943#else
944 /* standard driver POLLS for INTB via CPLD register */
945 ci->regram->__glcd = __constant_cpu_to_le32 (GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
946#endif
947
948 ci->regram->__iqp = cpu_to_le32 (OS_vtophys (&ci->iqd_p[0]));
949 ci->regram->__iql = __constant_cpu_to_le32 (INT_QUEUE_SIZE - 1);
950 pci_write_32 ((u_int32_t *) &ci->reg->dacbp, 0);
951 FLUSH_MEM_WRITE ();
952
953 ci->state = C_RUNNING; /* mark as full interrupt processing
954 * available */
955
956 musycc_serv_req (&ci->port[0], SR_GLOBAL_INIT); /* FIRST INTERRUPT ! */
957
958 /* sanity check settable parameters */
959
960 if (max_mru > 0xffe)
961 {
962 printk (KERN_WARNING "%s: Maximum allowed MRU exceeded, resetting %d to %d.\n",
963 THIS_MODULE->name, max_mru, 0xffe);
964 max_mru = 0xffe;
965 }
966 if (max_mtu > 0xffe)
967 {
968 printk (KERN_WARNING "%s: Maximum allowed MTU exceeded, resetting %d to %d.\n",
969 THIS_MODULE->name, max_mtu, 0xffe);
970 max_mtu = 0xffe;
971 }
972#ifdef SBE_WAN256T3_ENABLE
973 for (i = 0; i < MUSYCC_NPORTS; i++)
974 musycc_init_port (&ci->port[i]);
975#endif
976
977 return SBE_DRVR_SUCCESS; /* no error */
978}
979
980
981void
982musycc_bh_tx_eom (mpi_t * pi, int gchan)
983{
984 mch_t *ch;
985 struct mdesc *md;
986
987#if 0
988#ifndef SBE_ISR_INLINE
989 unsigned long flags;
990
991#endif
992#endif
993 volatile u_int32_t status;
994
995 ch = pi->chan[gchan];
996 if (ch == 0 || ch->state != UP)
997 {
998 if (log_level >= LOG_ERROR)
999 printk ("%s: intr: xmit EOM on uninitialized channel %d\n", pi->up->devname, gchan);
1000 }
1001 if (ch == 0 || ch->mdt == 0)
1002 return; /* note: mdt==0 implies a malloc()
1003 * failure w/in chan_up() routine */
1004
1005#if 0
1006#ifdef SBE_ISR_INLINE
1007 spin_lock_irq (&ch->ch_txlock);
1008#else
1009 spin_lock_irqsave (&ch->ch_txlock, flags);
1010#endif
1011#endif
1012 do
1013 {
1014 FLUSH_MEM_READ ();
1015 md = ch->txd_irq_srv;
1016 status = le32_to_cpu (md->status);
1017
1018 /*
1019 * Note: Per MUSYCC Ref 6.4.9, the host does not poll a host-owned
1020 * Transmit Buffer Descriptor during Transparent Mode.
1021 */
1022 if (status & MUSYCC_TX_OWNED)
1023 {
1024 int readCount, loopCount;
1025
1026 /***********************************************************/
1027 /* HW Bug Fix */
1028 /* ---------- */
1029 /* Under certain PCI Bus loading conditions, the data */
1030 /* associated with an update of Shared Memory is delayed */
1031 /* relative to its PCI Interrupt. This is caught when */
1032 /* the host determines it does not yet OWN the descriptor. */
1033 /***********************************************************/
1034
1035 readCount = 0;
1036 while (status & MUSYCC_TX_OWNED)
1037 {
1038 for (loopCount = 0; loopCount < 0x30; loopCount++)
1039 OS_uwait_dummy (); /* use call to avoid optimization
1040 * removal of dummy delay */
1041 FLUSH_MEM_READ ();
1042 status = le32_to_cpu (md->status);
1043 if (readCount++ > 40)
1044 break; /* don't wait any longer */
1045 }
1046 if (status & MUSYCC_TX_OWNED)
1047 {
1048 if (log_level >= LOG_MONITOR)
1049 {
1050 printk ("%s: Port %d Chan %2d - unexpected TX msg ownership intr (md %p sts %x)\n",
1051 pi->up->devname, pi->portnum, ch->channum, md, status);
1052 printk ("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n",
1053 ch->user, ch->txd_irq_srv, ch->txd_usr_add,
1054 sd_queue_stopped (ch->user),
1055 ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode);
1056 musycc_dump_txbuffer_ring (ch, 0);
1057 }
1058 break; /* Not our mdesc, done */
1059 } else
1060 {
1061 if (log_level >= LOG_MONITOR)
1062 printk ("%s: Port %d Chan %2d - recovered TX msg ownership [%d] (md %p sts %x)\n",
1063 pi->up->devname, pi->portnum, ch->channum, readCount, md, status);
1064 }
1065 }
1066 ch->txd_irq_srv = md->snext;
1067
1068 md->data = 0;
1069 if (md->mem_token != 0)
1070 {
1071 /* upcount channel */
1072 atomic_sub (OS_mem_token_tlen (md->mem_token), &ch->tx_pending);
1073 /* upcount card */
1074 atomic_sub (OS_mem_token_tlen (md->mem_token), &pi->up->tx_pending);
1075#ifdef SBE_WAN256T3_ENABLE
1076 if (!atomic_read (&pi->up->tx_pending))
1077 wan256t3_led (pi->up, LED_TX, 0);
1078#endif
1079
1080#ifdef CONFIG_SBE_WAN256T3_NCOMM
1081 /* callback that our packet was sent */
1082 {
1083 int hdlcnum = (pi->portnum * 32 + gchan);
1084
1085 if (hdlcnum >= 228)
1086 {
1087 if (nciProcess_TX_complete)
1088 (*nciProcess_TX_complete) (hdlcnum,
1089 getuserbychan (gchan));
1090 }
1091 }
1092#endif /*** CONFIG_SBE_WAN256T3_NCOMM ***/
1093
1094 OS_mem_token_free_irq (md->mem_token);
1095 md->mem_token = 0;
1096 }
1097 md->status = 0;
1098#ifdef RLD_TXFULL_DEBUG
1099 if (log_level >= LOG_MONITOR2)
1100 printk ("~~ tx_eom: tx_full %x txd_free %d -> %d\n", ch->tx_full, ch->txd_free, ch->txd_free + 1);
1101#endif
1102 ++ch->txd_free;
1103 FLUSH_MEM_WRITE ();
1104
1105 if ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) && (status & EOBIRQ_ENABLE))
1106 {
1107 if (log_level >= LOG_MONITOR)
1108 printk ("%s: Mode (%x) incorrect EOB status (%x)\n",
1109 pi->up->devname, ch->p.chan_mode, status);
1110 if ((status & EOMIRQ_ENABLE) == 0)
1111 break;
1112 }
1113 }
1114 while ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) && ((status & EOMIRQ_ENABLE) == 0));
1115 /*
1116 * NOTE: (The above 'while' is coupled w/ previous 'do', way above.) Each
1117 * Transparent data buffer has the EOB bit, and NOT the EOM bit, set and
1118 * will furthermore have a separate IQD associated with each messages
1119 * buffer.
1120 */
1121
1122 FLUSH_MEM_READ ();
1123 /*
1124 * Smooth flow control hysterisis by maintaining task stoppage until half
1125 * the available write buffers are available.
1126 */
1127 if (ch->tx_full && (ch->txd_free >= (ch->txd_num / 2)))
1128 {
1129 /*
1130 * Then, only releave task stoppage if we actually have enough
1131 * buffers to service the last requested packet. It may require MORE
1132 * than half the available!
1133 */
1134 if (ch->txd_free >= ch->txd_required)
1135 {
1136
1137#ifdef RLD_TXFULL_DEBUG
1138 if (log_level >= LOG_MONITOR2)
1139 printk ("tx_eom[%d]: enable xmit tx_full no more, txd_free %d txd_num/2 %d\n",
1140 ch->channum,
1141 ch->txd_free, ch->txd_num / 2);
1142#endif
1143 ch->tx_full = 0;
1144 ch->txd_required = 0;
1145 sd_enable_xmit (ch->user); /* re-enable to catch flow controlled
1146 * channel */
1147 }
1148 }
1149#ifdef RLD_TXFULL_DEBUG
1150 else if (ch->tx_full)
1151 {
1152 if (log_level >= LOG_MONITOR2)
1153 printk ("tx_eom[%d]: bypass TX enable though room available? (txd_free %d txd_num/2 %d)\n",
1154 ch->channum,
1155 ch->txd_free, ch->txd_num / 2);
1156 }
1157#endif
1158
1159 FLUSH_MEM_WRITE ();
1160#if 0
1161#ifdef SBE_ISR_INLINE
1162 spin_unlock_irq (&ch->ch_txlock);
1163#else
1164 spin_unlock_irqrestore (&ch->ch_txlock, flags);
1165#endif
1166#endif
1167}
1168
1169
1170STATIC void
1171musycc_bh_rx_eom (mpi_t * pi, int gchan)
1172{
1173 mch_t *ch;
1174 void *m, *m2;
1175 struct mdesc *md;
1176 volatile u_int32_t status;
1177 u_int32_t error;
1178
1179 ch = pi->chan[gchan];
1180 if (ch == 0 || ch->state != UP)
1181 {
1182 if (log_level > LOG_ERROR)
1183 printk ("%s: intr: receive EOM on uninitialized channel %d\n", pi->up->devname, gchan);
1184 return;
1185 }
1186 if (ch->mdr == 0)
1187 return; /* can this happen ? */
1188
1189 for (;;)
1190 {
1191 FLUSH_MEM_READ ();
1192 md = &ch->mdr[ch->rxix_irq_srv];
1193 status = le32_to_cpu (md->status);
1194 if (!(status & HOST_RX_OWNED))
1195 break; /* Not our mdesc, done */
1196 m = md->mem_token;
1197 error = (status >> 16) & 0xf;
1198 if (error == 0)
1199 {
1200#ifdef CONFIG_SBE_WAN256T3_NCOMM
1201 int hdlcnum = (pi->portnum * 32 + gchan);
1202
1203 /*
1204 * if the packet number belongs to NCOMM, then send it to the TMS
1205 * driver
1206 */
1207 if (hdlcnum >= 228)
1208 {
1209 if (nciProcess_RX_packet)
1210 (*nciProcess_RX_packet) (hdlcnum, status & 0x3fff, m, ch->user);
1211 } else
1212#endif /*** CONFIG_SBE_WAN256T3_NCOMM ***/
1213
1214 {
1215 if ((m2 = OS_mem_token_alloc (max_mru)))
1216 {
1217 /* substitute the mbuf+cluster */
1218 md->mem_token = m2;
1219 md->data = cpu_to_le32 (OS_vtophys (OS_mem_token_data (m2)));
1220
1221 /* pass the received mbuf upward */
1222 sd_recv_consume (m, status & LENGTH_MASK, ch->user);
1223 ch->s.rx_packets++;
1224 ch->s.rx_bytes += status & LENGTH_MASK;
1225 } else
1226 {
1227 ch->s.rx_dropped++;
1228 }
1229 }
1230 } else if (error == ERR_FCS)
1231 {
1232 ch->s.rx_crc_errors++;
1233 } else if (error == ERR_ALIGN)
1234 {
1235 ch->s.rx_missed_errors++;
1236 } else if (error == ERR_ABT)
1237 {
1238 ch->s.rx_missed_errors++;
1239 } else if (error == ERR_LNG)
1240 {
1241 ch->s.rx_length_errors++;
1242 } else if (error == ERR_SHT)
1243 {
1244 ch->s.rx_length_errors++;
1245 }
1246 FLUSH_MEM_WRITE ();
1247 status = max_mru;
1248 if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
1249 status |= EOBIRQ_ENABLE;
1250 md->status = cpu_to_le32 (status);
1251
1252 /* Check next mdesc in the ring */
1253 if (++ch->rxix_irq_srv >= ch->rxd_num)
1254 ch->rxix_irq_srv = 0;
1255 FLUSH_MEM_WRITE ();
1256 }
1257}
1258
1259
1260irqreturn_t
1261musycc_intr_th_handler (void *devp)
1262{
1263 ci_t *ci = (ci_t *) devp;
1264 volatile u_int32_t status, currInt = 0;
1265 u_int32_t nextInt, intCnt;
1266
1267 /*
1268 * Hardware not available, potential interrupt hang. But since interrupt
1269 * might be shared, just return.
1270 */
1271 if (ci->state == C_INIT)
1272 {
1273 return IRQ_NONE;
1274 }
1275 /*
1276 * Marked as hardware available. Don't service interrupts, just clear the
1277 * event.
1278 */
1279
1280 if (ci->state == C_IDLE)
1281 {
1282 status = pci_read_32 ((u_int32_t *) &ci->reg->isd);
1283
1284 /* clear the interrupt but process nothing else */
1285 pci_write_32 ((u_int32_t *) &ci->reg->isd, status);
1286 return IRQ_HANDLED;
1287 }
1288 FLUSH_PCI_READ ();
1289 FLUSH_MEM_READ ();
1290
1291 status = pci_read_32 ((u_int32_t *) &ci->reg->isd);
1292 nextInt = INTRPTS_NEXTINT (status);
1293 intCnt = INTRPTS_INTCNT (status);
1294 ci->intlog.drvr_intr_thcount++;
1295
1296 /*********************************************************/
1297 /* HW Bug Fix */
1298 /* ---------- */
1299 /* Under certain PCI Bus loading conditions, the */
1300 /* MUSYCC looses the data associated with an update */
1301 /* of its ISD and erroneously returns the immediately */
1302 /* preceding 'nextInt' value. However, the 'intCnt' */
1303 /* value appears to be correct. By not starting service */
1304 /* where the 'missing' 'nextInt' SHOULD point causes */
1305 /* the IQD not to be serviced - the 'not serviced' */
1306 /* entries then remain and continue to increase as more */
1307 /* incorrect ISD's are encountered. */
1308 /*********************************************************/
1309
1310 if (nextInt != INTRPTS_NEXTINT (ci->intlog.this_status_new))
1311 {
1312 if (log_level >= LOG_MONITOR)
1313 {
1314 printk ("%s: note - updated ISD from %08x to %08x\n",
1315 ci->devname, status,
1316 (status & (~INTRPTS_NEXTINT_M)) | ci->intlog.this_status_new);
1317 }
1318 /*
1319 * Replace bogus status with software corrected value.
1320 *
1321 * It's not known whether, during this problem occurrence, if the
1322 * INTFULL bit is correctly reported or not.
1323 */
1324 status = (status & (~INTRPTS_NEXTINT_M)) | (ci->intlog.this_status_new);
1325 nextInt = INTRPTS_NEXTINT (status);
1326 }
1327 /**********************************************/
1328 /* Cn847x Bug Fix */
1329 /* -------------- */
1330 /* Fix for inability to write back same index */
1331 /* as read for a full interrupt queue. */
1332 /**********************************************/
1333
1334 if (intCnt == INT_QUEUE_SIZE)
1335 {
1336 currInt = ((intCnt - 1) + nextInt) & (INT_QUEUE_SIZE - 1);
1337 } else
1338 /************************************************/
1339 /* Interrupt Write Location Issues */
1340 /* ------------------------------- */
1341 /* When the interrupt status descriptor is */
1342 /* written, the interrupt line is de-asserted */
1343 /* by the Cn847x. In the case of MIPS */
1344 /* microprocessors, this must occur at the */
1345 /* beginning of the interrupt handler so that */
1346 /* the interrupt handle is not re-entered due */
1347 /* to interrupt dis-assertion latency. */
1348 /* In the case of all other processors, this */
1349 /* action should occur at the end of the */
1350 /* interrupt handler to avoid overwriting the */
1351 /* interrupt queue. */
1352 /************************************************/
1353
1354 if (intCnt)
1355 {
1356 currInt = (intCnt + nextInt) & (INT_QUEUE_SIZE - 1);
1357 } else
1358 {
1359 /*
1360 * NOTE: Servicing an interrupt whose ISD contains a count of ZERO
1361 * can be indicative of a Shared Interrupt chain. Our driver can be
1362 * called from the system's interrupt handler as a matter of the OS
1363 * walking the chain. As the chain is walked, the interrupt will
1364 * eventually be serviced by the correct driver/handler.
1365 */
1366#if 0
1367 /* chained interrupt = not ours */
1368 printk (">> %s: intCnt NULL, sts %x, possibly a chained interrupt!\n",
1369 ci->devname, status);
1370#endif
1371 return IRQ_NONE;
1372 }
1373
1374 ci->iqp_tailx = currInt;
1375
1376 currInt <<= INTRPTS_NEXTINT_S;
1377 ci->intlog.last_status_new = ci->intlog.this_status_new;
1378 ci->intlog.this_status_new = currInt;
1379
1380 if ((log_level >= LOG_WARN) && (status & INTRPTS_INTFULL_M))
1381 {
1382 printk ("%s: Interrupt queue full condition occurred\n", ci->devname);
1383 }
1384 if (log_level >= LOG_DEBUG)
1385 printk ("%s: interrupts pending, isd @ 0x%p: %x curr %d cnt %d NEXT %d\n",
1386 ci->devname, &ci->reg->isd,
1387 status, nextInt, intCnt, (intCnt + nextInt) & (INT_QUEUE_SIZE - 1));
1388
1389 FLUSH_MEM_WRITE ();
1390#if defined(SBE_ISR_TASKLET)
1391 pci_write_32 ((u_int32_t *) &ci->reg->isd, currInt);
1392 atomic_inc (&ci->bh_pending);
1393 tasklet_schedule (&ci->ci_musycc_isr_tasklet);
1394#elif defined(SBE_ISR_IMMEDIATE)
1395 pci_write_32 ((u_int32_t *) &ci->reg->isd, currInt);
1396 atomic_inc (&ci->bh_pending);
1397 queue_task (&ci->ci_musycc_isr_tq, &tq_immediate);
1398 mark_bh (IMMEDIATE_BH);
1399#elif defined(SBE_ISR_INLINE)
1400 (void) musycc_intr_bh_tasklet (ci);
1401 pci_write_32 ((u_int32_t *) &ci->reg->isd, currInt);
1402#endif
1403 return IRQ_HANDLED;
1404}
1405
1406
1407#if defined(SBE_ISR_IMMEDIATE)
1408unsigned long
1409#else
1410void
1411#endif
1412musycc_intr_bh_tasklet (ci_t * ci)
1413{
1414 mpi_t *pi;
1415 mch_t *ch;
1416 unsigned int intCnt;
1417 volatile u_int32_t currInt = 0;
1418 volatile unsigned int headx, tailx;
1419 int readCount, loopCount;
1420 int group, gchan, event, err, tx;
1421 u_int32_t badInt = INT_EMPTY_ENTRY;
1422 u_int32_t badInt2 = INT_EMPTY_ENTRY2;
1423
1424 /*
1425 * Hardware not available, potential interrupt hang. But since interrupt
1426 * might be shared, just return.
1427 */
1428 if ((drvr_state != SBE_DRVR_AVAILABLE) || (ci->state == C_INIT))
1429 {
1430#if defined(SBE_ISR_IMMEDIATE)
1431 return 0L;
1432#else
1433 return;
1434#endif
1435 }
1436#if defined(SBE_ISR_TASKLET) || defined(SBE_ISR_IMMEDIATE)
1437 if (drvr_state != SBE_DRVR_AVAILABLE)
1438 {
1439#if defined(SBE_ISR_TASKLET)
1440 return;
1441#elif defined(SBE_ISR_IMMEDIATE)
1442 return 0L;
1443#endif
1444 }
1445#elif defined(SBE_ISR_INLINE)
1446 /* no semaphore taken, no double checks */
1447#endif
1448
1449 ci->intlog.drvr_intr_bhcount++;
1450 FLUSH_MEM_READ ();
1451 {
1452 unsigned int bh = atomic_read (&ci->bh_pending);
1453
1454 max_bh = max (bh, max_bh);
1455 }
1456 atomic_set (&ci->bh_pending, 0);/* if here, no longer pending */
1457 while ((headx = ci->iqp_headx) != (tailx = ci->iqp_tailx))
1458 {
1459 intCnt = (tailx >= headx) ? (tailx - headx) : (tailx - headx + INT_QUEUE_SIZE);
1460 currInt = le32_to_cpu (ci->iqd_p[headx]);
1461
1462 max_intcnt = max (intCnt, max_intcnt); /* RLD DEBUG */
1463
1464 /**************************************************/
1465 /* HW Bug Fix */
1466 /* ---------- */
1467 /* The following code checks for the condition */
1468 /* of interrupt assertion before interrupt */
1469 /* queue update. This is a problem on several */
1470 /* PCI-Local bridge chips found on some products. */
1471 /**************************************************/
1472
1473 readCount = 0;
1474 if ((currInt == badInt) || (currInt == badInt2))
1475 ci->intlog.drvr_int_failure++;
1476
1477 while ((currInt == badInt) || (currInt == badInt2))
1478 {
1479 for (loopCount = 0; loopCount < 0x30; loopCount++)
1480 OS_uwait_dummy (); /* use call to avoid optimization removal
1481 * of dummy delay */
1482 FLUSH_MEM_READ ();
1483 currInt = le32_to_cpu (ci->iqd_p[headx]);
1484 if (readCount++ > 20)
1485 break;
1486 }
1487
1488 if ((currInt == badInt) || (currInt == badInt2)) /* catch failure of Bug
1489 * Fix checking */
1490 {
1491 if (log_level >= LOG_WARN)
1492 printk ("%s: Illegal Interrupt Detected @ 0x%p, mod %d.)\n",
1493 ci->devname, &ci->iqd_p[headx], headx);
1494
1495 /*
1496 * If the descriptor has not recovered, then leaving the EMPTY
1497 * entry set will not signal to the MUSYCC that this descriptor
1498 * has been serviced. The Interrupt Queue can then start loosing
1499 * available descriptors and MUSYCC eventually encounters and
1500 * reports the INTFULL condition. Per manual, changing any bit
1501 * marks descriptor as available, thus the use of different
1502 * EMPTY_ENTRY values.
1503 */
1504
1505 if (currInt == badInt)
1506 {
1507 ci->iqd_p[headx] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY2);
1508 } else
1509 {
1510 ci->iqd_p[headx] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY);
1511 }
1512 ci->iqp_headx = (headx + 1) & (INT_QUEUE_SIZE - 1); /* insure wrapness */
1513 FLUSH_MEM_WRITE ();
1514 FLUSH_MEM_READ ();
1515 continue;
1516 }
1517 group = INTRPT_GRP (currInt);
1518 gchan = INTRPT_CH (currInt);
1519 event = INTRPT_EVENT (currInt);
1520 err = INTRPT_ERROR (currInt);
1521 tx = currInt & INTRPT_DIR_M;
1522
1523 ci->iqd_p[headx] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY);
1524 FLUSH_MEM_WRITE ();
1525
1526 if (log_level >= LOG_DEBUG)
1527 {
1528 if (err != 0)
1529 printk (" %08x -> err: %2d,", currInt, err);
1530
1531 printk ("+ interrupt event: %d, grp: %d, chan: %2d, side: %cX\n",
1532 event, group, gchan, tx ? 'T' : 'R');
1533 }
1534 pi = &ci->port[group]; /* notice that here we assume 1-1 group -
1535 * port mapping */
1536 ch = pi->chan[gchan];
1537 switch (event)
1538 {
1539 case EVE_SACK: /* Service Request Acknowledge */
1540 if (log_level >= LOG_DEBUG)
1541 {
1542 volatile u_int32_t r;
1543
1544 r = pci_read_32 ((u_int32_t *) &pi->reg->srd);
1545 printk ("- SACK cmd: %08x (hdw= %08x)\n", pi->sr_last, r);
1546 }
1547 SD_SEM_GIVE (&pi->sr_sem_wait); /* wake up waiting process */
1548 break;
1549 case EVE_CHABT: /* Change To Abort Code (0x7e -> 0xff) */
1550 case EVE_CHIC: /* Change To Idle Code (0xff -> 0x7e) */
1551 break;
1552 case EVE_EOM: /* End Of Message */
1553 case EVE_EOB: /* End Of Buffer (Transparent mode) */
1554 if (tx)
1555 {
1556 musycc_bh_tx_eom (pi, gchan);
1557 } else
1558 {
1559 musycc_bh_rx_eom (pi, gchan);
1560 }
1561#if 0
1562 break;
1563#else
1564 /*
1565 * MUSYCC Interrupt Descriptor section states that EOB and EOM
1566 * can be combined with the NONE error (as well as others). So
1567 * drop thru to catch this...
1568 */
1569#endif
1570 case EVE_NONE:
1571 if (err == ERR_SHT)
1572 {
1573 ch->s.rx_length_errors++;
1574 }
1575 break;
1576 default:
1577 if (log_level >= LOG_WARN)
1578 printk ("%s: unexpected interrupt event: %d, iqd[%d]: %08x, port: %d\n", ci->devname,
1579 event, headx, currInt, group);
1580 break;
1581 } /* switch on event */
1582
1583
1584 /*
1585 * Per MUSYCC Manual, Section 6.4.8.3 [Transmit Errors], TX errors
1586 * are service-affecting and require action to resume normal
1587 * bit-level processing.
1588 */
1589
1590 switch (err)
1591 {
1592 case ERR_ONR:
1593 /*
1594 * Per MUSYCC manual, Section 6.4.8.3 [Transmit Errors], this
1595 * error requires Transmit channel reactivation.
1596 *
1597 * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors], this error
1598 * requires Receive channel reactivation.
1599 */
1600 if (tx)
1601 {
1602
1603 /*
1604 * TX ONR Error only occurs when channel is configured for
1605 * Transparent Mode. However, this code will catch and
1606 * re-activate on ANY TX ONR error.
1607 */
1608
1609 /*
1610 * Set flag to re-enable on any next transmit attempt.
1611 */
1612 ch->ch_start_tx = CH_START_TX_ONR;
1613
1614 {
1615#ifdef RLD_TRANS_DEBUG
1616 if (1 || log_level >= LOG_MONITOR)
1617#else
1618 if (log_level >= LOG_MONITOR)
1619#endif
1620 {
1621 printk ("%s: TX buffer underflow [ONR] on channel %d, mode %x QStopped %x free %d\n",
1622 ci->devname, ch->channum, ch->p.chan_mode, sd_queue_stopped (ch->user), ch->txd_free);
1623#ifdef RLD_DEBUG
1624 if (ch->p.chan_mode == 2) /* problem = ONR on HDLC
1625 * mode */
1626 {
1627 printk ("++ Failed Last %x Next %x QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n",
1628 (u_int32_t) ch->txd_irq_srv, (u_int32_t) ch->txd_usr_add,
1629 sd_queue_stopped (ch->user),
1630 ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode);
1631 musycc_dump_txbuffer_ring (ch, 0);
1632 }
1633#endif
1634 }
1635 }
1636 } else /* RX buffer overrun */
1637 {
1638 /*
1639 * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors],
1640 * channel recovery for this RX ONR error IS required. It is
1641 * also suggested to increase the number of receive buffers
1642 * for this channel. Receive channel reactivation IS
1643 * required, and data has been lost.
1644 */
1645 ch->s.rx_over_errors++;
1646 ch->ch_start_rx = CH_START_RX_ONR;
1647
1648 if (log_level >= LOG_WARN)
1649 {
1650 printk ("%s: RX buffer overflow [ONR] on channel %d, mode %x\n",
1651 ci->devname, ch->channum, ch->p.chan_mode);
1652 //musycc_dump_rxbuffer_ring (ch, 0); /* RLD DEBUG */
1653 }
1654 }
1655 musycc_chan_restart (ch);
1656 break;
1657 case ERR_BUF:
1658 if (tx)
1659 {
1660 ch->s.tx_fifo_errors++;
1661 ch->ch_start_tx = CH_START_TX_BUF;
1662 /*
1663 * Per MUSYCC manual, Section 6.4.8.3 [Transmit Errors],
1664 * this BUFF error requires Transmit channel reactivation.
1665 */
1666 if (log_level >= LOG_MONITOR)
1667 printk ("%s: TX buffer underrun [BUFF] on channel %d, mode %x\n",
1668 ci->devname, ch->channum, ch->p.chan_mode);
1669 } else /* RX buffer overrun */
1670 {
1671 ch->s.rx_over_errors++;
1672 /*
1673 * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors], HDLC
1674 * mode requires NO recovery for this RX BUFF error is
1675 * required. It is suggested to increase the FIFO buffer
1676 * space for this channel. Receive channel reactivation is
1677 * not required, but data has been lost.
1678 */
1679 if (log_level >= LOG_WARN)
1680 printk ("%s: RX buffer overrun [BUFF] on channel %d, mode %x\n",
1681 ci->devname, ch->channum, ch->p.chan_mode);
1682 /*
1683 * Per MUSYCC manual, Section 6.4.9.4 [Receive Errors],
1684 * Transparent mode DOES require recovery for the RX BUFF
1685 * error. It is suggested to increase the FIFO buffer space
1686 * for this channel. Receive channel reactivation IS
1687 * required and data has been lost.
1688 */
1689 if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
1690 ch->ch_start_rx = CH_START_RX_BUF;
1691 }
1692
1693 if (tx || (ch->p.chan_mode == CFG_CH_PROTO_TRANS))
1694 musycc_chan_restart (ch);
1695 break;
1696 default:
1697 break;
1698 } /* switch on err */
1699
1700 /* Check for interrupt lost condition */
1701 if ((currInt & INTRPT_ILOST_M) && (log_level >= LOG_ERROR))
1702 {
1703 printk ("%s: Interrupt queue overflow - ILOST asserted\n",
1704 ci->devname);
1705 }
1706 ci->iqp_headx = (headx + 1) & (INT_QUEUE_SIZE - 1); /* insure wrapness */
1707 FLUSH_MEM_WRITE ();
1708 FLUSH_MEM_READ ();
1709 } /* while */
1710 if ((log_level >= LOG_MONITOR2) && (ci->iqp_headx != ci->iqp_tailx))
1711 {
1712 int bh;
1713
1714 bh = atomic_read (&CI->bh_pending);
1715 printk ("_bh_: late arrivals, head %d != tail %d, pending %d\n",
1716 ci->iqp_headx, ci->iqp_tailx, bh);
1717 }
1718#if defined(SBE_ISR_IMMEDIATE)
1719 return 0L;
1720#endif
1721 /* else, nothing returned */
1722}
1723
1724#if 0
1725int __init
1726musycc_new_chan (ci_t * ci, int channum, void *user)
1727{
1728 mch_t *ch;
1729
1730 ch = ci->port[channum / MUSYCC_NCHANS].chan[channum % MUSYCC_NCHANS];
1731
1732 if (ch->state != UNASSIGNED)
1733 return EEXIST;
1734 /* NOTE: mch_t already cleared during OS_kmalloc() */
1735 ch->state = DOWN;
1736 ch->user = user;
1737#if 0
1738 ch->status = 0;
1739 ch->p.status = 0;
1740 ch->p.intr_mask = 0;
1741#endif
1742 ch->p.chan_mode = CFG_CH_PROTO_HDLC_FCS16;
1743 ch->p.idlecode = CFG_CH_FLAG_7E;
1744 ch->p.pad_fill_count = 2;
1745 spin_lock_init (&ch->ch_rxlock);
1746 spin_lock_init (&ch->ch_txlock);
1747
1748 return 0;
1749}
1750#endif
1751
1752
1753#ifdef SBE_PMCC4_ENABLE
1754status_t
1755musycc_chan_down (ci_t * dummy, int channum)
1756{
1757 mpi_t *pi;
1758 mch_t *ch;
1759 int i, gchan;
1760
1761 if (!(ch = sd_find_chan (dummy, channum)))
1762 return EINVAL;
1763 pi = ch->up;
1764 gchan = ch->gchan;
1765
1766 /* Deactivate the channel */
1767 musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_RX_DIRECTION | gchan);
1768 ch->ch_start_rx = 0;
1769 musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_TX_DIRECTION | gchan);
1770 ch->ch_start_tx = 0;
1771
1772 if (ch->state == DOWN)
1773 return 0;
1774 ch->state = DOWN;
1775
1776 pi->regram->thp[gchan] = 0;
1777 pi->regram->tmp[gchan] = 0;
1778 pi->regram->rhp[gchan] = 0;
1779 pi->regram->rmp[gchan] = 0;
1780 FLUSH_MEM_WRITE ();
1781 for (i = 0; i < ch->txd_num; i++)
1782 {
1783 if (ch->mdt[i].mem_token != 0)
1784 OS_mem_token_free (ch->mdt[i].mem_token);
1785 }
1786
1787 for (i = 0; i < ch->rxd_num; i++)
1788 {
1789 if (ch->mdr[i].mem_token != 0)
1790 OS_mem_token_free (ch->mdr[i].mem_token);
1791 }
1792
1793 OS_kfree (ch->mdr);
1794 ch->mdr = 0;
1795 ch->rxd_num = 0;
1796 OS_kfree (ch->mdt);
1797 ch->mdt = 0;
1798 ch->txd_num = 0;
1799
1800 musycc_update_timeslots (pi);
1801 c4_fifo_free (pi, ch->gchan);
1802
1803 pi->openchans--;
1804 return 0;
1805}
1806#endif
1807
1808
1809int
1810musycc_del_chan (ci_t * ci, int channum)
1811{
1812 mch_t *ch;
1813
1814 if ((channum < 0) || (channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS))) /* sanity chk param */
1815 return ECHRNG;
1816 if (!(ch = sd_find_chan (ci, channum)))
1817 return ENOENT;
1818 if (ch->state == UP)
1819 musycc_chan_down (ci, channum);
1820 ch->state = UNASSIGNED;
1821 return 0;
1822}
1823
1824
1825int
1826musycc_del_chan_stats (ci_t * ci, int channum)
1827{
1828 mch_t *ch;
1829
1830 if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS)) /* sanity chk param */
1831 return ECHRNG;
1832 if (!(ch = sd_find_chan (ci, channum)))
1833 return ENOENT;
1834
1835 memset (&ch->s, 0, sizeof (struct sbecom_chan_stats));
1836 return 0;
1837}
1838
1839
1840int
1841musycc_start_xmit (ci_t * ci, int channum, void *mem_token)
1842{
1843 mch_t *ch;
1844 struct mdesc *md;
1845 void *m2;
1846#if 0
1847 unsigned long flags;
1848#endif
1849 int txd_need_cnt;
1850 u_int32_t len;
1851
1852 if (!(ch = sd_find_chan (ci, channum)))
1853 return ENOENT;
1854
1855 if (ci->state != C_RUNNING) /* full interrupt processing available */
1856 return EINVAL;
1857 if (ch->state != UP)
1858 return EINVAL;
1859
1860 if (!(ch->status & TX_ENABLED))
1861 return EROFS; /* how else to flag unwritable state ? */
1862
1863#ifdef RLD_TRANS_DEBUGx
1864 if (1 || log_level >= LOG_MONITOR2)
1865#else
1866 if (log_level >= LOG_MONITOR2)
1867#endif
1868 {
1869 printk ("++ start_xmt[%d]: state %x start %x full %d free %d required %d stopped %x\n",
1870 channum, ch->state, ch->ch_start_tx, ch->tx_full,
1871 ch->txd_free, ch->txd_required, sd_queue_stopped (ch->user));
1872 }
1873 /***********************************************/
1874 /** Determine total amount of data to be sent **/
1875 /***********************************************/
1876 m2 = mem_token;
1877 txd_need_cnt = 0;
1878 for (len = OS_mem_token_tlen (m2); len > 0;
1879 m2 = (void *) OS_mem_token_next (m2))
1880 {
1881 if (!OS_mem_token_len (m2))
1882 continue;
1883 txd_need_cnt++;
1884 len -= OS_mem_token_len (m2);
1885 }
1886
1887 if (txd_need_cnt == 0)
1888 {
1889 if (log_level >= LOG_MONITOR2)
1890 printk ("%s channel %d: no TX data in User buffer\n", ci->devname, channum);
1891 OS_mem_token_free (mem_token);
1892 return 0; /* no data to send */
1893 }
1894 /*************************************************/
1895 /** Are there sufficient descriptors available? **/
1896 /*************************************************/
1897 if (txd_need_cnt > ch->txd_num) /* never enough descriptors for this
1898 * large a buffer */
1899 {
1900 if (log_level >= LOG_DEBUG)
1901 {
1902 printk ("start_xmit: discarding buffer, insufficient descriptor cnt %d, need %d.\n",
1903 ch->txd_num, txd_need_cnt + 1);
1904 }
1905 ch->s.tx_dropped++;
1906 OS_mem_token_free (mem_token);
1907 return 0;
1908 }
1909#if 0
1910 spin_lock_irqsave (&ch->ch_txlock, flags);
1911#endif
1912 /************************************************************/
1913 /** flow control the line if not enough descriptors remain **/
1914 /************************************************************/
1915 if (txd_need_cnt > ch->txd_free)
1916 {
1917 if (log_level >= LOG_MONITOR2)
1918 {
1919 printk ("start_xmit[%d]: EBUSY - need more descriptors, have %d of %d need %d\n",
1920 channum, ch->txd_free, ch->txd_num, txd_need_cnt);
1921 }
1922 ch->tx_full = 1;
1923 ch->txd_required = txd_need_cnt;
1924 sd_disable_xmit (ch->user);
1925#if 0
1926 spin_unlock_irqrestore (&ch->ch_txlock, flags);
1927#endif
1928 return EBUSY; /* tell user to try again later */
1929 }
1930 /**************************************************/
1931 /** Put the user data into MUSYCC data buffer(s) **/
1932 /**************************************************/
1933 m2 = mem_token;
1934 md = ch->txd_usr_add; /* get current available descriptor */
1935
1936 for (len = OS_mem_token_tlen (m2); len > 0; m2 = OS_mem_token_next (m2))
1937 {
1938 int u = OS_mem_token_len (m2);
1939
1940 if (!u)
1941 continue;
1942 len -= u;
1943
1944 /*
1945 * Enable following chunks, yet wait to enable the FIRST chunk until
1946 * after ALL subsequent chunks are setup.
1947 */
1948 if (md != ch->txd_usr_add) /* not first chunk */
1949 u |= MUSYCC_TX_OWNED; /* transfer ownership from HOST to MUSYCC */
1950
1951 if (len) /* not last chunk */
1952 u |= EOBIRQ_ENABLE;
1953 else if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
1954 {
1955 /*
1956 * Per MUSYCC Ref 6.4.9 for Transparent Mode, the host must
1957 * always clear EOMIRQ_ENABLE in every Transmit Buffer Descriptor
1958 * (IE. don't set herein).
1959 */
1960 u |= EOBIRQ_ENABLE;
1961 } else
1962 u |= EOMIRQ_ENABLE; /* EOM, last HDLC chunk */
1963
1964
1965 /* last chunk in hdlc mode */
1966 u |= (ch->p.idlecode << IDLE_CODE);
1967 if (ch->p.pad_fill_count)
1968 {
1969#if 0
1970 /* NOOP NOTE: u_int8_t cannot be > 0xFF */
1971 /* sanitize pad_fill_count for maximums allowed by hardware */
1972 if (ch->p.pad_fill_count > EXTRA_FLAGS_MASK)
1973 ch->p.pad_fill_count = EXTRA_FLAGS_MASK;
1974#endif
1975 u |= (PADFILL_ENABLE | (ch->p.pad_fill_count << EXTRA_FLAGS));
1976 }
1977 md->mem_token = len ? 0 : mem_token; /* Fill in mds on last
1978 * segment, others set ZERO
1979 * so that entire token is
1980 * removed ONLY when ALL
1981 * segments have been
1982 * transmitted. */
1983
1984 md->data = cpu_to_le32 (OS_vtophys (OS_mem_token_data (m2)));
1985 FLUSH_MEM_WRITE ();
1986 md->status = cpu_to_le32 (u);
1987 --ch->txd_free;
1988 md = md->snext;
1989 }
1990 FLUSH_MEM_WRITE ();
1991
1992
1993 /*
1994 * Now transfer ownership of first chunk from HOST to MUSYCC in order to
1995 * fire-off this XMIT.
1996 */
1997 ch->txd_usr_add->status |= __constant_cpu_to_le32 (MUSYCC_TX_OWNED);
1998 FLUSH_MEM_WRITE ();
1999 ch->txd_usr_add = md;
2000
2001 len = OS_mem_token_tlen (mem_token);
2002 atomic_add (len, &ch->tx_pending);
2003 atomic_add (len, &ci->tx_pending);
2004 ch->s.tx_packets++;
2005 ch->s.tx_bytes += len;
2006#if 0
2007 spin_unlock_irqrestore (&ch->ch_txlock, flags); /* allow pending
2008 * interrupt to sneak
2009 * thru */
2010#endif
2011
2012 /*
2013 * If an ONR was seen, then channel requires poking to restart
2014 * transmission.
2015 */
2016 if (ch->ch_start_tx)
2017 {
2018#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,41)
2019 SD_SEM_TAKE (&ci->sem_wdbusy, "_wd_"); /* only 1 thru here, per
2020 * board */
2021 if ((ch->ch_start_tx == CH_START_TX_ONR) && (ch->p.chan_mode == CFG_CH_PROTO_TRANS))
2022 {
2023 /* ONR restart transmission from background loop */
2024 ci->wd_notify = WD_NOTIFY_ONR; /* enabled global watchdog
2025 * scan-thru */
2026 } else
2027 {
2028 /* start first transmission from background loop */
2029 ci->wd_notify = WD_NOTIFY_1TX; /* enabled global watchdog
2030 * scan-thru */
2031 }
2032 musycc_chan_restart (ch);
2033 SD_SEM_GIVE (&ci->sem_wdbusy);
2034#else
2035 musycc_chan_restart (ch);
2036#endif
2037 }
2038#ifdef SBE_WAN256T3_ENABLE
2039 wan256t3_led (ci, LED_TX, LEDV_G);
2040#endif
2041 return 0;
2042}
2043
2044
2045#if 0
2046int
2047musycc_set_chan (ci_t * ci, int channum, struct sbecom_chan_param * p)
2048{
2049 mch_t *ch;
2050 int rok = 0;
2051 int n = 0;
2052
2053 if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS)) /* sanity chk param */
2054 return ECHRNG;
2055 if (!(ch = sd_find_chan (ci, channum)))
2056 return ENOENT;
2057 if (ch->channum != p->channum)
2058 return EINVAL;
2059 if (sd_line_is_ok (ch->user))
2060 {
2061 rok = 1;
2062 sd_line_is_down (ch->user);
2063 }
2064 if (ch->state == UP && /* bring down in current configuration */
2065 (ch->p.status != p->status ||
2066 ch->p.chan_mode != p->chan_mode ||
2067 ch->p.intr_mask != p->intr_mask ||
2068 ch->txd_free < ch->txd_num))
2069 {
2070 if ((n = musycc_chan_down (ci, channum)))
2071 return n;
2072 if (ch->p.mode_56k != p->mode_56k)
2073 {
2074 ch->p = *p; /* copy in new parameters */
2075 musycc_update_timeslots (&ci->port[ch->channum / MUSYCC_NCHANS]);
2076 } else
2077 ch->p = *p; /* copy in new parameters */
2078 if ((n = musycc_chan_up (ci, channum)))
2079 return n;
2080 sd_enable_xmit (ch->user); /* re-enable to catch flow controlled
2081 * channel */
2082 } else
2083 {
2084 if (ch->p.mode_56k != p->mode_56k)
2085 {
2086 ch->p = *p; /* copy in new parameters */
2087 musycc_update_timeslots (&ci->port[ch->channum / MUSYCC_NCHANS]);
2088 } else
2089 ch->p = *p; /* copy in new parameters */
2090 }
2091
2092 if (rok)
2093 sd_line_is_up (ch->user);
2094 return 0;
2095}
2096#endif
2097
2098
2099int
2100musycc_get_chan (ci_t * ci, int channum, struct sbecom_chan_param * p)
2101{
2102 mch_t *ch;
2103
2104#if 0
2105 if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS)) /* sanity chk param */
2106 return ECHRNG;
2107#endif
2108 if (!(ch = sd_find_chan (ci, channum)))
2109 return ENOENT;
2110 *p = ch->p;
2111 return 0;
2112}
2113
2114
2115int
2116musycc_get_chan_stats (ci_t * ci, int channum, struct sbecom_chan_stats * p)
2117{
2118 mch_t *ch;
2119
2120 if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS)) /* sanity chk param */
2121 return ECHRNG;
2122 if (!(ch = sd_find_chan (ci, channum)))
2123 return ENOENT;
2124 *p = ch->s;
2125 p->tx_pending = atomic_read (&ch->tx_pending);
2126 return 0;
2127}
2128
2129
2130
2131#ifdef SBE_WAN256T3_ENABLE
2132int
2133musycc_chan_down (ci_t * ci, int channum)
2134{
2135 mch_t *ch;
2136 mpi_t *pi;
2137 int i, gchan;
2138
2139 if (!(ch = sd_find_chan (ci, channum)))
2140 return EINVAL;
2141 pi = ch->up;
2142 gchan = ch->gchan;
2143
2144 /* Deactivate the channel */
2145 musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_RX_DIRECTION | gchan);
2146 ch->ch_start_rx = 0;
2147 musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_TX_DIRECTION | gchan);
2148 ch->ch_start_tx = 0;
2149
2150 if (ch->state == DOWN)
2151 return 0;
2152 ch->state = DOWN;
2153
2154 pi->regram->thp[gchan] = 0;
2155 pi->regram->tmp[gchan] = 0;
2156 pi->regram->rhp[gchan] = 0;
2157 pi->regram->rmp[gchan] = 0;
2158 FLUSH_MEM_WRITE ();
2159 for (i = 0; i < ch->txd_num; i++)
2160 {
2161 if (ch->mdt[i].mem_token != 0)
2162 OS_mem_token_free (ch->mdt[i].mem_token);
2163 }
2164
2165 for (i = 0; i < ch->rxd_num; i++)
2166 {
2167 if (ch->mdr[i].mem_token != 0)
2168 OS_mem_token_free (ch->mdr[i].mem_token);
2169 }
2170
2171 OS_kfree (ch->mdt);
2172 ch->mdt = 0;
2173 OS_kfree (ch->mdr);
2174 ch->mdr = 0;
2175
2176 return 0;
2177}
2178#endif
2179
2180/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/musycc.h b/drivers/staging/cxt1e1/musycc.h
new file mode 100644
index 00000000000..d2c91ef686d
--- /dev/null
+++ b/drivers/staging/cxt1e1/musycc.h
@@ -0,0 +1,460 @@
1/*
2 * $Id: musycc.h,v 1.3 2005/09/28 00:10:08 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_MUSYCC_H_
6#define _INC_MUSYCC_H_
7
8/*-----------------------------------------------------------------------------
9 * musycc.h - Multichannel Synchronous Communications Controller
10 * CN8778/8474A/8472A/8471A
11 *
12 * Copyright (C) 2002-2005 SBE, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * For further information, contact via email: support@sbei.com
25 * SBE, Inc. San Ramon, California U.S.A.
26 *-----------------------------------------------------------------------------
27 * RCS info:
28 * RCS revision: $Revision: 1.3 $
29 * Last changed on $Date: 2005/09/28 00:10:08 $
30 * Changed by $Author: rickd $
31 *-----------------------------------------------------------------------------
32 * $Log: musycc.h,v $
33 * Revision 1.3 2005/09/28 00:10:08 rickd
34 * Add GNU license info. Add PMCC4 PCI/DevIDs. Implement new
35 * musycc reg&bits namings. Use PORTMAP_0 GCD grouping.
36 *
37 * Revision 1.2 2005/04/28 23:43:04 rickd
38 * Add RCS tracking heading.
39 *
40 *-----------------------------------------------------------------------------
41 */
42
43#if defined (__FreeBSD__) || defined (__NetBSD__)
44#include <sys/types.h>
45#else
46#include <linux/types.h>
47#endif
48
49#define VINT8 volatile u_int8_t
50#define VINT32 volatile u_int32_t
51
52#ifdef __cplusplus
53extern "C"
54{
55#endif
56
57#include "pmcc4_defs.h"
58
59
60/*------------------------------------------------------------------------
61// Vendor, Board Identification definitions
62//------------------------------------------------------------------------
63*/
64
65#define PCI_VENDOR_ID_CONEXANT 0x14f1
66#define PCI_DEVICE_ID_CN8471 0x8471
67#define PCI_DEVICE_ID_CN8472 0x8472
68#define PCI_DEVICE_ID_CN8474 0x8474
69#define PCI_DEVICE_ID_CN8478 0x8478
70#define PCI_DEVICE_ID_CN8500 0x8500
71#define PCI_DEVICE_ID_CN8501 0x8501
72#define PCI_DEVICE_ID_CN8502 0x8502
73#define PCI_DEVICE_ID_CN8503 0x8503
74
75#define INT_QUEUE_SIZE MUSYCC_NIQD
76
77/* RAM image of MUSYCC registers layed out as a C structure */
78 struct musycc_groupr
79 {
80 VINT32 thp[32]; /* Transmit Head Pointer [5-29] */
81 VINT32 tmp[32]; /* Transmit Message Pointer [5-30] */
82 VINT32 rhp[32]; /* Receive Head Pointer [5-29] */
83 VINT32 rmp[32]; /* Receive Message Pointer [5-30] */
84 VINT8 ttsm[128]; /* Time Slot Map [5-22] */
85 VINT8 tscm[256]; /* Subchannel Map [5-24] */
86 VINT32 tcct[32]; /* Channel Configuration [5-26] */
87 VINT8 rtsm[128]; /* Time Slot Map [5-22] */
88 VINT8 rscm[256]; /* Subchannel Map [5-24] */
89 VINT32 rcct[32]; /* Channel Configuration [5-26] */
90 VINT32 __glcd; /* Global Configuration Descriptor [5-10] */
91 VINT32 __iqp; /* Interrupt Queue Pointer [5-36] */
92 VINT32 __iql; /* Interrupt Queue Length [5-36] */
93 VINT32 grcd; /* Group Configuration Descriptor [5-16] */
94 VINT32 mpd; /* Memory Protection Descriptor [5-18] */
95 VINT32 mld; /* Message Length Descriptor [5-20] */
96 VINT32 pcd; /* Port Configuration Descriptor [5-19] */
97 };
98
99/* hardware MUSYCC registers layed out as a C structure */
100 struct musycc_globalr
101 {
102 VINT32 gbp; /* Group Base Pointer */
103 VINT32 dacbp; /* Dual Address Cycle Base Pointer */
104 VINT32 srd; /* Service Request Descriptor */
105 VINT32 isd; /* Interrupt Service Descriptor */
106 /*
107 * adjust __thp due to above 4 registers, which are not contained
108 * within musycc_groupr[]. All __XXX[] are just place holders,
109 * anyhow.
110 */
111 VINT32 __thp[32 - 4]; /* Transmit Head Pointer [5-29] */
112 VINT32 __tmp[32]; /* Transmit Message Pointer [5-30] */
113 VINT32 __rhp[32]; /* Receive Head Pointer [5-29] */
114 VINT32 __rmp[32]; /* Receive Message Pointer [5-30] */
115 VINT8 ttsm[128]; /* Time Slot Map [5-22] */
116 VINT8 tscm[256]; /* Subchannel Map [5-24] */
117 VINT32 tcct[32]; /* Channel Configuration [5-26] */
118 VINT8 rtsm[128]; /* Time Slot Map [5-22] */
119 VINT8 rscm[256]; /* Subchannel Map [5-24] */
120 VINT32 rcct[32]; /* Channel Configuration [5-26] */
121 VINT32 glcd; /* Global Configuration Descriptor [5-10] */
122 VINT32 iqp; /* Interrupt Queue Pointer [5-36] */
123 VINT32 iql; /* Interrupt Queue Length [5-36] */
124 VINT32 grcd; /* Group Configuration Descriptor [5-16] */
125 VINT32 mpd; /* Memory Protection Descriptor [5-18] */
126 VINT32 mld; /* Message Length Descriptor [5-20] */
127 VINT32 pcd; /* Port Configuration Descriptor [5-19] */
128 VINT32 rbist; /* Receive BIST status [5-4] */
129 VINT32 tbist; /* Receive BIST status [5-4] */
130 };
131
132/* Global Config Descriptor bit macros */
133#define MUSYCC_GCD_ECLK_ENABLE 0x00000800 /* EBUS clock enable */
134#define MUSYCC_GCD_INTEL_SELECT 0x00000400 /* MPU type select */
135#define MUSYCC_GCD_INTA_DISABLE 0x00000008 /* PCI INTA disable */
136#define MUSYCC_GCD_INTB_DISABLE 0x00000004 /* PCI INTB disable */
137#define MUSYCC_GCD_BLAPSE 12 /* Position index for BLAPSE bit
138 * field */
139#define MUSYCC_GCD_ALAPSE 8 /* Position index for ALAPSE bit
140 * field */
141#define MUSYCC_GCD_ELAPSE 4 /* Position index for ELAPSE bit
142 * field */
143#define MUSYCC_GCD_PORTMAP_3 3 /* Reserved */
144#define MUSYCC_GCD_PORTMAP_2 2 /* Port 0=>Grp 0,1,2,3; Port 1=>Grp
145 * 4,5,6,7 */
146#define MUSYCC_GCD_PORTMAP_1 1 /* Port 0=>Grp 0,1; Port 1=>Grp 2,3,
147 * etc... */
148#define MUSYCC_GCD_PORTMAP_0 0 /* Port 0=>Grp 0; Port 1=>Grp 2,
149 * etc... */
150
151/* and board specific assignments... */
152#ifdef SBE_WAN256T3_ENABLE
153#define BLAPSE_VAL 0
154#define ALAPSE_VAL 0
155#define ELAPSE_VAL 7
156#define PORTMAP_VAL MUSYCC_GCD_PORTMAP_2
157#endif
158
159#ifdef SBE_PMCC4_ENABLE
160#define BLAPSE_VAL 7
161#define ALAPSE_VAL 3
162#define ELAPSE_VAL 7
163#define PORTMAP_VAL MUSYCC_GCD_PORTMAP_0
164#endif
165
166#define GCD_MAGIC (((BLAPSE_VAL)<<(MUSYCC_GCD_BLAPSE)) | \
167 ((ALAPSE_VAL)<<(MUSYCC_GCD_ALAPSE)) | \
168 ((ELAPSE_VAL)<<(MUSYCC_GCD_ELAPSE)) | \
169 (MUSYCC_GCD_ECLK_ENABLE) | PORTMAP_VAL)
170
171/* Group Config Descriptor bit macros */
172#define MUSYCC_GRCD_RX_ENABLE 0x00000001 /* Enable receive processing */
173#define MUSYCC_GRCD_TX_ENABLE 0x00000002 /* Enable transmit processing */
174#define MUSYCC_GRCD_SUBCHAN_DISABLE 0x00000004 /* Master disable for
175 * subchanneling */
176#define MUSYCC_GRCD_OOFMP_DISABLE 0x00000008 /* Out of Frame message
177 * processing disabled all
178 * channels */
179#define MUSYCC_GRCD_OOFIRQ_DISABLE 0x00000010 /* Out of Frame/In Frame irqs
180 * disabled */
181#define MUSYCC_GRCD_COFAIRQ_DISABLE 0x00000020 /* Change of Frame Alignment
182 * irq disabled */
183#define MUSYCC_GRCD_INHRBSD 0x00000100 /* Receive Buffer Status
184 * overwrite disabled */
185#define MUSYCC_GRCD_INHTBSD 0x00000200 /* Transmit Buffer Status
186 * overwrite disabled */
187#define MUSYCC_GRCD_SF_ALIGN 0x00008000 /* External frame sync */
188#define MUSYCC_GRCD_MC_ENABLE 0x00000040 /* Message configuration bits
189 * copy enable. Conexant sez
190 * turn this on */
191#define MUSYCC_GRCD_POLLTH_16 0x00000001 /* Poll every 16th frame */
192#define MUSYCC_GRCD_POLLTH_32 0x00000002 /* Poll every 32nd frame */
193#define MUSYCC_GRCD_POLLTH_64 0x00000003 /* Poll every 64th frame */
194#define MUSYCC_GRCD_POLLTH_SHIFT 10 /* Position index for poll throttle
195 * bit field */
196#define MUSYCC_GRCD_SUERM_THRESH_SHIFT 16 /* Position index for SUERM
197 * count threshold */
198
199/* Port Config Descriptor bit macros */
200#define MUSYCC_PCD_E1X2_MODE 2 /* Port mode in bits 0-2. T1 and E1 */
201#define MUSYCC_PCD_E1X4_MODE 3 /* are defined in cn847x.h */
202#define MUSYCC_PCD_NX64_MODE 4
203#define MUSYCC_PCD_TXDATA_RISING 0x00000010 /* Sample Tx data on TCLK
204 * rising edge */
205#define MUSYCC_PCD_TXSYNC_RISING 0x00000020 /* Sample Tx frame sync on
206 * TCLK rising edge */
207#define MUSYCC_PCD_RXDATA_RISING 0x00000040 /* Sample Rx data on RCLK
208 * rising edge */
209#define MUSYCC_PCD_RXSYNC_RISING 0x00000080 /* Sample Rx frame sync on
210 * RCLK rising edge */
211#define MUSYCC_PCD_ROOF_RISING 0x00000100 /* Sample Rx Out Of Frame
212 * signal on RCLK rising edge */
213#define MUSYCC_PCD_TX_DRIVEN 0x00000200 /* No mapped timeslots causes
214 * logic 1 on output, else
215 * tristate */
216#define MUSYCC_PCD_PORTMODE_MASK 0xfffffff8 /* For changing the port mode
217 * between E1 and T1 */
218
219/* Time Slot Descriptor bit macros */
220#define MUSYCC_TSD_MODE_64KBPS 4
221#define MUSYCC_TSD_MODE_56KBPS 5
222#define MUSYCC_TSD_SUBCHANNEL_WO_FIRST 6
223#define MUSYCC_TSD_SUBCHANNEL_WITH_FIRST 7
224
225/* Message Descriptor bit macros */
226#define MUSYCC_MDT_BASE03_ADDR 0x00006000
227
228/* Channel Config Descriptor bit macros */
229#define MUSYCC_CCD_BUFIRQ_DISABLE 0x00000002 /* BUFF and ONR irqs disabled */
230#define MUSYCC_CCD_EOMIRQ_DISABLE 0x00000004 /* EOM irq disabled */
231#define MUSYCC_CCD_MSGIRQ_DISABLE 0x00000008 /* LNG, FCS, ALIGN, and ABT
232 * irqs disabled */
233#define MUSYCC_CCD_IDLEIRQ_DISABLE 0x00000010 /* CHABT, CHIC, and SHT irqs
234 * disabled */
235#define MUSYCC_CCD_FILTIRQ_DISABLE 0x00000020 /* SFILT irq disabled */
236#define MUSYCC_CCD_SDECIRQ_DISABLE 0x00000040 /* SDEC irq disabled */
237#define MUSYCC_CCD_SINCIRQ_DISABLE 0x00000080 /* SINC irq disabled */
238#define MUSYCC_CCD_SUERIRQ_DISABLE 0x00000100 /* SUERR irq disabled */
239#define MUSYCC_CCD_FCS_XFER 0x00000200 /* Propagate FCS along with
240 * received data */
241#define MUSYCC_CCD_PROTO_SHIFT 12 /* Position index for protocol bit
242 * field */
243#define MUSYCC_CCD_TRANS 0 /* Protocol mode in bits 12-14 */
244#define MUSYCC_CCD_SS7 1
245#define MUSYCC_CCD_HDLC_FCS16 2
246#define MUSYCC_CCD_HDLC_FCS32 3
247#define MUSYCC_CCD_EOPIRQ_DISABLE 0x00008000 /* EOP irq disabled */
248#define MUSYCC_CCD_INVERT_DATA 0x00800000 /* Invert data */
249#define MUSYCC_CCD_MAX_LENGTH 10 /* Position index for max length bit
250 * field */
251#define MUSYCC_CCD_BUFFER_LENGTH 16 /* Position index for internal data
252 * buffer length */
253#define MUSYCC_CCD_BUFFER_LOC 24 /* Position index for internal data
254 * buffer starting location */
255
256/****************************************************************************
257 * Interrupt Descriptor Information */
258
259#define INT_EMPTY_ENTRY 0xfeedface
260#define INT_EMPTY_ENTRY2 0xdeadface
261
262/****************************************************************************
263 * Interrupt Status Descriptor
264 *
265 * NOTE: One must first fetch the value of the interrupt status descriptor
266 * into a local variable, then pass that value into the read macros. This
267 * is required to avoid race conditions.
268 ***/
269
270#define INTRPTS_NEXTINT_M 0x7FFF0000
271#define INTRPTS_NEXTINT_S 16
272#define INTRPTS_NEXTINT(x) ((x & INTRPTS_NEXTINT_M) >> INTRPTS_NEXTINT_S)
273
274#define INTRPTS_INTFULL_M 0x00008000
275#define INTRPTS_INTFULL_S 15
276#define INTRPTS_INTFULL(x) ((x & INTRPTS_INTFULL_M) >> INTRPTS_INTFULL_S)
277
278#define INTRPTS_INTCNT_M 0x00007FFF
279#define INTRPTS_INTCNT_S 0
280#define INTRPTS_INTCNT(x) ((x & INTRPTS_INTCNT_M) >> INTRPTS_INTCNT_S)
281
282
283/****************************************************************************
284 * Interrupt Descriptor
285 ***/
286
287#define INTRPT_DIR_M 0x80000000
288#define INTRPT_DIR_S 31
289#define INTRPT_DIR(x) ((x & INTRPT_DIR_M) >> INTRPT_DIR_S)
290
291#define INTRPT_GRP_M 0x60000000
292#define INTRPT_GRP_MSB_M 0x00004000
293#define INTRPT_GRP_S 29
294#define INTRPT_GRP_MSB_S 12
295#define INTRPT_GRP(x) (((x & INTRPT_GRP_M) >> INTRPT_GRP_S) | \
296 ((x & INTRPT_GRP_MSB_M) >> INTRPT_GRP_MSB_S))
297
298#define INTRPT_CH_M 0x1F000000
299#define INTRPT_CH_S 24
300#define INTRPT_CH(x) ((x & INTRPT_CH_M) >> INTRPT_CH_S)
301
302#define INTRPT_EVENT_M 0x00F00000
303#define INTRPT_EVENT_S 20
304#define INTRPT_EVENT(x) ((x & INTRPT_EVENT_M) >> INTRPT_EVENT_S)
305
306#define INTRPT_ERROR_M 0x000F0000
307#define INTRPT_ERROR_S 16
308#define INTRPT_ERROR(x) ((x & INTRPT_ERROR_M) >> INTRPT_ERROR_S)
309
310#define INTRPT_ILOST_M 0x00008000
311#define INTRPT_ILOST_S 15
312#define INTRPT_ILOST(x) ((x & INTRPT_ILOST_M) >> INTRPT_ILOST_S)
313
314#define INTRPT_PERR_M 0x00004000
315#define INTRPT_PERR_S 14
316#define INTRPT_PERR(x) ((x & INTRPT_PERR_M) >> INTRPT_PERR_S)
317
318#define INTRPT_BLEN_M 0x00003FFF
319#define INTRPT_BLEN_S 0
320#define INTRPT_BLEN(x) ((x & INTRPT_BLEN_M) >> INTRPT_BLEN_S)
321
322
323/* Buffer Descriptor bit macros */
324#define OWNER_BIT 0x80000000 /* Set for MUSYCC owner on xmit, host
325 * owner on receive */
326#define HOST_TX_OWNED 0x00000000 /* Host owns descriptor */
327#define MUSYCC_TX_OWNED 0x80000000 /* MUSYCC owns descriptor */
328#define HOST_RX_OWNED 0x80000000 /* Host owns descriptor */
329#define MUSYCC_RX_OWNED 0x00000000 /* MUSYCC owns descriptor */
330
331#define POLL_DISABLED 0x40000000 /* MUSYCC not allowed to poll buffer
332 * for ownership */
333#define EOMIRQ_ENABLE 0x20000000 /* This buffer contains the end of
334 * the message */
335#define EOBIRQ_ENABLE 0x10000000 /* EOB irq enabled */
336#define PADFILL_ENABLE 0x01000000 /* Enable padfill */
337#define REPEAT_BIT 0x00008000 /* Bit on for FISU descriptor */
338#define LENGTH_MASK 0X3fff /* This part of status descriptor is
339 * length */
340#define IDLE_CODE 25 /* Position index for idle code (2
341 * bits) */
342#define EXTRA_FLAGS 16 /* Position index for minimum flags
343 * between messages (8 bits) */
344#define IDLE_CODE_MASK 0x03 /* Gets rid of garbage before the
345 * pattern is OR'd in */
346#define EXTRA_FLAGS_MASK 0xff /* Gets rid of garbage before the
347 * pattern is OR'd in */
348#define PCI_PERMUTED_OWNER_BIT 0x00000080 /* For flipping the bit on
349 * the polled mode descriptor */
350
351/* Service Request Descriptor bit macros */
352#define SREQ 8 /* Position index for service request bit
353 * field */
354#define SR_NOOP (0<<(SREQ)) /* No Operation. Generates SACK */
355#define SR_CHIP_RESET (1<<(SREQ)) /* Soft chip reset */
356#define SR_GROUP_RESET (2<<(SREQ)) /* Group reset */
357#define SR_GLOBAL_INIT (4<<(SREQ)) /* Global init: read global
358 * config deswc and interrupt
359 * queue desc */
360#define SR_GROUP_INIT (5<<(SREQ)) /* Group init: read Timeslot
361 * and Subchannel maps,
362 * Channel Config, */
363 /*
364 * Group Config, Memory Protect, Message Length, and Port Config
365 * Descriptors
366 */
367#define SR_CHANNEL_ACTIVATE (8<<(SREQ)) /* Init channel, read Head
368 * Pointer, process first
369 * Message Descriptor */
370#define SR_GCHANNEL_MASK 0x001F /* channel portion (gchan) */
371#define SR_CHANNEL_DEACTIVATE (9<<(SREQ)) /* Stop channel processing */
372#define SR_JUMP (10<<(SREQ)) /* a: Process new Message
373 * List */
374#define SR_CHANNEL_CONFIG (11<<(SREQ)) /* b: Read channel
375 * Configuration Descriptor */
376#define SR_GLOBAL_CONFIG (16<<(SREQ)) /* 10: Read Global
377 * Configuration Descriptor */
378#define SR_INTERRUPT_Q (17<<(SREQ)) /* 11: Read Interrupt Queue
379 * Descriptor */
380#define SR_GROUP_CONFIG (18<<(SREQ)) /* 12: Read Group
381 * Configuration Descriptor */
382#define SR_MEMORY_PROTECT (19<<(SREQ)) /* 13: Read Memory Protection
383 * Descriptor */
384#define SR_MESSAGE_LENGTH (20<<(SREQ)) /* 14: Read Message Length
385 * Descriptor */
386#define SR_PORT_CONFIG (21<<(SREQ)) /* 15: Read Port
387 * Configuration Descriptor */
388#define SR_TIMESLOT_MAP (24<<(SREQ)) /* 18: Read Timeslot Map */
389#define SR_SUBCHANNEL_MAP (25<<(SREQ)) /* 19: Read Subchannel Map */
390#define SR_CHAN_CONFIG_TABLE (26<<(SREQ)) /* 20: Read Channel
391 * Configuration Table for
392 * the group */
393#define SR_TX_DIRECTION 0x00000020 /* Transmit direction bit.
394 * Bit off indicates receive
395 * direction */
396#define SR_RX_DIRECTION 0x00000000
397
398/* Interrupt Descriptor bit macros */
399#define GROUP10 29 /* Position index for the 2 LS group
400 * bits */
401#define CHANNEL 24 /* Position index for channel bits */
402#define INT_IQD_TX 0x80000000
403#define INT_IQD_GRP 0x60000000
404#define INT_IQD_CHAN 0x1f000000
405#define INT_IQD_EVENT 0x00f00000
406#define INT_IQD_ERROR 0x000f0000
407#define INT_IQD_ILOST 0x00008000
408#define INT_IQD_PERR 0x00004000
409#define INT_IQD_BLEN 0x00003fff
410
411/* Interrupt Descriptor Events */
412#define EVE_EVENT 20 /* Position index for event bits */
413#define EVE_NONE 0 /* No event to report in this
414 * interrupt */
415#define EVE_SACK 1 /* Service Request acknowledge */
416#define EVE_EOB 2 /* End of Buffer */
417#define EVE_EOM 3 /* End of Message */
418#define EVE_EOP 4 /* End of Padfill */
419#define EVE_CHABT 5 /* Change to Abort Code */
420#define EVE_CHIC 6 /* Change to Idle Code */
421#define EVE_FREC 7 /* Frame Recovery */
422#define EVE_SINC 8 /* MTP2 SUERM Increment */
423#define EVE_SDEC 9 /* MTP2 SUERM Decrement */
424#define EVE_SFILT 10 /* MTP2 SUERM Filtered Message */
425/* Interrupt Descriptor Errors */
426#define ERR_ERRORS 16 /* Position index for error bits */
427#define ERR_BUF 1 /* Buffer Error */
428#define ERR_COFA 2 /* Change of Frame Alignment Error */
429#define ERR_ONR 3 /* Owner Bit Error */
430#define ERR_PROT 4 /* Memory Protection Error */
431#define ERR_OOF 8 /* Out of Frame Error */
432#define ERR_FCS 9 /* FCS Error */
433#define ERR_ALIGN 10 /* Octet Alignment Error */
434#define ERR_ABT 11 /* Abort Termination */
435#define ERR_LNG 12 /* Long Message Error */
436#define ERR_SHT 13 /* Short Message Error */
437#define ERR_SUERR 14 /* SUERM threshold exceeded */
438#define ERR_PERR 15 /* PCI Parity Error */
439/* Other Stuff */
440#define TRANSMIT_DIRECTION 0x80000000 /* Transmit direction bit. Bit off
441 * indicates receive direction */
442#define ILOST 0x00008000 /* Interrupt Lost */
443#define GROUPMSB 0x00004000 /* Group number MSB */
444#define SACK_IMAGE 0x00100000 /* Used in IRQ for semaphore test */
445#define INITIAL_STATUS 0x10000 /* IRQ status should be this after
446 * reset */
447
448/* This must be defined on an entire channel group (Port) basis */
449#define SUERM_THRESHOLD 0x1f
450
451#ifdef __cplusplus
452}
453#endif
454
455#undef VINT32
456#undef VINT8
457
458#endif /*** _INC_MUSYCC_H_ ***/
459
460/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/ossiRelease.c b/drivers/staging/cxt1e1/ossiRelease.c
new file mode 100644
index 00000000000..a56029866c2
--- /dev/null
+++ b/drivers/staging/cxt1e1/ossiRelease.c
@@ -0,0 +1,39 @@
1/*
2 * $Id: ossiRelease.c,v 1.2 2008/05/08 20:14:03 rdobbs PMCC4_3_1B $
3 */
4
5/*-----------------------------------------------------------------------------
6 * ossiRelease.c -
7 *
8 * This string will be embedded into the executable and will track the
9 * release. The embedded string may be displayed using the following:
10 *
11 * strings <filename> | grep \$Rel
12 *
13 * Copyright (C) 2002-2008 One Stop Systems, Inc.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * For further information, contact via email: support@onestopsystems.com
26 * One Stop Systems, Inc. Escondido, California U.S.A.
27 *
28 *-----------------------------------------------------------------------------
29 * RCS info:
30 * RCS revision: $Revision: 1.2 $
31 * Last changed on $Date: 2008/05/08 20:14:03 $
32 * Changed by $Author: rdobbs $
33 *-----------------------------------------------------------------------------
34 */
35
36
37char pmcc4_OSSI_release[] = "$Release: PMCC4_3_1B, Copyright (c) 2008 One Stop Systems$";
38
39/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/pmc93x6_eeprom.c b/drivers/staging/cxt1e1/pmc93x6_eeprom.c
new file mode 100644
index 00000000000..02c829b318b
--- /dev/null
+++ b/drivers/staging/cxt1e1/pmc93x6_eeprom.c
@@ -0,0 +1,559 @@
1/* pmc93x6_eeprom.c - PMC's 93LC46 EEPROM Device
2 *
3 * The 93LC46 is a low-power, serial Electrically Erasable and
4 * Programmable Read Only Memory organized as 128 8-bit bytes.
5 *
6 * Accesses to the 93LC46 are done in a bit serial stream, organized
7 * in a 3 wire format. Writes are internally timed by the device
8 * (the In data bit is pulled low until the write is complete and
9 * then is pulled high) and take about 6 milliseconds.
10 *
11 * Copyright (C) 2003-2005 SBE, Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 */
23
24#include <linux/types.h>
25#include "pmcc4_sysdep.h"
26#include "sbecom_inline_linux.h"
27#include "pmcc4.h"
28#include "sbe_promformat.h"
29
30#ifndef TRUE
31#define TRUE 1
32#define FALSE 0
33#endif
34
35#ifdef SBE_INCLUDE_SYMBOLS
36#define STATIC
37#else
38#define STATIC static
39#endif
40
41
42/*------------------------------------------------------------------------
43 * EEPROM address definitions
44 *------------------------------------------------------------------------
45 *
46 * The offset in the definitions below allows the test to skip over
47 * areas of the EEPROM that other programs (such a VxWorks) are
48 * using.
49 */
50
51#define EE_MFG (long)0 /* Index to manufacturing record */
52#define EE_FIRST 0x28 /* Index to start testing at */
53#define EE_LIMIT 128 /* Index to end testing at */
54
55
56/* Bit Ordering for Instructions
57**
58** A0, A1, A2, A3, A4, A5, A6, OP0, OP1, SB (lsb, or 1st bit out)
59**
60*/
61
62#define EPROM_EWEN 0x0019 /* Erase/Write enable (reversed) */
63#define EPROM_EWDS 0x0001 /* Erase/Write disable (reversed) */
64#define EPROM_READ 0x0003 /* Read (reversed) */
65#define EPROM_WRITE 0x0005 /* Write (reversed) */
66#define EPROM_ERASE 0x0007 /* Erase (reversed) */
67#define EPROM_ERAL 0x0009 /* Erase All (reversed) */
68#define EPROM_WRAL 0x0011 /* Write All (reversed) */
69
70#define EPROM_ADR_SZ 7 /* Number of bits in offset address */
71#define EPROM_OP_SZ 3 /* Number of bits in command */
72#define SIZE_ADDR_OP (EPROM_ADR_SZ + EPROM_OP_SZ)
73#define LC46A_MAX_OPS 10 /* Number of bits in Instruction */
74#define NUM_OF_BITS 8 /* Number of bits in data */
75
76
77/* EEPROM signal bits */
78#define EPROM_ACTIVE_OUT_BIT 0x0001 /* Out data bit */
79#define EPROM_ACTIVE_IN_BIT 0x0002 /* In data bit */
80#define ACTIVE_IN_BIT_SHIFT 0x0001 /* Shift In data bit to LSB */
81#define EPROM_ENCS 0x0004 /* Set EEPROM CS during operation */
82
83
84/*------------------------------------------------------------------------
85 * The ByteReverse table is used to reverses the 8 bits within a byte
86 *------------------------------------------------------------------------
87 */
88
89static unsigned char ByteReverse[256];
90static int ByteReverseBuilt = FALSE;
91
92
93/*------------------------------------------------------------------------
94 * mfg_template - initial serial EEPROM data structure
95 *------------------------------------------------------------------------
96 */
97
98short mfg_template[sizeof (FLD_TYPE2)] =
99{
100 PROM_FORMAT_TYPE2, /* type; */
101 0x00, 0x1A, /* length[2]; */
102 0x00, 0x00, 0x00, 0x00, /* Crc32[4]; */
103 0x11, 0x76, /* Id[2]; */
104 0x07, 0x05, /* SubId[2] E1; */
105 0x00, 0xA0, 0xD6, 0x00, 0x00, 0x00, /* Serial[6]; */
106 0x00, 0x00, 0x00, 0x00, /* CreateTime[4]; */
107 0x00, 0x00, 0x00, 0x00, /* HeatRunTime[4]; */
108 0x00, 0x00, 0x00, 0x00, /* HeatRunIterations[4]; */
109 0x00, 0x00, 0x00, 0x00, /* HeatRunErrors[4]; */
110};
111
112
113/*------------------------------------------------------------------------
114 * BuildByteReverse - build the 8-bit reverse table
115 *------------------------------------------------------------------------
116 *
117 * The 'ByteReverse' table reverses the 8 bits within a byte
118 * (the MSB becomes the LSB etc.).
119 */
120
121STATIC void
122BuildByteReverse (void)
123{
124 long half; /* Used to build by powers to 2 */
125 int i;
126
127 ByteReverse[0] = 0;
128
129 for (half = 1; half < sizeof (ByteReverse); half <<= 1)
130 for (i = 0; i < half; i++)
131 ByteReverse[half + i] = (char) (ByteReverse[i] | (0x80 / half));
132
133 ByteReverseBuilt = TRUE;
134}
135
136
137/*------------------------------------------------------------------------
138 * eeprom_delay - small delay for EEPROM timing
139 *------------------------------------------------------------------------
140 */
141
142STATIC void
143eeprom_delay (void)
144{
145 int timeout;
146
147 for (timeout = 20; timeout; --timeout)
148 {
149 OS_uwait_dummy ();
150 }
151}
152
153
154/*------------------------------------------------------------------------
155 * eeprom_put_byte - Send a byte to the EEPROM serially
156 *------------------------------------------------------------------------
157 *
158 * Given the PCI address and the data, this routine serially sends
159 * the data to the EEPROM.
160 */
161
162void
163eeprom_put_byte (long addr, long data, int count)
164{
165 u_int32_t output;
166
167 while (--count >= 0)
168 {
169 output = (data & EPROM_ACTIVE_OUT_BIT) ? 1 : 0; /* Get next data bit */
170 output |= EPROM_ENCS; /* Add Chip Select */
171 data >>= 1;
172
173 eeprom_delay ();
174 pci_write_32 ((u_int32_t *) addr, output); /* Output it */
175 }
176}
177
178
179/*------------------------------------------------------------------------
180 * eeprom_get_byte - Receive a byte from the EEPROM serially
181 *------------------------------------------------------------------------
182 *
183 * Given the PCI address, this routine serially fetches the data
184 * from the EEPROM.
185 */
186
187u_int32_t
188eeprom_get_byte (long addr)
189{
190 u_int32_t input;
191 u_int32_t data;
192 int count;
193
194/* Start the Reading of DATA
195**
196** The first read is a dummy as the data is latched in the
197** EPLD and read on the next read access to the EEPROM.
198*/
199
200 input = pci_read_32 ((u_int32_t *) addr);
201
202 data = 0;
203 count = NUM_OF_BITS;
204 while (--count >= 0)
205 {
206 eeprom_delay ();
207 input = pci_read_32 ((u_int32_t *) addr);
208
209 data <<= 1; /* Shift data over */
210 data |= (input & EPROM_ACTIVE_IN_BIT) ? 1 : 0;
211
212 }
213
214 return data;
215}
216
217
218/*------------------------------------------------------------------------
219 * disable_pmc_eeprom - Disable writes to the EEPROM
220 *------------------------------------------------------------------------
221 *
222 * Issue the EEPROM command to disable writes.
223 */
224
225STATIC void
226disable_pmc_eeprom (long addr)
227{
228 eeprom_put_byte (addr, EPROM_EWDS, SIZE_ADDR_OP);
229
230 pci_write_32 ((u_int32_t *) addr, 0); /* this removes Chip Select
231 * from EEPROM */
232}
233
234
235/*------------------------------------------------------------------------
236 * enable_pmc_eeprom - Enable writes to the EEPROM
237 *------------------------------------------------------------------------
238 *
239 * Issue the EEPROM command to enable writes.
240 */
241
242STATIC void
243enable_pmc_eeprom (long addr)
244{
245 eeprom_put_byte (addr, EPROM_EWEN, SIZE_ADDR_OP);
246
247 pci_write_32 ((u_int32_t *) addr, 0); /* this removes Chip Select
248 * from EEPROM */
249}
250
251
252/*------------------------------------------------------------------------
253 * pmc_eeprom_read - EEPROM location read
254 *------------------------------------------------------------------------
255 *
256 * Given a EEPROM PCI address and location offset, this routine returns
257 * the contents of the specified location to the calling routine.
258 */
259
260u_int32_t
261pmc_eeprom_read (long addr, long mem_offset)
262{
263 u_int32_t data; /* Data from chip */
264
265 if (!ByteReverseBuilt)
266 BuildByteReverse ();
267
268 mem_offset = ByteReverse[0x7F & mem_offset]; /* Reverse address */
269 /*
270 * NOTE: The max offset address is 128 or half the reversal table. So the
271 * LSB is always zero and counts as a built in shift of one bit. So even
272 * though we need to shift 3 bits to make room for the command, we only
273 * need to shift twice more because of the built in shift.
274 */
275 mem_offset <<= 2; /* Shift for command */
276 mem_offset |= EPROM_READ; /* Add command */
277
278 eeprom_put_byte (addr, mem_offset, SIZE_ADDR_OP); /* Output chip address */
279
280 data = eeprom_get_byte (addr); /* Read chip data */
281
282 pci_write_32 ((u_int32_t *) addr, 0); /* Remove Chip Select from
283 * EEPROM */
284
285 return (data & 0x000000FF);
286}
287
288
289/*------------------------------------------------------------------------
290 * pmc_eeprom_write - EEPROM location write
291 *------------------------------------------------------------------------
292 *
293 * Given a EEPROM PCI address, location offset and value, this
294 * routine writes the value to the specified location.
295 *
296 * Note: it is up to the caller to determine if the write
297 * operation succeeded.
298 */
299
300int
301pmc_eeprom_write (long addr, long mem_offset, u_int32_t data)
302{
303 volatile u_int32_t temp;
304 int count;
305
306 if (!ByteReverseBuilt)
307 BuildByteReverse ();
308
309 mem_offset = ByteReverse[0x7F & mem_offset]; /* Reverse address */
310 /*
311 * NOTE: The max offset address is 128 or half the reversal table. So the
312 * LSB is always zero and counts as a built in shift of one bit. So even
313 * though we need to shift 3 bits to make room for the command, we only
314 * need to shift twice more because of the built in shift.
315 */
316 mem_offset <<= 2; /* Shift for command */
317 mem_offset |= EPROM_WRITE; /* Add command */
318
319 eeprom_put_byte (addr, mem_offset, SIZE_ADDR_OP); /* Output chip address */
320
321 data = ByteReverse[0xFF & data];/* Reverse data */
322 eeprom_put_byte (addr, data, NUM_OF_BITS); /* Output chip data */
323
324 pci_write_32 ((u_int32_t *) addr, 0); /* Remove Chip Select from
325 * EEPROM */
326
327/*
328** Must see Data In at a low state before completing this transaction.
329**
330** Afterwards, the data bit will return to a high state, ~6 ms, terminating
331** the operation.
332*/
333 pci_write_32 ((u_int32_t *) addr, EPROM_ENCS); /* Re-enable Chip Select */
334 temp = pci_read_32 ((u_int32_t *) addr); /* discard first read */
335 temp = pci_read_32 ((u_int32_t *) addr);
336 if (temp & EPROM_ACTIVE_IN_BIT)
337 {
338 temp = pci_read_32 ((u_int32_t *) addr);
339 if (temp & EPROM_ACTIVE_IN_BIT)
340 {
341 pci_write_32 ((u_int32_t *) addr, 0); /* Remove Chip Select
342 * from EEPROM */
343 return (1);
344 }
345 }
346 count = 1000;
347 while (count--)
348 {
349 for (temp = 0; temp < 0x10; temp++)
350 OS_uwait_dummy ();
351
352 if (pci_read_32 ((u_int32_t *) addr) & EPROM_ACTIVE_IN_BIT)
353 break;
354 }
355
356 if (count == -1)
357 return (2);
358
359 return (0);
360}
361
362
363/*------------------------------------------------------------------------
364 * pmcGetBuffValue - read the specified value from buffer
365 *------------------------------------------------------------------------
366 */
367
368long
369pmcGetBuffValue (char *ptr, int size)
370{
371 long value = 0;
372 int index;
373
374 for (index = 0; index < size; ++index)
375 {
376 value <<= 8;
377 value |= ptr[index] & 0xFF;
378 }
379
380 return value;
381}
382
383
384/*------------------------------------------------------------------------
385 * pmcSetBuffValue - save the specified value to buffer
386 *------------------------------------------------------------------------
387 */
388
389void
390pmcSetBuffValue (char *ptr, long value, int size)
391{
392 int index = size;
393
394 while (--index >= 0)
395 {
396 ptr[index] = (char) (value & 0xFF);
397 value >>= 8;
398 }
399}
400
401
402/*------------------------------------------------------------------------
403 * pmc_eeprom_read_buffer - read EEPROM data into specified buffer
404 *------------------------------------------------------------------------
405 */
406
407void
408pmc_eeprom_read_buffer (long addr, long mem_offset, char *dest_ptr, int size)
409{
410 while (--size >= 0)
411 *dest_ptr++ = (char) pmc_eeprom_read (addr, mem_offset++);
412}
413
414
415/*------------------------------------------------------------------------
416 * pmc_eeprom_write_buffer - write EEPROM data from specified buffer
417 *------------------------------------------------------------------------
418 */
419
420void
421pmc_eeprom_write_buffer (long addr, long mem_offset, char *dest_ptr, int size)
422{
423 enable_pmc_eeprom (addr);
424
425 while (--size >= 0)
426 pmc_eeprom_write (addr, mem_offset++, *dest_ptr++);
427
428 disable_pmc_eeprom (addr);
429}
430
431
432/*------------------------------------------------------------------------
433 * pmcCalcCrc - calculate the CRC for the serial EEPROM structure
434 *------------------------------------------------------------------------
435 */
436
437u_int32_t
438pmcCalcCrc_T01 (void *bufp)
439{
440 FLD_TYPE2 *buf = bufp;
441 u_int32_t crc; /* CRC of the structure */
442
443 /* Calc CRC for type and length fields */
444 sbeCrc (
445 (u_int8_t *) &buf->type,
446 (u_int32_t) STRUCT_OFFSET (FLD_TYPE1, Crc32),
447 (u_int32_t) 0,
448 (u_int32_t *) &crc);
449
450#ifdef EEPROM_TYPE_DEBUG
451 printk ("sbeCrc: crc 1 calculated as %08x\n", crc); /* RLD DEBUG */
452#endif
453 return ~crc;
454}
455
456u_int32_t
457pmcCalcCrc_T02 (void *bufp)
458{
459 FLD_TYPE2 *buf = bufp;
460 u_int32_t crc; /* CRC of the structure */
461
462 /* Calc CRC for type and length fields */
463 sbeCrc (
464 (u_int8_t *) &buf->type,
465 (u_int32_t) STRUCT_OFFSET (FLD_TYPE2, Crc32),
466 (u_int32_t) 0,
467 (u_int32_t *) &crc);
468
469 /* Calc CRC for remaining fields */
470 sbeCrc (
471 (u_int8_t *) &buf->Id[0],
472 (u_int32_t) (sizeof (FLD_TYPE2) - STRUCT_OFFSET (FLD_TYPE2, Id)),
473 (u_int32_t) crc,
474 (u_int32_t *) &crc);
475
476#ifdef EEPROM_TYPE_DEBUG
477 printk ("sbeCrc: crc 2 calculated as %08x\n", crc); /* RLD DEBUG */
478#endif
479 return crc;
480}
481
482
483/*------------------------------------------------------------------------
484 * pmc_init_seeprom - initialize the serial EEPROM structure
485 *------------------------------------------------------------------------
486 *
487 * At the front of the serial EEPROM there is a record that contains
488 * manufacturing information. If the info does not already exist, it
489 * is created. The only field modifiable by the operator is the
490 * serial number field.
491 */
492
493void
494pmc_init_seeprom (u_int32_t addr, u_int32_t serialNum)
495{
496 PROMFORMAT buffer; /* Memory image of structure */
497 u_int32_t crc; /* CRC of structure */
498 time_t createTime;
499 int i;
500
501#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
502 createTime = CURRENT_TIME;
503#else
504 createTime = get_seconds ();
505#endif
506
507 /* use template data */
508 for (i = 0; i < sizeof (FLD_TYPE2); ++i)
509 buffer.bytes[i] = mfg_template[i];
510
511 /* Update serial number field in buffer */
512 pmcSetBuffValue (&buffer.fldType2.Serial[3], serialNum, 3);
513
514 /* Update create time field in buffer */
515 pmcSetBuffValue (&buffer.fldType2.CreateTime[0], createTime, 4);
516
517 /* Update CRC field in buffer */
518 crc = pmcCalcCrc_T02 (&buffer);
519 pmcSetBuffValue (&buffer.fldType2.Crc32[0], crc, 4);
520
521#ifdef DEBUG
522 for (i = 0; i < sizeof (FLD_TYPE2); ++i)
523 printk ("[%02X] = %02X\n", i, buffer.bytes[i] & 0xFF);
524#endif
525
526 /* Write structure to serial EEPROM */
527 pmc_eeprom_write_buffer (addr, EE_MFG, (char *) &buffer, sizeof (FLD_TYPE2));
528}
529
530
531char
532pmc_verify_cksum (void *bufp)
533{
534 FLD_TYPE1 *buf1 = bufp;
535 FLD_TYPE2 *buf2 = bufp;
536 u_int32_t crc1, crc2; /* CRC read from EEPROM */
537
538 /* Retrieve contents of CRC field */
539 crc1 = pmcGetBuffValue (&buf1->Crc32[0], sizeof (buf1->Crc32));
540#ifdef EEPROM_TYPE_DEBUG
541 printk ("EEPROM: chksum 1 reads as %08x\n", crc1); /* RLD DEBUG */
542#endif
543 if ((buf1->type == PROM_FORMAT_TYPE1) &&
544 (pmcCalcCrc_T01 ((void *) buf1) == crc1))
545 return PROM_FORMAT_TYPE1; /* checksum type 1 verified */
546
547 crc2 = pmcGetBuffValue (&buf2->Crc32[0], sizeof (buf2->Crc32));
548#ifdef EEPROM_TYPE_DEBUG
549 printk ("EEPROM: chksum 2 reads as %08x\n", crc2); /* RLD DEBUG */
550#endif
551 if ((buf2->type == PROM_FORMAT_TYPE2) &&
552 (pmcCalcCrc_T02 ((void *) buf2) == crc2))
553 return PROM_FORMAT_TYPE2; /* checksum type 2 verified */
554
555 return PROM_FORMAT_Unk; /* failed to validate */
556}
557
558
559/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/pmc93x6_eeprom.h b/drivers/staging/cxt1e1/pmc93x6_eeprom.h
new file mode 100644
index 00000000000..c3ada87efd2
--- /dev/null
+++ b/drivers/staging/cxt1e1/pmc93x6_eeprom.h
@@ -0,0 +1,60 @@
1/*
2 * $Id: pmc93x6_eeprom.h,v 1.1 2005/09/28 00:10:08 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_PMC93X6_EEPROM_H_
6#define _INC_PMC93X6_EEPROM_H_
7
8/*-----------------------------------------------------------------------------
9 * pmc93x6_eeprom.h -
10 *
11 * Copyright (C) 2002-2004 SBE, Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * For further information, contact via email: support@sbei.com
24 * SBE, Inc. San Ramon, California U.S.A.
25 *-----------------------------------------------------------------------------
26 * RCS info:
27 *-----------------------------------------------------------------------------
28 * $Log: pmc93x6_eeprom.h,v $
29 * Revision 1.1 2005/09/28 00:10:08 rickd
30 * pmc_verify_cksum return value is char.
31 *
32 * Revision 1.0 2005/05/04 17:20:51 rickd
33 * Initial revision
34 *
35 * Revision 1.0 2005/04/22 23:48:48 rickd
36 * Initial revision
37 *
38 *-----------------------------------------------------------------------------
39 */
40
41#if defined (__FreeBSD__) || defined (__NetBSD__)
42#include <sys/types.h>
43#else
44#include <linux/types.h>
45#endif
46
47#ifdef __KERNEL__
48
49#include "pmcc4_private.h"
50
51void pmc_eeprom_read_buffer (long, long, char *, int);
52void pmc_eeprom_write_buffer (long, long, char *, int);
53void pmc_init_seeprom (u_int32_t, u_int32_t);
54char pmc_verify_cksum (void *);
55
56#endif /*** __KERNEL__ ***/
57
58#endif
59
60/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/pmcc4.h b/drivers/staging/cxt1e1/pmcc4.h
new file mode 100644
index 00000000000..26c1f0ea72e
--- /dev/null
+++ b/drivers/staging/cxt1e1/pmcc4.h
@@ -0,0 +1,155 @@
1/*
2 * $Id: pmcc4.h,v 1.4 2005/11/01 19:24:48 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_PMCC4_H_
6#define _INC_PMCC4_H_
7
8/*-----------------------------------------------------------------------------
9 * pmcc4.h -
10 *
11 * Copyright (C) 2005 SBE, Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * For further information, contact via email: support@sbei.com
24 * SBE, Inc. San Ramon, California U.S.A.
25 *-----------------------------------------------------------------------------
26 * RCS info:
27 * RCS revision: $Revision: 1.4 $
28 * Last changed on $Date: 2005/11/01 19:24:48 $
29 * Changed by $Author: rickd $
30 *-----------------------------------------------------------------------------
31 * $Log: pmcc4.h,v $
32 * Revision 1.4 2005/11/01 19:24:48 rickd
33 * Remove de-implement function prototypes. Several <int> to
34 * <status_t> changes for consistant usage of same.
35 *
36 * Revision 1.3 2005/09/28 00:10:08 rickd
37 * Add GNU license info. Use config params from libsbew.h
38 *
39 * Revision 1.2 2005/04/28 23:43:03 rickd
40 * Add RCS tracking heading.
41 *
42 *-----------------------------------------------------------------------------
43 */
44
45
46#if defined(__FreeBSD__) || defined(__NetBSD__)
47#include <sys/types.h>
48#else
49#ifndef __KERNEL__
50#include <sys/types.h>
51#else
52#include <linux/types.h>
53#endif
54#endif
55
56
57
58typedef int status_t;
59
60#define SBE_DRVR_FAIL 0
61#define SBE_DRVR_SUCCESS 1
62
63#ifdef __cplusplus
64extern "C"
65{
66#endif
67
68
69/********************/
70/* PMCC4 memory Map */
71/********************/
72
73#define COMET_OFFSET(x) (0x80000+(x)*0x10000)
74#define EEPROM_OFFSET 0xC0000
75#define CPLD_OFFSET 0xD0000
76
77 struct pmcc4_timeslot_param
78 {
79 u_int8_t card; /* the card number */
80 u_int8_t port; /* the port number */
81 u_int8_t _reserved1;
82 u_int8_t _reserved2;
83
84 /*
85 * each byte in bitmask below represents one timeslot (bitmask[0] is
86 * for timeslot 0 and so on), each bit in the byte selects timeslot
87 * bits for this channel (0xff - whole timeslot, 0x7f - 56kbps mode)
88 */
89 u_int8_t bitmask[32];
90 };
91
92 struct c4_musycc_param
93 {
94 u_int8_t RWportnum;
95 u_int16_t offset;
96 u_int32_t value;
97 };
98
99/*Alarm values */
100#define sbeE1RMAI 0x100
101#define sbeYelAlm 0x04
102#define sbeRedAlm 0x02
103#define sbeAISAlm 0x01
104
105#define sbeE1errSMF 0x02
106#define sbeE1CRC 0x01
107
108#ifdef __cplusplus
109}
110#endif
111
112#ifdef __KERNEL__
113
114/*
115 * Device Driver interface, routines are for internal use only.
116 */
117
118#include "pmcc4_private.h"
119
120#if !(LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
121char *get_hdlc_name (hdlc_device *);
122
123#endif
124
125
126/*
127 * external interface
128 */
129
130void c4_cleanup (void);
131status_t c4_chan_up (ci_t *, int channum);
132status_t c4_del_chan_stats (int channum);
133status_t c4_del_chan (int channum);
134status_t c4_get_iidinfo (ci_t * ci, struct sbe_iid_info * iip);
135int c4_is_chan_up (int channum);
136
137void *getuserbychan (int channum);
138void pci_flush_write (ci_t * ci);
139void sbecom_set_loglevel (int debuglevel);
140char *sbeid_get_bdname (ci_t * ci);
141void sbeid_set_bdtype (ci_t * ci);
142void sbeid_set_hdwbid (ci_t * ci);
143u_int32_t sbeCrc (u_int8_t *, u_int32_t, u_int32_t, u_int32_t *);
144
145void VMETRO_TRACE (void *); /* put data into 8 LEDs */
146void VMETRO_TRIGGER (ci_t *, int); /* Note: int = 0(default)
147 * thru 15 */
148
149#if defined (SBE_ISR_TASKLET)
150void musycc_intr_bh_tasklet (ci_t *);
151
152#endif
153
154#endif /*** __KERNEL __ ***/
155#endif /* _INC_PMCC4_H_ */
diff --git a/drivers/staging/cxt1e1/pmcc4_cpld.h b/drivers/staging/cxt1e1/pmcc4_cpld.h
new file mode 100644
index 00000000000..6d8f0337aa3
--- /dev/null
+++ b/drivers/staging/cxt1e1/pmcc4_cpld.h
@@ -0,0 +1,124 @@
1/*
2 * $Id: pmcc4_cpld.h,v 1.0 2005/09/28 00:10:08 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_PMCC4_CPLD_H_
6#define _INC_PMCC4_CPLD_H_
7
8/*-----------------------------------------------------------------------------
9 * pmcc4_cpld.h -
10 *
11 * Copyright (C) 2005 SBE, Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * For further information, contact via email: support@sbei.com
24 * SBE, Inc. San Ramon, California U.S.A.
25 *-----------------------------------------------------------------------------
26 * RCS info:
27 * RCS revision: $Revision: 1.0 $
28 * Last changed on $Date: 2005/09/28 00:10:08 $
29 * Changed by $Author: rickd $
30 *-----------------------------------------------------------------------------
31 * $Log: pmcc4_cpld.h,v $
32 * Revision 1.0 2005/09/28 00:10:08 rickd
33 * Initial revision
34 *
35 *-----------------------------------------------------------------------------
36 */
37
38
39#if defined(__FreeBSD__) || defined(__NetBSD__)
40#include <sys/types.h>
41#else
42#ifndef __KERNEL__
43#include <sys/types.h>
44#else
45#include <linux/types.h>
46#endif
47#endif
48
49#ifdef __cplusplus
50extern "C"
51{
52#endif
53
54
55/********************************/
56/* iSPLD control chip registers */
57/********************************/
58
59#if 0
60#define CPLD_MCSR 0x0
61#define CPLD_MCLK 0x1
62#define CPLD_LEDS 0x2
63#define CPLD_INTR 0x3
64#endif
65
66 struct c4_cpld
67 {
68 volatile u_int32_t mcsr;/* r/w: Master Clock Source Register */
69 volatile u_int32_t mclk;/* r/w: Master Clock Register */
70 volatile u_int32_t leds;/* r/w: LED Register */
71 volatile u_int32_t intr;/* r: Interrupt Register */
72 };
73
74 typedef struct c4_cpld c4cpld_t;
75
76/* mcsr note: sourcing COMET must be initialized to Master Mode */
77#define PMCC4_CPLD_MCSR_IND 0 /* ports used individual BP Clk as
78 * source, no slaves */
79#define PMCC4_CPLD_MCSR_CMT_1 1 /* COMET 1 BP Clk is source, 2,3,4
80 * are Clk slaves */
81#define PMCC4_CPLD_MCSR_CMT_2 2 /* COMET 2 BP Clk is source, 1,3,4
82 * are Clk slaves */
83#define PMCC4_CPLD_MCSR_CMT_3 3 /* COMET 3 BP Clk is source, 1,2,4
84 * are Clk slaves */
85#define PMCC4_CPLD_MCSR_CMT_4 4 /* COMET 4 BP Clk is source, 1,2,3
86 * are Clk slaves */
87
88#define PMCC4_CPLD_MCLK_MASK 0x0f
89#define PMCC4_CPLD_MCLK_P1 0x1
90#define PMCC4_CPLD_MCLK_P2 0x2
91#define PMCC4_CPLD_MCLK_P3 0x4
92#define PMCC4_CPLD_MCLK_P4 0x8
93#define PMCC4_CPLD_MCLK_T1 0x00
94#define PMCC4_CPLD_MCLK_P1_E1 0x01
95#define PMCC4_CPLD_MCLK_P2_E1 0x02
96#define PMCC4_CPLD_MCLK_P3_E1 0x04
97#define PMCC4_CPLD_MCLK_P4_E1 0x08
98
99#define PMCC4_CPLD_LED_OFF 0
100#define PMCC4_CPLD_LED_ON 1
101#define PMCC4_CPLD_LED_GP0 0x01 /* port 0, green */
102#define PMCC4_CPLD_LED_YP0 0x02 /* port 0, yellow */
103#define PMCC4_CPLD_LED_GP1 0x04 /* port 1, green */
104#define PMCC4_CPLD_LED_YP1 0x08 /* port 1, yellow */
105#define PMCC4_CPLD_LED_GP2 0x10 /* port 2, green */
106#define PMCC4_CPLD_LED_YP2 0x20 /* port 2, yellow */
107#define PMCC4_CPLD_LED_GP3 0x40 /* port 3, green */
108#define PMCC4_CPLD_LED_YP3 0x80 /* port 3, yellow */
109#define PMCC4_CPLD_LED_GREEN (PMCC4_CPLD_LED_GP0 | PMCC4_CPLD_LED_GP1 | \
110 PMCC4_CPLD_LED_GP2 | PMCC4_CPLD_LED_GP3 )
111#define PMCC4_CPLD_LED_YELLOW (PMCC4_CPLD_LED_YP0 | PMCC4_CPLD_LED_YP1 | \
112 PMCC4_CPLD_LED_YP2 | PMCC4_CPLD_LED_YP3)
113
114#define PMCC4_CPLD_INTR_MASK 0x0f
115#define PMCC4_CPLD_INTR_CMT_1 0x01
116#define PMCC4_CPLD_INTR_CMT_2 0x02
117#define PMCC4_CPLD_INTR_CMT_3 0x04
118#define PMCC4_CPLD_INTR_CMT_4 0x08
119
120#ifdef __cplusplus
121}
122#endif
123
124#endif /* _INC_PMCC4_CPLD_H_ */
diff --git a/drivers/staging/cxt1e1/pmcc4_defs.h b/drivers/staging/cxt1e1/pmcc4_defs.h
new file mode 100644
index 00000000000..186347b8d56
--- /dev/null
+++ b/drivers/staging/cxt1e1/pmcc4_defs.h
@@ -0,0 +1,82 @@
1/*
2 * $Id: pmcc4_defs.h,v 1.0 2005/09/28 00:10:09 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_PMCC4_DEFS_H_
6#define _INC_PMCC4_DEFS_H_
7
8/*-----------------------------------------------------------------------------
9 * c4_defs.h -
10 *
11 * Implementation elements of the wanPMC-C4T1E1 device driver
12 *
13 * Copyright (C) 2005 SBE, Inc.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * For further information, contact via email: support@sbei.com
26 * SBE, Inc. San Ramon, California U.S.A.
27 *-----------------------------------------------------------------------------
28 * RCS info:
29 * RCS revision: $Revision: 1.0 $
30 * Last changed on $Date: 2005/09/28 00:10:09 $
31 * Changed by $Author: rickd $
32 *-----------------------------------------------------------------------------
33 * $Log: pmcc4_defs.h,v $
34 * Revision 1.0 2005/09/28 00:10:09 rickd
35 * Initial revision
36 *
37 *-----------------------------------------------------------------------------
38 */
39
40
41#define MAX_BOARDS 8
42#define MAX_CHANS_USED 128
43
44#ifdef SBE_PMCC4_ENABLE
45#define MUSYCC_NPORTS 4 /* CN8474 */
46#endif
47#ifdef SBE_WAN256T3_ENABLE
48#define MUSYCC_NPORTS 8 /* CN8478 */
49#endif
50#define MUSYCC_NCHANS 32 /* actually, chans per port */
51
52#define MUSYCC_NIQD 0x1000 /* power of 2 */
53#define MUSYCC_MRU 2048 /* default */
54#define MUSYCC_MTU 2048 /* default */
55#define MUSYCC_TXDESC_MIN 10 /* HDLC mode default */
56#define MUSYCC_RXDESC_MIN 18 /* HDLC mode default */
57#define MUSYCC_TXDESC_TRANS 4 /* Transparent mode minumum # of TX descriptors */
58#define MUSYCC_RXDESC_TRANS 12 /* Transparent mode minumum # of RX descriptors */
59
60#define MAX_DEFAULT_IFQLEN 32 /* network qlen */
61
62
63#define SBE_IFACETMPL "pmcc4-%d"
64#ifdef IFNAMSIZ
65#define SBE_IFACETMPL_SIZE IFNAMSIZ
66#else
67#define SBE_IFACETMPL_SIZE 16
68#endif
69
70/* we want the PMCC4 watchdog to fire off every 250ms */
71#define WATCHDOG_TIMEOUT 250000
72
73/* if we restart the watchdog every 250ms, then we'll time out
74 * an additional 300ms later */
75#define WATCHDOG_UTIMEOUT (WATCHDOG_TIMEOUT+300000)
76
77#if !defined(SBE_ISR_TASKLET) && !defined(SBE_ISR_IMMEDIATE) && !defined(SBE_ISR_INLINE)
78#define SBE_ISR_TASKLET
79#endif
80
81#endif /*** _INC_PMCC4_DEFS_H_ ***/
82
diff --git a/drivers/staging/cxt1e1/pmcc4_drv.c b/drivers/staging/cxt1e1/pmcc4_drv.c
new file mode 100644
index 00000000000..ada80d0b605
--- /dev/null
+++ b/drivers/staging/cxt1e1/pmcc4_drv.c
@@ -0,0 +1,1855 @@
1/*
2 * $Id: pmcc4_drv.c,v 3.1 2007/08/15 23:32:17 rickd PMCC4_3_1B $
3 */
4
5
6/*-----------------------------------------------------------------------------
7 * pmcc4_drv.c -
8 *
9 * Copyright (C) 2007 One Stop Systems, Inc.
10 * Copyright (C) 2002-2006 SBE, Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * For further information, contact via email: support@onestopsystems.com
23 * One Stop Systems, Inc. Escondido, California U.S.A.
24 *-----------------------------------------------------------------------------
25 * RCS info:
26 * RCS revision: $Revision: 3.1 $
27 * Last changed on $Date: 2007/08/15 23:32:17 $
28 * Changed by $Author: rickd $
29 *-----------------------------------------------------------------------------
30 * $Log: pmcc4_drv.c,v $
31 * Revision 3.1 2007/08/15 23:32:17 rickd
32 * Use 'if 0' instead of GNU comment delimeter to avoid line wrap induced compiler errors.
33 *
34 * Revision 3.0 2007/08/15 22:19:55 rickd
35 * Correct sizeof() castings and pi->regram to support 64bit compatibility.
36 *
37 * Revision 2.10 2006/04/21 00:56:40 rickd
38 * workqueue files now prefixed with <sbecom> prefix.
39 *
40 * Revision 2.9 2005/11/01 19:22:49 rickd
41 * Add sanity checks against max_port for ioctl functions.
42 *
43 * Revision 2.8 2005/10/27 18:59:25 rickd
44 * Code cleanup. Default channel config to HDLC_FCS16.
45 *
46 * Revision 2.7 2005/10/18 18:16:30 rickd
47 * Further NCOMM code repairs - (1) interrupt matrix usage inconsistant
48 * for indexing into nciInterrupt[][], code missing double parameters.
49 * (2) check input of ncomm interrupt registration cardID for correct
50 * boundary values.
51 *
52 * Revision 2.6 2005/10/17 23:55:28 rickd
53 * Initial port of NCOMM support patches from original work found
54 * in pmc_c4t1e1 as updated by NCOMM. Ref: CONFIG_SBE_PMCC4_NCOMM.
55 * Corrected NCOMMs wanpmcC4T1E1_getBaseAddress() to correctly handle
56 * multiple boards.
57 *
58 * Revision 2.5 2005/10/13 23:01:28 rickd
59 * Correct panic for illegal address reference w/in get_brdinfo on
60 * first_if/last_if name acquistion under Linux 2.6
61 *
62 * Revision 2.4 2005/10/13 21:20:19 rickd
63 * Correction of c4_cleanup() wherein next should be acquired before
64 * ci_t structure is free'd.
65 *
66 * Revision 2.3 2005/10/13 19:20:10 rickd
67 * Correct driver removal cleanup code for multiple boards.
68 *
69 * Revision 2.2 2005/10/11 18:34:04 rickd
70 * New routine added to determine number of ports (comets) on board.
71 *
72 * Revision 2.1 2005/10/05 00:48:13 rickd
73 * Add some RX activation trace code.
74 *
75 * Revision 2.0 2005/09/28 00:10:06 rickd
76 * Implement 2.6 workqueue for TX/RX restart. Correction to
77 * hardware register boundary checks allows expanded access of MUSYCC.
78 * Implement new musycc reg&bits namings.
79 *
80 *-----------------------------------------------------------------------------
81 */
82
83char OSSIid_pmcc4_drvc[] =
84"@(#)pmcc4_drv.c - $Revision: 3.1 $ (c) Copyright 2002-2007 One Stop Systems, Inc.";
85
86
87#if defined (__FreeBSD__) || defined (__NetBSD__)
88#include <sys/param.h>
89#include <sys/systm.h>
90#include <sys/errno.h>
91#else
92#include <linux/types.h>
93#include "pmcc4_sysdep.h"
94#include <linux/errno.h>
95#include <linux/kernel.h>
96#include <linux/sched.h> /* include for timer */
97#include <linux/timer.h> /* include for timer */
98#include <linux/hdlc.h>
99#include <asm/io.h>
100#endif
101
102#include "sbecom_inline_linux.h"
103#include "libsbew.h"
104#include "pmcc4_private.h"
105#include "pmcc4.h"
106#include "pmcc4_ioctls.h"
107#include "musycc.h"
108#include "comet.h"
109#include "sbe_bid.h"
110
111#ifdef SBE_INCLUDE_SYMBOLS
112#define STATIC
113#else
114#define STATIC static
115#endif
116
117
118#define KERN_WARN KERN_WARNING
119
120/* forward references */
121#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
122status_t c4_wk_chan_init (mpi_t *, mch_t *);
123void c4_wq_port_cleanup (mpi_t *);
124status_t c4_wq_port_init (mpi_t *);
125
126#endif
127int c4_loop_port (ci_t *, int, u_int8_t);
128status_t c4_set_port (ci_t *, int);
129status_t musycc_chan_down (ci_t *, int);
130
131u_int32_t musycc_chan_proto (int);
132status_t musycc_dump_ring (ci_t *, unsigned int);
133status_t __init musycc_init (ci_t *);
134void musycc_init_mdt (mpi_t *);
135void musycc_serv_req (mpi_t *, u_int32_t);
136void musycc_update_timeslots (mpi_t *);
137
138extern void musycc_update_tx_thp (mch_t *);
139extern int log_level;
140extern int max_mru;
141extern int max_mtu;
142extern int max_rxdesc_used, max_rxdesc_default;
143extern int max_txdesc_used, max_txdesc_default;
144
145#if defined (__powerpc__)
146extern void *memset (void *s, int c, size_t n);
147
148#endif
149
150int drvr_state = SBE_DRVR_INIT;
151ci_t *c4_list = 0;
152ci_t *CI; /* dummy pointer to board ZEROE's data -
153 * DEBUG USAGE */
154
155
156void
157sbecom_set_loglevel (int d)
158{
159 /*
160 * The code within the following -if- clause is a backdoor debug facility
161 * which can be used to display the state of a board's channel.
162 */
163 if (d > LOG_DEBUG)
164 {
165 unsigned int channum = d - (LOG_DEBUG + 1); /* convert to ZERO
166 * relativity */
167
168 (void) musycc_dump_ring ((ci_t *) CI, channum); /* CI implies support
169 * for card 0 only */
170 } else
171 {
172 if (log_level != d)
173 {
174 printk ("%s: log level changed from %d to %d\n", THIS_MODULE->name, log_level, d);
175 log_level = d; /* set new */
176 } else
177 printk ("%s: log level is %d\n", THIS_MODULE->name, log_level);
178 }
179}
180
181
182mch_t *
183c4_find_chan (int channum)
184{
185 ci_t *ci;
186 mch_t *ch;
187 int portnum, gchan;
188
189 for (ci = c4_list; ci; ci = ci->next)
190 for (portnum = 0; portnum < ci->max_port; portnum++)
191 for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++)
192 {
193 if ((ch = ci->port[portnum].chan[gchan]))
194 {
195 if ((ch->state != UNASSIGNED) &&
196 (ch->channum == channum))
197 return (ch);
198 }
199 }
200 return 0;
201}
202
203
204ci_t *__init
205c4_new (void *hi)
206{
207 ci_t *ci;
208
209#ifdef SBE_MAP_DEBUG
210 printk (KERN_WARNING "%s: c4_new() entered, ci needs %u.\n",
211 THIS_MODULE->name, (unsigned int) sizeof (ci_t));
212#endif
213
214 ci = (ci_t *) OS_kmalloc (sizeof (ci_t));
215 if (ci)
216 {
217 ci->hdw_info = hi;
218 ci->state = C_INIT; /* mark as hardware not available */
219 ci->next = c4_list;
220 c4_list = ci;
221 ci->brdno = ci->next ? ci->next->brdno + 1 : 0;
222 } else
223 printk (KERN_WARNING "%s: failed CI malloc, size %u.\n",
224 THIS_MODULE->name, (unsigned int) sizeof (ci_t));
225
226 if (CI == 0)
227 CI = ci; /* DEBUG, only board 0 usage */
228 return ci;
229}
230
231
232/***
233 * Check port state and set LED states using watchdog or ioctl...
234 * also check for in-band SF loopback commands (& cause results if they are there)
235 *
236 * Alarm function depends on comet bits indicating change in
237 * link status (linkMask) to keep the link status indication straight.
238 *
239 * Indications are only LED and system log -- except when ioctl is invoked.
240 *
241 * "alarmed" record (a.k.a. copyVal, in some cases below) decodes as:
242 *
243 * RMAI (E1 only) 0x100
244 * alarm LED on 0x80
245 * link LED on 0x40
246 * link returned 0x20 (link was down, now it's back and 'port get' hasn't run)
247 * change in LED 0x10 (update LED register because value has changed)
248 * link is down 0x08
249 * YelAlm(RAI) 0x04
250 * RedAlm 0x02
251 * AIS(blue)Alm 0x01
252 *
253 * note "link has returned" indication is reset on read
254 * (e.g. by use of the c4_control port get command)
255 */
256
257#define sbeLinkMask 0x41 /* change in signal status (lost/recovered) +
258 * state */
259#define sbeLinkChange 0x40
260#define sbeLinkDown 0x01
261#define sbeAlarmsMask 0x07 /* red / yellow / blue alarm conditions */
262#define sbeE1AlarmsMask 0x107 /* alarm conditions */
263
264#define COMET_LBCMD_READ 0x80 /* read only (do not set, return read value) */
265
266void
267checkPorts (ci_t * ci)
268{
269#ifndef CONFIG_SBE_PMCC4_NCOMM
270 /*
271 * PORT POINT - NCOMM needs to avoid this code since the polling of
272 * alarms conflicts with NCOMM's interrupt servicing implementation.
273 */
274
275 comet_t *comet;
276 volatile u_int32_t value;
277 u_int32_t copyVal, LEDval;
278
279 u_int8_t portnum;
280
281 LEDval = 0;
282 for (portnum = 0; portnum < ci->max_port; portnum++)
283 {
284 copyVal = 0x12f & (ci->alarmed[portnum]); /* port's alarm record */
285 comet = ci->port[portnum].cometbase;
286 value = pci_read_32 ((u_int32_t *) &comet->cdrc_ists) & sbeLinkMask; /* link loss reg */
287
288 if (value & sbeLinkChange) /* is there a change in the link stuff */
289 {
290 /* if there's been a change (above) and yet it's the same (below) */
291 if (!(((copyVal >> 3) & sbeLinkDown) ^ (value & sbeLinkDown)))
292 {
293 if (value & sbeLinkDown)
294 printk (KERN_WARN "%s: Port %d momentarily recovered.\n",
295 ci->devname, portnum);
296 else
297 printk (KERN_WARN
298 "%s: Warning: Port %d link was briefly down.\n",
299 ci->devname, portnum);
300 } else if (value & sbeLinkDown)
301 printk (KERN_WARN "%s: Warning: Port %d link is down.\n",
302 ci->devname, portnum);
303 else
304 {
305 printk (KERN_WARN "%s: Port %d link has recovered.\n",
306 ci->devname, portnum);
307 copyVal |= 0x20; /* record link transition to up */
308 }
309 copyVal |= 0x10; /* change (link) --> update LEDs */
310 }
311 copyVal &= 0x137; /* clear LED & link old history bits &
312 * save others */
313 if (value & sbeLinkDown)
314 copyVal |= 0x08; /* record link status (now) */
315 else
316 { /* if link is up, do this */
317 copyVal |= 0x40; /* LED indicate link is up */
318 /* Alarm things & the like ... first if E1, then if T1 */
319 if (IS_FRAME_ANY_E1 (ci->port[portnum].p.port_mode))
320 {
321 /*
322 * first check Codeword (SaX) changes & CRC and
323 * sub-multi-frame errors
324 */
325 /*
326 * note these errors are printed every time they are detected
327 * vs. alarms
328 */
329 value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_nat_ists); /* codeword */
330 if (value & 0x1f)
331 { /* if errors (crc or smf only) */
332 if (value & 0x10)
333 printk (KERN_WARN
334 "%s: E1 Port %d Codeword Sa4 change detected.\n",
335 ci->devname, portnum);
336 if (value & 0x08)
337 printk (KERN_WARN
338 "%s: E1 Port %d Codeword Sa5 change detected.\n",
339 ci->devname, portnum);
340 if (value & 0x04)
341 printk (KERN_WARN
342 "%s: E1 Port %d Codeword Sa6 change detected.\n",
343 ci->devname, portnum);
344 if (value & 0x02)
345 printk (KERN_WARN
346 "%s: E1 Port %d Codeword Sa7 change detected.\n",
347 ci->devname, portnum);
348 if (value & 0x01)
349 printk (KERN_WARN
350 "%s: E1 Port %d Codeword Sa8 change detected.\n",
351 ci->devname, portnum);
352 }
353 value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_mists); /* crc & smf */
354 if (value & 0x3)
355 { /* if errors (crc or smf only) */
356 if (value & sbeE1CRC)
357 printk (KERN_WARN "%s: E1 Port %d CRC-4 error(s) detected.\n",
358 ci->devname, portnum);
359 if (value & sbeE1errSMF) /* error in sub-multiframe */
360 printk (KERN_WARN "%s: E1 Port %d received errored SMF.\n",
361 ci->devname, portnum);
362 }
363 value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_masts) & 0xcc; /* alarms */
364 /*
365 * pack alarms together (bitmiser), and construct similar to
366 * T1
367 */
368 /* RAI,RMAI,.,.,LOF,AIS,.,. ==> RMAI,.,.,.,.,.,RAI,LOF,AIS */
369 /* see 0x97 */
370 value = (value >> 2);
371 if (value & 0x30)
372 {
373 if (value & 0x20)
374 value |= 0x40; /* RAI */
375 if (value & 0x10)
376 value |= 0x100; /* RMAI */
377 value &= ~0x30;
378 } /* finished packing alarm in handy order */
379 if (value != (copyVal & sbeE1AlarmsMask))
380 { /* if alarms changed */
381 copyVal |= 0x10;/* change LED status */
382 if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm))
383 {
384 copyVal &= ~sbeRedAlm;
385 printk (KERN_WARN "%s: E1 Port %d LOF alarm ended.\n",
386 ci->devname, portnum);
387 } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm))
388 {
389 copyVal |= sbeRedAlm;
390 printk (KERN_WARN "%s: E1 Warning: Port %d LOF alarm.\n",
391 ci->devname, portnum);
392 } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm))
393 {
394 copyVal &= ~sbeYelAlm;
395 printk (KERN_WARN "%s: E1 Port %d RAI alarm ended.\n",
396 ci->devname, portnum);
397 } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm))
398 {
399 copyVal |= sbeYelAlm;
400 printk (KERN_WARN "%s: E1 Warning: Port %d RAI alarm.\n",
401 ci->devname, portnum);
402 } else if ((copyVal & sbeE1RMAI) && !(value & sbeE1RMAI))
403 {
404 copyVal &= ~sbeE1RMAI;
405 printk (KERN_WARN "%s: E1 Port %d RMAI alarm ended.\n",
406 ci->devname, portnum);
407 } else if (!(copyVal & sbeE1RMAI) && (value & sbeE1RMAI))
408 {
409 copyVal |= sbeE1RMAI;
410 printk (KERN_WARN "%s: E1 Warning: Port %d RMAI alarm.\n",
411 ci->devname, portnum);
412 } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm))
413 {
414 copyVal &= ~sbeAISAlm;
415 printk (KERN_WARN "%s: E1 Port %d AIS alarm ended.\n",
416 ci->devname, portnum);
417 } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm))
418 {
419 copyVal |= sbeAISAlm;
420 printk (KERN_WARN "%s: E1 Warning: Port %d AIS alarm.\n",
421 ci->devname, portnum);
422 }
423 }
424 /* end of E1 alarm code */
425 } else
426 { /* if a T1 mode */
427 value = pci_read_32 ((u_int32_t *) &comet->t1_almi_ists); /* alarms */
428 value &= sbeAlarmsMask;
429 if (value != (copyVal & sbeAlarmsMask))
430 { /* if alarms changed */
431 copyVal |= 0x10;/* change LED status */
432 if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm))
433 {
434 copyVal &= ~sbeRedAlm;
435 printk (KERN_WARN "%s: Port %d red alarm ended.\n",
436 ci->devname, portnum);
437 } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm))
438 {
439 copyVal |= sbeRedAlm;
440 printk (KERN_WARN "%s: Warning: Port %d red alarm.\n",
441 ci->devname, portnum);
442 } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm))
443 {
444 copyVal &= ~sbeYelAlm;
445 printk (KERN_WARN "%s: Port %d yellow (RAI) alarm ended.\n",
446 ci->devname, portnum);
447 } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm))
448 {
449 copyVal |= sbeYelAlm;
450 printk (KERN_WARN "%s: Warning: Port %d yellow (RAI) alarm.\n",
451 ci->devname, portnum);
452 } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm))
453 {
454 copyVal &= ~sbeAISAlm;
455 printk (KERN_WARN "%s: Port %d blue (AIS) alarm ended.\n",
456 ci->devname, portnum);
457 } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm))
458 {
459 copyVal |= sbeAISAlm;
460 printk (KERN_WARN "%s: Warning: Port %d blue (AIS) alarm.\n",
461 ci->devname, portnum);
462 }
463 }
464 } /* end T1 mode alarm checks */
465 }
466 if (copyVal & sbeAlarmsMask)
467 copyVal |= 0x80; /* if alarm turn yel LED on */
468 if (copyVal & 0x10)
469 LEDval |= 0x100; /* tag if LED values have changed */
470 LEDval |= ((copyVal & 0xc0) >> (6 - (portnum * 2)));
471
472 ci->alarmed[portnum] &= 0xfffff000; /* out with the old (it's fff
473 * ... foo) */
474 ci->alarmed[portnum] |= (copyVal); /* in with the new */
475
476 /*
477 * enough with the alarms and LED's, now let's check for loopback
478 * requests
479 */
480
481 if (IS_FRAME_ANY_T1 (ci->port[portnum].p.port_mode))
482 { /* if a T1 mode */
483 /*
484 * begin in-band (SF) loopback code detection -- start by reading
485 * command
486 */
487 value = pci_read_32 ((u_int32_t *) &comet->ibcd_ies); /* detect reg. */
488 value &= 0x3; /* trim to handy bits */
489 if (value & 0x2)
490 { /* activate loopback (sets for deactivate
491 * code length) */
492 copyVal = c4_loop_port (ci, portnum, COMET_LBCMD_READ); /* read line loopback
493 * mode */
494 if (copyVal != COMET_MDIAG_LINELB) /* don't do it again if
495 * already in that mode */
496 c4_loop_port (ci, portnum, COMET_MDIAG_LINELB); /* put port in line
497 * loopback mode */
498 }
499 if (value & 0x1)
500 { /* deactivate loopback (sets for activate
501 * code length) */
502 copyVal = c4_loop_port (ci, portnum, COMET_LBCMD_READ); /* read line loopback
503 * mode */
504 if (copyVal != COMET_MDIAG_LBOFF) /* don't do it again if
505 * already in that mode */
506 c4_loop_port (ci, portnum, COMET_MDIAG_LBOFF); /* take port out of any
507 * loopback mode */
508 }
509 }
510 if (IS_FRAME_ANY_T1ESF (ci->port[portnum].p.port_mode))
511 { /* if a T1 ESF mode */
512 /* begin ESF loopback code */
513 value = pci_read_32 ((u_int32_t *) &comet->t1_rboc_sts) & 0x3f; /* read command */
514 if (value == 0x07)
515 c4_loop_port (ci, portnum, COMET_MDIAG_LINELB); /* put port in line
516 * loopback mode */
517 if (value == 0x0a)
518 c4_loop_port (ci, portnum, COMET_MDIAG_PAYLB); /* put port in payload
519 * loopbk mode */
520 if ((value == 0x1c) || (value == 0x19) || (value == 0x12))
521 c4_loop_port (ci, portnum, COMET_MDIAG_LBOFF); /* take port out of any
522 * loopbk mode */
523 if (log_level >= LOG_DEBUG)
524 if (value != 0x3f)
525 printk (KERN_WARN "%s: BOC value = %x on Port %d\n",
526 ci->devname, value, portnum);
527 /* end ESF loopback code */
528 }
529 }
530
531 /* if something is new, update LED's */
532 if (LEDval & 0x100)
533 pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, LEDval & 0xff);
534#endif /*** CONFIG_SBE_PMCC4_NCOMM ***/
535}
536
537
538STATIC void
539c4_watchdog (ci_t * ci)
540{
541#if 0
542 //unsigned long flags;
543#endif
544
545 if (drvr_state != SBE_DRVR_AVAILABLE)
546 {
547 if (log_level >= LOG_MONITOR)
548 printk ("%s: drvr not available (%x)\n", THIS_MODULE->name, drvr_state);
549 return;
550 }
551#if 0
552 SD_SEM_TAKE (&ci->sem_wdbusy, "_wd_"); /* only 1 thru here, per
553 * board */
554#endif
555
556 ci->wdcount++;
557 checkPorts (ci);
558#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,41)
559 if (ci->wd_notify)
560 { /* is there a state change to search for */
561 int port, gchan;
562
563 ci->wd_notify = 0; /* reset notification */
564 for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++)
565 {
566 for (port = 0; port < ci->max_port; port++)
567 {
568 mch_t *ch = ci->port[port].chan[gchan];
569
570 if (!ch || ci->state != C_RUNNING) /* state changed while
571 * acquiring semaphore */
572 break;
573 if (ch->state == UP)/* channel must be set up */
574 {
575#if 0
576#ifdef RLD_TRANS_DEBUG
577 if (1 || log_level >= LOG_MONITOR)
578#else
579 if (log_level >= LOG_MONITOR)
580#endif
581 printk ("%s: watchdog reviving Port %d Channel %d [%d] sts %x/%x, start_TX %x free %x start_RX %x\n",
582 ci->devname, ch->channum, port, gchan, ch->channum,
583 ch->p.status, ch->status,
584 ch->ch_start_tx, ch->txd_free, ch->ch_start_rx);
585#endif
586
587 /**********************************/
588 /** check for RX restart request **/
589 /**********************************/
590
591 if (ch->ch_start_rx &&
592 (ch->status & RX_ENABLED)) /* requires start on
593 * enabled RX */
594 {
595 ch->ch_start_rx = 0; /* we are restarting RX... */
596#ifdef RLD_TRANS_DEBUG
597 printk ("++ c4_watchdog() CHAN RX ACTIVATE: chan %d\n", ch->channum);
598#endif
599#ifdef RLD_RXACT_DEBUG
600 {
601 struct mdesc *md;
602 static int hereb4 = 7;
603
604 if (hereb4)
605 {
606 hereb4--;
607 md = &ch->mdr[ch->rxix_irq_srv];
608 printk ("++ c4_watchdog[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n",
609 ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status), ch->s.rx_packets);
610 musycc_dump_rxbuffer_ring (ch, 1); /* RLD DEBUG */
611 }
612 }
613#endif
614 musycc_serv_req (ch->up, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | gchan);
615 }
616 /**********************************/
617 /** check for TX restart request **/
618 /**********************************/
619
620 if (ch->ch_start_tx &&
621 (ch->status & TX_ENABLED)) /* requires start on
622 * enabled TX */
623 {
624 struct mdesc *md;
625
626 /*
627 * find next unprocessed message, then set TX thp to
628 * it
629 */
630 musycc_update_tx_thp (ch);
631
632#if 0
633 spin_lock_irqsave (&ch->ch_txlock, flags);
634#endif
635 md = ch->txd_irq_srv;
636 if (!md)
637 {
638 printk ("-- c4_watchdog[%d]: WARNING, starting NULL md\n", ch->channum);
639 printk ("-- chan %d txd_irq_srv %p sts %x usr_add %p sts %x, txpkt %lu\n",
640 ch->channum, ch->txd_irq_srv, le32_to_cpu ((struct mdesc *) (ch->txd_irq_srv)->status),
641 ch->txd_usr_add, le32_to_cpu ((struct mdesc *) (ch->txd_usr_add)->status),
642 ch->s.tx_packets);
643#if 0
644 spin_unlock_irqrestore (&ch->ch_txlock, flags);
645#endif
646 } else if (md->data && ((le32_to_cpu (md->status)) & MUSYCC_TX_OWNED))
647 {
648#ifdef RLD_TRANS_DEBUG
649 printk ("++ c4_watchdog[%d] CHAN TX ACTIVATE: start_tx %x\n", ch->channum, ch->ch_start_tx);
650#endif
651 ch->ch_start_tx = 0; /* we are restarting
652 * TX... */
653#if 0
654 spin_unlock_irqrestore (&ch->ch_txlock, flags); /* allow interrupts for
655 * service request */
656#endif
657 musycc_serv_req (ch->up, SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION | gchan);
658#ifdef RLD_TRANS_DEBUG
659 if (1 || log_level >= LOG_MONITOR)
660#else
661 if (log_level >= LOG_MONITOR)
662#endif
663 printk ("++ SACK[P%d/C%d] ack'd, continuing...\n", ch->up->portnum, ch->channum);
664 }
665 }
666 }
667 }
668 }
669 }
670#else
671 ci->wd_notify = 0;
672#endif
673#if 0
674 SD_SEM_GIVE (&ci->sem_wdbusy);/* release per-board hold */
675#endif
676}
677
678
679void
680c4_cleanup (void)
681{
682 ci_t *ci, *next;
683 mpi_t *pi;
684 int portnum, j;
685
686 ci = c4_list;
687 while (ci)
688 {
689 next = ci->next; /* protect <next> from upcoming <free> */
690 pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, PMCC4_CPLD_LED_OFF);
691 for (portnum = 0; portnum < ci->max_port; portnum++)
692 {
693 pi = &ci->port[portnum];
694#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
695 c4_wq_port_cleanup (pi);
696#endif
697 for (j = 0; j < MUSYCC_NCHANS; j++)
698 {
699 if (pi->chan[j])
700 OS_kfree (pi->chan[j]); /* free mch_t struct */
701 }
702 OS_kfree (pi->regram_saved);
703 }
704#if 0
705 /* obsolete - watchdog is now static w/in ci_t */
706 OS_free_watchdog (ci->wd);
707#endif
708 OS_kfree (ci->iqd_p_saved);
709 OS_kfree (ci);
710 ci = next; /* cleanup next board, if any */
711 }
712}
713
714
715/*
716 * This function issues a write to all comet chips and expects the same data
717 * to be returned from the subsequent read. This determines the board build
718 * to be a 1-port, 2-port, or 4-port build. The value returned represents a
719 * bit-mask of the found ports. Only certain configurations are considered
720 * VALID or LEGAL builds.
721 */
722
723int
724c4_get_portcfg (ci_t * ci)
725{
726 comet_t *comet;
727 int portnum, mask;
728 u_int32_t wdata, rdata;
729
730 wdata = COMET_MDIAG_LBOFF; /* take port out of any loopback mode */
731
732 mask = 0;
733 for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++)
734 {
735 comet = ci->port[portnum].cometbase;
736 pci_write_32 ((u_int32_t *) &comet->mdiag, wdata);
737 rdata = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
738 if (wdata == rdata)
739 mask |= 1 << portnum;
740 }
741 return mask;
742}
743
744
745/* nothing herein should generate interrupts */
746
747status_t __init
748c4_init (ci_t * ci, u_char *func0, u_char *func1)
749{
750 mpi_t *pi;
751 mch_t *ch;
752 static u_int32_t count = 0;
753 int portnum, j;
754
755 ci->state = C_INIT;
756 ci->brdno = count++;
757 ci->intlog.this_status_new = 0;
758 atomic_set (&ci->bh_pending, 0);
759
760 ci->reg = (struct musycc_globalr *) func0;
761 ci->eeprombase = (u_int32_t *) (func1 + EEPROM_OFFSET);
762 ci->cpldbase = (c4cpld_t *) ((u_int32_t *) (func1 + ISPLD_OFFSET));
763
764 /*** PORT POINT - the following is the first access of any type to the hardware ***/
765#ifdef CONFIG_SBE_PMCC4_NCOMM
766 /* NCOMM driver uses INTB interrupt to monitor CPLD register */
767 pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC);
768#else
769 /* standard driver POLLS for INTB via CPLD register */
770 pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
771#endif
772
773 {
774 int pmsk;
775
776 /* need comet addresses available for determination of hardware build */
777 for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++)
778 {
779 pi = &ci->port[portnum];
780 pi->cometbase = (comet_t *) ((u_int32_t *) (func1 + COMET_OFFSET (portnum)));
781 pi->reg = (struct musycc_globalr *) ((u_char *) ci->reg + (portnum * 0x800));
782 pi->portnum = portnum;
783 pi->p.portnum = portnum;
784 pi->openchans = 0;
785#ifdef SBE_MAP_DEBUG
786 printk ("Comet-%d: addr = %p\n", portnum, pi->cometbase);
787#endif
788 }
789 pmsk = c4_get_portcfg (ci);
790 switch (pmsk)
791 {
792 case 0x1:
793 ci->max_port = 1;
794 break;
795 case 0x3:
796 ci->max_port = 2;
797 break;
798#if 0
799 case 0x7: /* not built, but could be... */
800 ci->max_port = 3;
801 break;
802#endif
803 case 0xf:
804 ci->max_port = 4;
805 break;
806 default:
807 ci->max_port = 0;
808 printk (KERN_WARNING "%s: illegal port configuration (%x)\n", ci->devname, pmsk);
809 return SBE_DRVR_FAIL;
810 }
811#ifdef SBE_MAP_DEBUG
812 printk (">> %s: c4_get_build - pmsk %x max_port %x\n", ci->devname, pmsk, ci->max_port);
813#endif
814 }
815
816 for (portnum = 0; portnum < ci->max_port; portnum++)
817 {
818 pi = &ci->port[portnum];
819 pi->up = ci;
820 pi->sr_last = 0xffffffff;
821 pi->p.port_mode = CFG_FRAME_SF; /* T1 B8ZS, the default */
822 pi->p.portP = (CFG_CLK_PORT_EXTERNAL | CFG_LBO_LH0); /* T1 defaults */
823
824 OS_sem_init (&pi->sr_sem_busy, SEM_AVAILABLE);
825 OS_sem_init (&pi->sr_sem_wait, SEM_TAKEN);
826
827 for (j = 0; j < 32; j++)
828 {
829 pi->fifomap[j] = -1;
830 pi->tsm[j] = 0; /* no assignments, all available */
831 }
832
833 /* allocate channel structures for this port */
834 for (j = 0; j < MUSYCC_NCHANS; j++)
835 {
836 ch = OS_kmalloc (sizeof (mch_t));
837 if (ch)
838 {
839 pi->chan[j] = ch;
840 ch->state = UNASSIGNED;
841 ch->up = pi;
842 ch->gchan = (-1); /* channel assignment not yet known */
843 ch->channum = (-1); /* channel assignment not yet known */
844 ch->p.card = ci->brdno;
845 ch->p.port = portnum;
846 ch->p.channum = (-1); /* channel assignment not yet known */
847 ch->p.mode_56k = 0; /* default is 64kbps mode */
848 } else
849 {
850 printk (KERN_WARNING "%s: failed mch_t malloc, port %d channel %d size %u.\n",
851 THIS_MODULE->name, portnum, j, (unsigned int) sizeof (mch_t));
852 break;
853 }
854 }
855 }
856
857
858 {
859 /*
860 * Set LEDs through their paces to supply visual proof that LEDs are
861 * functional and not burnt out nor broken.
862 *
863 * YELLOW + GREEN -> OFF.
864 */
865
866 pci_write_32 ((u_int32_t *) &ci->cpldbase->leds,
867 PMCC4_CPLD_LED_GREEN | PMCC4_CPLD_LED_YELLOW);
868 OS_uwait (750000, "leds");
869 pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, PMCC4_CPLD_LED_OFF);
870 }
871
872 OS_init_watchdog (&ci->wd, (void (*) (void *)) c4_watchdog, ci, WATCHDOG_TIMEOUT);
873 return SBE_DRVR_SUCCESS;
874}
875
876
877/* better be fully setup to handle interrupts when you call this */
878
879status_t __init
880c4_init2 (ci_t * ci)
881{
882 status_t ret;
883
884 /* PORT POINT: this routine generates first interrupt */
885 if ((ret = musycc_init (ci)) != SBE_DRVR_SUCCESS)
886 return ret;
887
888#if 0
889 ci->p.framing_type = FRAMING_CBP;
890 ci->p.h110enable = 1;
891#if 0
892 ci->p.hypersize = 0;
893#else
894 hyperdummy = 0;
895#endif
896 ci->p.clock = 0; /* Use internal clocking until set to
897 * external */
898 c4_card_set_params (ci, &ci->p);
899#endif
900 OS_start_watchdog (&ci->wd);
901 return SBE_DRVR_SUCCESS;
902}
903
904
905/* This function sets the loopback mode (or clears it, as the case may be). */
906
907int
908c4_loop_port (ci_t * ci, int portnum, u_int8_t cmd)
909{
910 comet_t *comet;
911 volatile u_int32_t loopValue;
912
913 comet = ci->port[portnum].cometbase;
914 loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
915
916 if (cmd & COMET_LBCMD_READ)
917 return loopValue; /* return the read value */
918
919 if (loopValue != cmd)
920 {
921 switch (cmd)
922 {
923 case COMET_MDIAG_LINELB:
924 /* set(SF)loopback down (turn off) code length to 6 bits */
925 pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x05);
926 break;
927 case COMET_MDIAG_LBOFF:
928 /* set (SF) loopback up (turn on) code length to 5 bits */
929 pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x00);
930 break;
931 }
932
933 pci_write_32 ((u_int32_t *) &comet->mdiag, cmd);
934 if (log_level >= LOG_WARN)
935 printk ("%s: loopback mode changed to %2x from %2x on Port %d\n",
936 ci->devname, cmd, loopValue, portnum);
937 loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
938 if (loopValue != cmd)
939 {
940 if (log_level >= LOG_ERROR)
941 printk ("%s: write to loop register failed, unknown state for Port %d\n",
942 ci->devname, portnum);
943 }
944 } else
945 {
946 if (log_level >= LOG_WARN)
947 printk ("%s: loopback already in that mode (%2x)\n", ci->devname, loopValue);
948 }
949 return 0;
950}
951
952
953/* c4_frame_rw: read or write the comet register specified
954 * (modifies use of port_param to non-standard use of struct)
955 * Specifically:
956 * pp.portnum (one guess)
957 * pp.port_mode offset of register
958 * pp.portP write (or not, i.e. read)
959 * pp.portStatus write value
960 * BTW:
961 * pp.portStatus also used to return read value
962 * pp.portP also used during write, to return old reg value
963 */
964
965status_t
966c4_frame_rw (ci_t * ci, struct sbecom_port_param * pp)
967{
968 comet_t *comet;
969 volatile u_int32_t data;
970
971 if (pp->portnum >= ci->max_port)/* sanity check */
972 return ENXIO;
973
974 comet = ci->port[pp->portnum].cometbase;
975 data = pci_read_32 ((u_int32_t *) comet + pp->port_mode) & 0xff;
976
977 if (pp->portP)
978 { /* control says this is a register
979 * _write_ */
980 if (pp->portStatus == data)
981 printk ("%s: Port %d already that value! Writing again anyhow.\n",
982 ci->devname, pp->portnum);
983 pp->portP = (u_int8_t) data;
984 pci_write_32 ((u_int32_t *) comet + pp->port_mode,
985 pp->portStatus);
986 data = pci_read_32 ((u_int32_t *) comet + pp->port_mode) & 0xff;
987 }
988 pp->portStatus = (u_int8_t) data;
989 return 0;
990}
991
992
993/* c4_pld_rw: read or write the pld register specified
994 * (modifies use of port_param to non-standard use of struct)
995 * Specifically:
996 * pp.port_mode offset of register
997 * pp.portP write (or not, i.e. read)
998 * pp.portStatus write value
999 * BTW:
1000 * pp.portStatus also used to return read value
1001 * pp.portP also used during write, to return old reg value
1002 */
1003
1004status_t
1005c4_pld_rw (ci_t * ci, struct sbecom_port_param * pp)
1006{
1007 volatile u_int32_t *regaddr;
1008 volatile u_int32_t data;
1009 int regnum = pp->port_mode;
1010
1011 regaddr = (u_int32_t *) ci->cpldbase + regnum;
1012 data = pci_read_32 ((u_int32_t *) regaddr) & 0xff;
1013
1014 if (pp->portP)
1015 { /* control says this is a register
1016 * _write_ */
1017 pp->portP = (u_int8_t) data;
1018 pci_write_32 ((u_int32_t *) regaddr, pp->portStatus);
1019 data = pci_read_32 ((u_int32_t *) regaddr) & 0xff;
1020 }
1021 pp->portStatus = (u_int8_t) data;
1022 return 0;
1023}
1024
1025/* c4_musycc_rw: read or write the musycc register specified
1026 * (modifies use of port_param to non-standard use of struct)
1027 * Specifically:
1028 * mcp.RWportnum port number and write indication bit (0x80)
1029 * mcp.offset offset of register
1030 * mcp.value write value going in and read value returning
1031 */
1032
1033/* PORT POINT: TX Subchannel Map registers are write-only
1034 * areas within the MUSYCC and always return FF */
1035/* PORT POINT: regram and reg structures are minorly different and <offset> ioctl
1036 * settings are aligned with the <reg> struct musycc_globalr{} usage.
1037 * Also, regram is separately allocated shared memory, allocated for each port.
1038 * PORT POINT: access offsets of 0x6000 for Msg Cfg Desc Tbl are for 4-port MUSYCC
1039 * only. (An 8-port MUSYCC has 0x16000 offsets for accessing its upper 4 tables.)
1040 */
1041
1042status_t
1043c4_musycc_rw (ci_t * ci, struct c4_musycc_param * mcp)
1044{
1045 mpi_t *pi;
1046 volatile u_int32_t *dph; /* hardware implemented register */
1047 u_int32_t *dpr = 0; /* RAM image of registers for group command
1048 * usage */
1049 int offset = mcp->offset % 0x800; /* group relative address
1050 * offset, mcp->portnum is
1051 * not used */
1052 int portnum, ramread = 0;
1053 volatile u_int32_t data;
1054
1055 /*
1056 * Sanity check hardware accessibility. The 0x6000 portion handles port
1057 * numbers associated with Msg Descr Tbl decoding.
1058 */
1059 portnum = (mcp->offset % 0x6000) / 0x800;
1060 if (portnum >= ci->max_port)
1061 return ENXIO;
1062 pi = &ci->port[portnum];
1063 if (mcp->offset >= 0x6000)
1064 offset += 0x6000; /* put back in MsgCfgDesc address offset */
1065 dph = (u_int32_t *) ((u_long) pi->reg + offset);
1066
1067 /* read of TX are from RAM image, since hardware returns FF */
1068 dpr = (u_int32_t *) ((u_long) pi->regram + offset);
1069 if (mcp->offset < 0x6000) /* non MsgDesc Tbl accesses might require
1070 * RAM access */
1071 {
1072 if (offset >= 0x200 && offset < 0x380)
1073 ramread = 1;
1074 if (offset >= 0x10 && offset < 0x200)
1075 ramread = 1;
1076 }
1077 /* read register from RAM or hardware, depending... */
1078 if (ramread)
1079 {
1080 data = *dpr;
1081 //printk ("c4_musycc_rw: RAM addr %p read data %x (portno %x offset %x RAM ramread %x)\n", dpr, data, portnum, offset, ramread); /* RLD DEBUG */
1082 } else
1083 {
1084 data = pci_read_32 ((u_int32_t *) dph);
1085 //printk ("c4_musycc_rw: REG addr %p read data %x (portno %x offset %x RAM ramread %x)\n", dph, data, portnum, offset, ramread); /* RLD DEBUG */
1086 }
1087
1088
1089 if (mcp->RWportnum & 0x80)
1090 { /* control says this is a register
1091 * _write_ */
1092 if (mcp->value == data)
1093 printk ("%s: musycc grp%d already that value! writing again anyhow.\n",
1094 ci->devname, (mcp->RWportnum & 0x7));
1095 /* write register RAM */
1096 if (ramread)
1097 *dpr = mcp->value;
1098 /* write hardware register */
1099 pci_write_32 ((u_int32_t *) dph, mcp->value);
1100 }
1101 mcp->value = data; /* return the read value (or the 'old
1102 * value', if is write) */
1103 return 0;
1104}
1105
1106status_t
1107c4_get_port (ci_t * ci, int portnum)
1108{
1109 if (portnum >= ci->max_port) /* sanity check */
1110 return ENXIO;
1111
1112 SD_SEM_TAKE (&ci->sem_wdbusy, "_wd_"); /* only 1 thru here, per
1113 * board */
1114 checkPorts (ci);
1115 ci->port[portnum].p.portStatus = (u_int8_t) ci->alarmed[portnum];
1116 ci->alarmed[portnum] &= 0xdf;
1117 SD_SEM_GIVE (&ci->sem_wdbusy); /* release per-board hold */
1118 return 0;
1119}
1120
1121status_t
1122c4_set_port (ci_t * ci, int portnum)
1123{
1124 mpi_t *pi;
1125 struct sbecom_port_param *pp;
1126 int e1mode;
1127 u_int8_t clck;
1128 int i;
1129
1130 if (portnum >= ci->max_port) /* sanity check */
1131 return ENXIO;
1132
1133 pi = &ci->port[portnum];
1134 pp = &ci->port[portnum].p;
1135 e1mode = IS_FRAME_ANY_E1 (pp->port_mode);
1136 if (log_level >= LOG_MONITOR2)
1137 {
1138 printk ("%s: c4_set_port[%d]: entered, e1mode = %x, openchans %d.\n",
1139 ci->devname,
1140 portnum, e1mode, pi->openchans);
1141 }
1142 if (pi->openchans)
1143 return EBUSY; /* group needs initialization only for
1144 * first channel of a group */
1145
1146#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
1147 {
1148 status_t ret;
1149
1150 if ((ret = c4_wq_port_init (pi))) /* create/init
1151 * workqueue_struct */
1152 return (ret);
1153 }
1154#endif
1155
1156 init_comet (ci, pi->cometbase, pp->port_mode, 1 /* clockmaster == true */ , pp->portP);
1157 clck = pci_read_32 ((u_int32_t *) &ci->cpldbase->mclk) & PMCC4_CPLD_MCLK_MASK;
1158 if (e1mode)
1159 clck |= 1 << portnum;
1160 else
1161 clck &= 0xf ^ (1 << portnum);
1162
1163 pci_write_32 ((u_int32_t *) &ci->cpldbase->mclk, clck);
1164 pci_write_32 ((u_int32_t *) &ci->cpldbase->mcsr, PMCC4_CPLD_MCSR_IND);
1165 pci_write_32 ((u_int32_t *) &pi->reg->gbp, OS_vtophys (pi->regram));
1166
1167 /*********************************************************************/
1168 /* ERRATA: If transparent mode is used, do not set OOFMP_DISABLE bit */
1169 /*********************************************************************/
1170
1171 pi->regram->grcd =
1172 __constant_cpu_to_le32 (MUSYCC_GRCD_RX_ENABLE |
1173 MUSYCC_GRCD_TX_ENABLE |
1174 MUSYCC_GRCD_OOFMP_DISABLE |
1175 MUSYCC_GRCD_SF_ALIGN | /* per MUSYCC ERRATA,
1176 * for T1 * fix */
1177 MUSYCC_GRCD_COFAIRQ_DISABLE |
1178 MUSYCC_GRCD_MC_ENABLE |
1179 (MUSYCC_GRCD_POLLTH_32 << MUSYCC_GRCD_POLLTH_SHIFT));
1180
1181 pi->regram->pcd =
1182 __constant_cpu_to_le32 ((e1mode ? 1 : 0) |
1183 MUSYCC_PCD_TXSYNC_RISING |
1184 MUSYCC_PCD_RXSYNC_RISING |
1185 MUSYCC_PCD_RXDATA_RISING);
1186
1187 /* Message length descriptor */
1188 pi->regram->mld = __constant_cpu_to_le32 (max_mru | (max_mru << 16));
1189
1190 /* tsm algorithm */
1191 for (i = 0; i < 32; i++)
1192 {
1193
1194 /*** ASSIGNMENT NOTES: ***/
1195 /*** Group's channel ZERO unavailable if E1. ***/
1196 /*** Group's channel 16 unavailable if E1 CAS. ***/
1197 /*** Group's channels 24-31 unavailable if T1. ***/
1198
1199 if (((i == 0) && e1mode) ||
1200 ((i == 16) && ((pp->port_mode == CFG_FRAME_E1CRC_CAS) || (pp->port_mode == CFG_FRAME_E1CRC_CAS_AMI)))
1201 || ((i > 23) && (!e1mode)))
1202 {
1203 pi->tsm[i] = 0xff; /* make tslot unavailable for this mode */
1204 } else
1205 {
1206 pi->tsm[i] = 0x00; /* make tslot available for assignment */
1207 }
1208 }
1209 for (i = 0; i < MUSYCC_NCHANS; i++)
1210 {
1211 pi->regram->ttsm[i] = 0;
1212 pi->regram->rtsm[i] = 0;
1213 }
1214 FLUSH_MEM_WRITE ();
1215 musycc_serv_req (pi, SR_GROUP_INIT | SR_RX_DIRECTION);
1216 musycc_serv_req (pi, SR_GROUP_INIT | SR_TX_DIRECTION);
1217
1218 musycc_init_mdt (pi);
1219
1220 pi->group_is_set = 1;
1221 pi->p = *pp;
1222 return 0;
1223}
1224
1225
1226unsigned int max_int = 0;
1227
1228status_t
1229c4_new_chan (ci_t * ci, int portnum, int channum, void *user)
1230{
1231 mpi_t *pi;
1232 mch_t *ch;
1233 int gchan;
1234
1235 if (c4_find_chan (channum)) /* a new channel shouldn't already exist */
1236 return EEXIST;
1237
1238 if (portnum >= ci->max_port) /* sanity check */
1239 return ENXIO;
1240
1241 pi = &(ci->port[portnum]);
1242 /* find any available channel within this port */
1243 for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++)
1244 {
1245 ch = pi->chan[gchan];
1246 if (ch && ch->state == UNASSIGNED) /* no assignment is good! */
1247 break;
1248 }
1249 if (gchan == MUSYCC_NCHANS) /* exhausted table, all were assigned */
1250 return ENFILE;
1251
1252 ch->up = pi;
1253
1254 /* NOTE: mch_t already cleared during OS_kmalloc() */
1255 ch->state = DOWN;
1256 ch->user = user;
1257 ch->gchan = gchan;
1258 ch->channum = channum; /* mark our channel assignment */
1259 ch->p.channum = channum;
1260#if 1
1261 ch->p.card = ci->brdno;
1262 ch->p.port = portnum;
1263#endif
1264 ch->p.chan_mode = CFG_CH_PROTO_HDLC_FCS16;
1265 ch->p.idlecode = CFG_CH_FLAG_7E;
1266 ch->p.pad_fill_count = 2;
1267 spin_lock_init (&ch->ch_rxlock);
1268 spin_lock_init (&ch->ch_txlock);
1269
1270#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
1271 {
1272 status_t ret;
1273
1274 if ((ret = c4_wk_chan_init (pi, ch)))
1275 return ret;
1276 }
1277#endif
1278
1279 /* save off interface assignments which bound a board */
1280 if (ci->first_if == 0) /* first channel registered is assumed to
1281 * be the lowest channel */
1282 {
1283 ci->first_if = ci->last_if = user;
1284 ci->first_channum = ci->last_channum = channum;
1285 } else
1286 {
1287 ci->last_if = user;
1288 if (ci->last_channum < channum) /* higher number channel found */
1289 ci->last_channum = channum;
1290 }
1291 return 0;
1292}
1293
1294status_t
1295c4_del_chan (int channum)
1296{
1297 mch_t *ch;
1298
1299 if (!(ch = c4_find_chan (channum)))
1300 return ENOENT;
1301 if (ch->state == UP)
1302 musycc_chan_down ((ci_t *) 0, channum);
1303 ch->state = UNASSIGNED;
1304 ch->gchan = (-1);
1305 ch->channum = (-1);
1306 ch->p.channum = (-1);
1307 return 0;
1308}
1309
1310status_t
1311c4_del_chan_stats (int channum)
1312{
1313 mch_t *ch;
1314
1315 if (!(ch = c4_find_chan (channum)))
1316 return ENOENT;
1317
1318 memset (&ch->s, 0, sizeof (struct sbecom_chan_stats));
1319 return 0;
1320}
1321
1322
1323status_t
1324c4_set_chan (int channum, struct sbecom_chan_param * p)
1325{
1326 mch_t *ch;
1327 int i, x = 0;
1328
1329 if (!(ch = c4_find_chan (channum)))
1330 return ENOENT;
1331
1332#if 1
1333 if (ch->p.card != p->card ||
1334 ch->p.port != p->port ||
1335 ch->p.channum != p->channum)
1336 return EINVAL;
1337#endif
1338
1339 if (!(ch->up->group_is_set))
1340 {
1341 return EIO; /* out of order, SET_PORT command
1342 * required prior to first group's
1343 * SET_CHAN command */
1344 }
1345 /*
1346 * Check for change of parameter settings in order to invoke closing of
1347 * channel prior to hardware poking.
1348 */
1349
1350 if (ch->p.status != p->status || ch->p.chan_mode != p->chan_mode ||
1351 ch->p.data_inv != p->data_inv || ch->p.intr_mask != p->intr_mask ||
1352 ch->txd_free < ch->txd_num) /* to clear out queued messages */
1353 x = 1; /* we have a change requested */
1354 for (i = 0; i < 32; i++) /* check for timeslot mapping changes */
1355 if (ch->p.bitmask[i] != p->bitmask[i])
1356 x = 1; /* we have a change requested */
1357 ch->p = *p;
1358 if (x && (ch->state == UP)) /* if change request and channel is
1359 * open... */
1360 {
1361 status_t ret;
1362
1363 if ((ret = musycc_chan_down ((ci_t *) 0, channum)))
1364 return ret;
1365 if ((ret = c4_chan_up (ch->up->up, channum)))
1366 return ret;
1367 sd_enable_xmit (ch->user); /* re-enable to catch flow controlled
1368 * channel */
1369 }
1370 return 0;
1371}
1372
1373
1374status_t
1375c4_get_chan (int channum, struct sbecom_chan_param * p)
1376{
1377 mch_t *ch;
1378
1379 if (!(ch = c4_find_chan (channum)))
1380 return ENOENT;
1381 *p = ch->p;
1382 return 0;
1383}
1384
1385status_t
1386c4_get_chan_stats (int channum, struct sbecom_chan_stats * p)
1387{
1388 mch_t *ch;
1389
1390 if (!(ch = c4_find_chan (channum)))
1391 return ENOENT;
1392 *p = ch->s;
1393 p->tx_pending = atomic_read (&ch->tx_pending);
1394 return 0;
1395}
1396
1397STATIC int
1398c4_fifo_alloc (mpi_t * pi, int chan, int *len)
1399{
1400 int i, l = 0, start = 0, max = 0, maxstart = 0;
1401
1402 for (i = 0; i < 32; i++)
1403 {
1404 if (pi->fifomap[i] != -1)
1405 {
1406 l = 0;
1407 start = i + 1;
1408 continue;
1409 }
1410 ++l;
1411 if (l > max)
1412 {
1413 max = l;
1414 maxstart = start;
1415 }
1416 if (max == *len)
1417 break;
1418 }
1419 if (max != *len)
1420 {
1421 if (log_level >= LOG_WARN)
1422 printk (
1423 "%s: wanted to allocate %d fifo space, but got only %d\n",
1424 pi->up->devname, *len, max);
1425 *len = max;
1426 }
1427 if (log_level >= LOG_DEBUG)
1428 printk ("%s: allocated %d fifo at %d for channel %d/%d\n",
1429 pi->up->devname, max, start, chan, pi->p.portnum);
1430 for (i = maxstart; i < (maxstart + max); i++)
1431 pi->fifomap[i] = chan;
1432 return start;
1433}
1434
1435void
1436c4_fifo_free (mpi_t * pi, int chan)
1437{
1438 int i;
1439
1440 if (log_level >= LOG_DEBUG)
1441 printk ("%s: deallocated fifo for channel %d/%d\n",
1442 pi->up->devname, chan, pi->p.portnum);
1443 for (i = 0; i < 32; i++)
1444 if (pi->fifomap[i] == chan)
1445 pi->fifomap[i] = -1;
1446}
1447
1448
1449status_t
1450c4_chan_up (ci_t * ci, int channum)
1451{
1452 mpi_t *pi;
1453 mch_t *ch;
1454 struct mbuf *m;
1455 struct mdesc *md;
1456 int nts, nbuf, txnum, rxnum;
1457 int addr, i, j, gchan;
1458 u_int32_t tmp; /* for optimizing conversion across BE
1459 * platform */
1460
1461 if (!(ch = c4_find_chan (channum)))
1462 return ENOENT;
1463 if (ch->state == UP)
1464 {
1465 if (log_level >= LOG_MONITOR)
1466 printk ("%s: channel already UP, graceful early exit\n", ci->devname);
1467 return 0;
1468 }
1469 pi = ch->up;
1470 gchan = ch->gchan;
1471 /* find nts ('number of timeslots') */
1472 nts = 0;
1473 for (i = 0; i < 32; i++)
1474 {
1475 if (ch->p.bitmask[i] & pi->tsm[i])
1476 {
1477 if (1 || log_level >= LOG_WARN)
1478 {
1479 printk ("%s: c4_chan_up[%d] EINVAL (attempt to cfg in-use or unavailable TimeSlot[%d])\n",
1480 ci->devname, channum, i);
1481 printk ("+ ask4 %x, currently %x\n", ch->p.bitmask[i], pi->tsm[i]);
1482 }
1483 return EINVAL;
1484 }
1485 for (j = 0; j < 8; j++)
1486 if (ch->p.bitmask[i] & (1 << j))
1487 nts++;
1488 }
1489
1490 nbuf = nts / 8 ? nts / 8 : 1;
1491 if (!nbuf)
1492 {
1493 /* if( log_level >= LOG_WARN) */
1494 printk ("%s: c4_chan_up[%d] ENOBUFS (no TimeSlots assigned)\n", ci->devname, channum);
1495 return ENOBUFS; /* this should not happen */
1496 }
1497 addr = c4_fifo_alloc (pi, gchan, &nbuf);
1498 ch->state = UP;
1499
1500 /* Setup the Time Slot Map */
1501 musycc_update_timeslots (pi);
1502
1503 /* ch->tx_limit = nts; */
1504 ch->s.tx_pending = 0;
1505
1506 /* Set Channel Configuration Descriptors */
1507 {
1508 u_int32_t ccd;
1509
1510 ccd = musycc_chan_proto (ch->p.chan_mode) << MUSYCC_CCD_PROTO_SHIFT;
1511 if ((ch->p.chan_mode == CFG_CH_PROTO_ISLP_MODE) ||
1512 (ch->p.chan_mode == CFG_CH_PROTO_TRANS))
1513 {
1514 ccd |= MUSYCC_CCD_FCS_XFER; /* Non FSC Mode */
1515 }
1516 ccd |= 2 << MUSYCC_CCD_MAX_LENGTH; /* Select second MTU */
1517 ccd |= ch->p.intr_mask;
1518 ccd |= addr << MUSYCC_CCD_BUFFER_LOC;
1519 if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
1520 ccd |= (nbuf) << MUSYCC_CCD_BUFFER_LENGTH;
1521 else
1522 ccd |= (nbuf - 1) << MUSYCC_CCD_BUFFER_LENGTH;
1523
1524 if (ch->p.data_inv & CFG_CH_DINV_TX)
1525 ccd |= MUSYCC_CCD_INVERT_DATA; /* Invert data */
1526 pi->regram->tcct[gchan] = cpu_to_le32 (ccd);
1527
1528 if (ch->p.data_inv & CFG_CH_DINV_RX)
1529 ccd |= MUSYCC_CCD_INVERT_DATA; /* Invert data */
1530 else
1531 ccd &= ~MUSYCC_CCD_INVERT_DATA; /* take away data inversion */
1532 pi->regram->rcct[gchan] = cpu_to_le32 (ccd);
1533 FLUSH_MEM_WRITE ();
1534 }
1535
1536 /* Reread the Channel Configuration Descriptor for this channel */
1537 musycc_serv_req (pi, SR_CHANNEL_CONFIG | SR_RX_DIRECTION | gchan);
1538 musycc_serv_req (pi, SR_CHANNEL_CONFIG | SR_TX_DIRECTION | gchan);
1539
1540 /*
1541 * Figure out how many buffers we want. If the customer has changed from
1542 * the defaults, then use the changed values. Otherwise, use Transparent
1543 * mode's specific minimum default settings.
1544 */
1545 if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
1546 {
1547 if (max_rxdesc_used == max_rxdesc_default) /* use default setting */
1548 max_rxdesc_used = MUSYCC_RXDESC_TRANS;
1549 if (max_txdesc_used == max_txdesc_default) /* use default setting */
1550 max_txdesc_used = MUSYCC_TXDESC_TRANS;
1551 }
1552 /*
1553 * Increase counts when hyperchanneling, since this implies an increase
1554 * in throughput per channel
1555 */
1556 rxnum = max_rxdesc_used + (nts / 4);
1557 txnum = max_txdesc_used + (nts / 4);
1558
1559#if 0
1560 /* DEBUG INFO */
1561 if (log_level >= LOG_MONITOR)
1562 printk ("%s: mode %x rxnum %d (rxused %d def %d) txnum %d (txused %d def %d)\n",
1563 ci->devname, ch->p.chan_mode,
1564 rxnum, max_rxdesc_used, max_rxdesc_default,
1565 txnum, max_txdesc_used, max_txdesc_default);
1566#endif
1567
1568 ch->rxd_num = rxnum;
1569 ch->txd_num = txnum;
1570 ch->rxix_irq_srv = 0;
1571
1572 ch->mdr = OS_kmalloc (sizeof (struct mdesc) * rxnum);
1573 ch->mdt = OS_kmalloc (sizeof (struct mdesc) * txnum);
1574 if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
1575 tmp = __constant_cpu_to_le32 (max_mru | EOBIRQ_ENABLE);
1576 else
1577 tmp = __constant_cpu_to_le32 (max_mru);
1578
1579 for (i = 0, md = ch->mdr; i < rxnum; i++, md++)
1580 {
1581 if (i == (rxnum - 1))
1582 {
1583 md->snext = &ch->mdr[0];/* wrapness */
1584 } else
1585 {
1586 md->snext = &ch->mdr[i + 1];
1587 }
1588 md->next = cpu_to_le32 (OS_vtophys (md->snext));
1589
1590 if (!(m = OS_mem_token_alloc (max_mru)))
1591 {
1592 if (log_level >= LOG_MONITOR)
1593 printk ("%s: c4_chan_up[%d] - token alloc failure, size = %d.\n", ci->devname, channum, max_mru);
1594 goto errfree;
1595 }
1596 md->mem_token = m;
1597 md->data = cpu_to_le32 (OS_vtophys (OS_mem_token_data (m)));
1598 md->status = tmp | MUSYCC_RX_OWNED; /* MUSYCC owns RX descriptor **
1599 * CODING NOTE:
1600 * MUSYCC_RX_OWNED = 0 so no
1601 * need to byteSwap */
1602 }
1603
1604 for (i = 0, md = ch->mdt; i < txnum; i++, md++)
1605 {
1606 md->status = HOST_TX_OWNED; /* Host owns TX descriptor ** CODING
1607 * NOTE: HOST_TX_OWNED = 0 so no need to
1608 * byteSwap */
1609 md->mem_token = 0;
1610 md->data = 0;
1611 if (i == (txnum - 1))
1612 {
1613 md->snext = &ch->mdt[0];/* wrapness */
1614 } else
1615 {
1616 md->snext = &ch->mdt[i + 1];
1617 }
1618 md->next = cpu_to_le32 (OS_vtophys (md->snext));
1619 }
1620 ch->txd_irq_srv = ch->txd_usr_add = &ch->mdt[0];
1621 ch->txd_free = txnum;
1622 ch->tx_full = 0;
1623 ch->txd_required = 0;
1624
1625 /* Configure it into the chip */
1626 tmp = cpu_to_le32 (OS_vtophys (&ch->mdt[0]));
1627 pi->regram->thp[gchan] = tmp;
1628 pi->regram->tmp[gchan] = tmp;
1629
1630 tmp = cpu_to_le32 (OS_vtophys (&ch->mdr[0]));
1631 pi->regram->rhp[gchan] = tmp;
1632 pi->regram->rmp[gchan] = tmp;
1633
1634 /* Activate the Channel */
1635 FLUSH_MEM_WRITE ();
1636 if (ch->p.status & RX_ENABLED)
1637 {
1638#ifdef RLD_TRANS_DEBUG
1639 printk ("++ c4_chan_up() CHAN RX ACTIVATE: chan %d\n", ch->channum);
1640#endif
1641 ch->ch_start_rx = 0; /* we are restarting RX... */
1642 musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | gchan);
1643 }
1644 if (ch->p.status & TX_ENABLED)
1645 {
1646#ifdef RLD_TRANS_DEBUG
1647 printk ("++ c4_chan_up() CHAN TX ACTIVATE: chan %d <delayed>\n", ch->channum);
1648#endif
1649 ch->ch_start_tx = CH_START_TX_1ST; /* we are delaying start
1650 * until receipt from user of
1651 * first packet to transmit. */
1652 }
1653 ch->status = ch->p.status;
1654 pi->openchans++;
1655 return 0;
1656
1657errfree:
1658 while (i > 0)
1659 {
1660 /* Don't leak all the previously allocated mbufs in this loop */
1661 i--;
1662 OS_mem_token_free (ch->mdr[i].mem_token);
1663 }
1664 OS_kfree (ch->mdt);
1665 ch->mdt = 0;
1666 ch->txd_num = 0;
1667 OS_kfree (ch->mdr);
1668 ch->mdr = 0;
1669 ch->rxd_num = 0;
1670 ch->state = DOWN;
1671 return ENOBUFS;
1672}
1673
1674/* stop the hardware from servicing & interrupting */
1675
1676void
1677c4_stopwd (ci_t * ci)
1678{
1679 OS_stop_watchdog (&ci->wd);
1680 SD_SEM_TAKE (&ci->sem_wdbusy, "_stop_"); /* ensure WD not running */
1681 SD_SEM_GIVE (&ci->sem_wdbusy);
1682}
1683
1684
1685void
1686sbecom_get_brdinfo (ci_t * ci, struct sbe_brd_info * bip, u_int8_t *bsn)
1687{
1688 char *np;
1689 u_int32_t sn = 0;
1690 int i;
1691
1692 bip->brdno = ci->brdno; /* our board number */
1693 bip->brd_id = ci->brd_id;
1694 bip->brd_hdw_id = ci->hdw_bid;
1695 bip->brd_chan_cnt = MUSYCC_NCHANS * ci->max_port; /* number of channels
1696 * being used */
1697 bip->brd_port_cnt = ci->max_port; /* number of ports being used */
1698 bip->brd_pci_speed = BINFO_PCI_SPEED_unk; /* PCI speed not yet
1699 * determinable */
1700
1701 if (ci->first_if)
1702 {
1703#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1704 np = (char *) hdlc_to_name (ci->first_if);
1705#else
1706 {
1707 struct net_device *dev;
1708
1709 dev = (struct net_device *) ci->first_if;
1710 np = (char *) dev->name;
1711 }
1712#endif
1713 strncpy (bip->first_iname, np, CHNM_STRLEN - 1);
1714 } else
1715 strcpy (bip->first_iname, "<NULL>");
1716 if (ci->last_if)
1717 {
1718#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1719 np = (char *) hdlc_to_name (ci->last_if);
1720#else
1721 {
1722 struct net_device *dev;
1723
1724 dev = (struct net_device *) ci->last_if;
1725 np = (char *) dev->name;
1726 }
1727#endif
1728 strncpy (bip->last_iname, np, CHNM_STRLEN - 1);
1729 } else
1730 strcpy (bip->last_iname, "<NULL>");
1731
1732 if (bsn)
1733 {
1734 for (i = 0; i < 3; i++)
1735 {
1736 bip->brd_mac_addr[i] = *bsn++;
1737 }
1738 for (; i < 6; i++)
1739 {
1740 bip->brd_mac_addr[i] = *bsn;
1741 sn = (sn << 8) | *bsn++;
1742 }
1743 } else
1744 {
1745 for (i = 0; i < 6; i++)
1746 bip->brd_mac_addr[i] = 0;
1747 }
1748 bip->brd_sn = sn;
1749}
1750
1751
1752status_t
1753c4_get_iidinfo (ci_t * ci, struct sbe_iid_info * iip)
1754{
1755 struct net_device *dev;
1756 char *np;
1757
1758 if (!(dev = getuserbychan (iip->channum)))
1759 return ENOENT;
1760
1761#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1762 np = (char *) hdlc_to_name (dev_to_hdlc (dev));
1763#else
1764 np = dev->name;
1765#endif
1766 strncpy (iip->iname, np, CHNM_STRLEN - 1);
1767 return 0;
1768}
1769
1770
1771#ifdef CONFIG_SBE_PMCC4_NCOMM
1772void (*nciInterrupt[MAX_BOARDS][4]) (void);
1773extern void wanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler);
1774
1775void
1776wanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler)
1777{
1778 if (cardID < MAX_BOARDS) /* sanity check */
1779 nciInterrupt[cardID][deviceID] = handler;
1780}
1781
1782irqreturn_t
1783c4_ebus_intr_th_handler (void *devp)
1784{
1785 ci_t *ci = (ci_t *) devp;
1786 volatile u_int32_t ists;
1787 int handled = 0;
1788 int brdno;
1789
1790 /* which COMET caused the interrupt */
1791 brdno = ci->brdno;
1792 ists = pci_read_32 ((u_int32_t *) &ci->cpldbase->intr);
1793 if (ists & PMCC4_CPLD_INTR_CMT_1)
1794 {
1795 handled = 0x1;
1796 if (nciInterrupt[brdno][0] != NULL)
1797 (*nciInterrupt[brdno][0]) ();
1798 }
1799 if (ists & PMCC4_CPLD_INTR_CMT_2)
1800 {
1801 handled |= 0x2;
1802 if (nciInterrupt[brdno][1] != NULL)
1803 (*nciInterrupt[brdno][1]) ();
1804 }
1805 if (ists & PMCC4_CPLD_INTR_CMT_3)
1806 {
1807 handled |= 0x4;
1808 if (nciInterrupt[brdno][2] != NULL)
1809 (*nciInterrupt[brdno][2]) ();
1810 }
1811 if (ists & PMCC4_CPLD_INTR_CMT_4)
1812 {
1813 handled |= 0x8;
1814 if (nciInterrupt[brdno][3] != NULL)
1815 (*nciInterrupt[brdno][3]) ();
1816 }
1817#if 0
1818 /*** Test code just de-implements the asserted interrupt. Alternate
1819 vendor will supply COMET interrupt handling code herein or such.
1820 ***/
1821 pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
1822#endif
1823
1824#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,20)
1825 return;
1826#else
1827 return IRQ_RETVAL (handled);
1828#endif
1829}
1830
1831
1832unsigned long
1833wanpmcC4T1E1_getBaseAddress (int cardID, int deviceID)
1834{
1835 ci_t *ci;
1836 unsigned long base = 0;
1837
1838 ci = c4_list;
1839 while (ci)
1840 {
1841 if (ci->brdno == cardID) /* found valid device */
1842 {
1843 if (deviceID < ci->max_port) /* comet is supported */
1844 base = ((unsigned long) ci->port[deviceID].cometbase);
1845 break;
1846 }
1847 ci = ci->next; /* next board, if any */
1848 }
1849 return (base);
1850}
1851
1852#endif /*** CONFIG_SBE_PMCC4_NCOMM ***/
1853
1854
1855/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/pmcc4_ioctls.h b/drivers/staging/cxt1e1/pmcc4_ioctls.h
new file mode 100644
index 00000000000..6b8d65673c7
--- /dev/null
+++ b/drivers/staging/cxt1e1/pmcc4_ioctls.h
@@ -0,0 +1,81 @@
1/* RCSid: $Header: /home/rickd/projects/pmcc4/include/pmcc4_ioctls.h,v 2.0 2005/09/28 00:10:09 rickd PMCC4_3_1B $
2 */
3
4#ifndef _INC_PMCC4_IOCTLS_H_
5#define _INC_PMCC4_IOCTLS_H_
6
7/*-----------------------------------------------------------------------------
8 * pmcc4_ioctls.h -
9 *
10 * Copyright (C) 2005 SBE, Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * For further information, contact via email: support@sbei.com
23 * SBE, Inc. San Ramon, California U.S.A.
24 *-----------------------------------------------------------------------------
25 * RCS info:
26 * RCS revision: $Revision: 2.0 $
27 * Last changed on $Date: 2005/09/28 00:10:09 $
28 * Changed by $Author: rickd $
29 *-----------------------------------------------------------------------------
30 * $Log: pmcc4_ioctls.h,v $
31 * Revision 2.0 2005/09/28 00:10:09 rickd
32 * Add GNU license info. Switch Ioctls to sbe_ioc.h usage.
33 *
34 * Revision 1.2 2005/04/28 23:43:03 rickd
35 * Add RCS tracking heading.
36 *
37 *-----------------------------------------------------------------------------
38 */
39
40#include "sbew_ioc.h"
41
42enum
43{
44 // C4_GET_PORT = 0,
45 // C4_SET_PORT,
46 // C4_GET_CHAN,
47 // C4_SET_CHAN,
48 C4_DEL_CHAN = 0,
49 // C4_CREATE_CHAN,
50 // C4_GET_CHAN_STATS,
51 // C4_RESET,
52 // C4_DEBUG,
53 C4_RESET_STATS,
54 C4_LOOP_PORT,
55 C4_RW_FRMR,
56 C4_RW_MSYC,
57 C4_RW_PLD
58};
59
60#define C4_GET_PORT SBE_IOC_PORT_GET
61#define C4_SET_PORT SBE_IOC_PORT_SET
62#define C4_GET_CHAN SBE_IOC_CHAN_GET
63#define C4_SET_CHAN SBE_IOC_CHAN_SET
64// #define C4_DEL_CHAN XXX
65#define C4_CREATE_CHAN SBE_IOC_CHAN_NEW
66#define C4_GET_CHAN_STATS SBE_IOC_CHAN_GET_STAT
67#define C4_RESET SBE_IOC_RESET_DEV
68#define C4_DEBUG SBE_IOC_LOGLEVEL
69// #define C4_RESET_STATS XXX
70// #define C4_LOOP_PORT XXX
71// #define C4_RW_FRMR XXX
72// #define C4_RW_MSYC XXX
73// #define C4_RW_PLD XXX
74
75struct c4_chan_stats_wrap
76{
77 int channum;
78 struct sbecom_chan_stats stats;
79};
80
81#endif /* _INC_PMCC4_IOCTLS_H_ */
diff --git a/drivers/staging/cxt1e1/pmcc4_private.h b/drivers/staging/cxt1e1/pmcc4_private.h
new file mode 100644
index 00000000000..0ae18c444a7
--- /dev/null
+++ b/drivers/staging/cxt1e1/pmcc4_private.h
@@ -0,0 +1,295 @@
1#ifndef _INC_PMCC4_PRIVATE_H_
2#define _INC_PMCC4_PRIVATE_H_
3
4/*-----------------------------------------------------------------------------
5 * pmcc4_private.h -
6 *
7 * Copyright (C) 2005 SBE, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20
21#include <linux/kernel.h>
22#include <linux/sched.h>
23#include <linux/spinlock.h>
24#include <linux/interrupt.h> /* support for tasklets */
25#include <linux/timer.h> /* support for timer */
26#include <linux/workqueue.h>
27#include <linux/hdlc.h>
28
29#include "libsbew.h"
30#include "pmcc4_defs.h"
31#include "pmcc4_cpld.h"
32#include "musycc.h"
33#include "sbe_promformat.h"
34#include "comet.h"
35
36
37/* driver state */
38#define SBE_DRVR_INIT 0x0
39#define SBE_DRVR_AVAILABLE 0x69734F4E
40#define SBE_DRVR_DOWN 0x1
41
42/******************************************************************************
43 * MUSYCC Message Descriptor - coupled to hardware implementation, the first
44 * three u_int32 must not be reordered.
45 */
46
47struct mdesc
48{
49 volatile u_int32_t status; /* Buffer Descriptor */
50 u_int32_t data; /* Data Pointer */
51 u_int32_t next; /* MUSYCC view of Next Pointer */
52 void *mem_token; /* Data */
53 struct mdesc *snext;
54};
55
56
57/*************************************************************************
58 * Private driver data structures, internal use only.
59 */
60
61struct c4_chan_info
62{
63 int gchan; /* channel number within group/port 0-31 */
64 int channum; /* absolute channel number 0-128 */
65 u_int8_t status;
66#define TX_RECOVERY_MASK 0x0f
67#define TX_ONR_RECOVERY 0x01
68#define TX_BUFF_RECOVERY 0x02
69#define RX_RECOVERY_MASK 0xf0
70#define RX_ONR_RECOVERY 0x10
71
72 unsigned char ch_start_rx;
73#define CH_START_RX_NOW 1
74#define CH_START_RX_ONR 2
75#define CH_START_RX_BUF 3
76
77 unsigned char ch_start_tx;
78#define CH_START_TX_1ST 1
79#define CH_START_TX_ONR 2
80#define CH_START_TX_BUF 3
81
82 char tx_full; /* boolean */
83 short txd_free; /* count of TX Desc available */
84 short txd_required; /* count of TX Desc needed by mesg */
85 unsigned short rxd_num; /* must support range up to 2000 */
86 unsigned short txd_num; /* must support range up to 1000 */
87 int rxix_irq_srv;
88
89 enum
90 {
91 UNASSIGNED, /* AVAILABLE, NOTINUSE */
92 DOWN, /* ASSIGNED, NOTINUSE */
93 UP /* ASSIGNED and INUSE */
94 } state;
95
96 struct c4_port_info *up;
97 void *user;
98
99 struct work_struct ch_work;
100 struct mdesc *mdt;
101 struct mdesc *mdr;
102 struct mdesc *txd_irq_srv;
103 struct mdesc *txd_usr_add;
104
105#if 0
106 /*
107 * FUTURE CODE MIGHT SEPARATE TIMESLOT MAP SETUPS INTO SINGLE IOCTL and
108 * REMOVE MAPS FROM CHANNEL PARAMETER STRUCTURE
109 */
110 /*
111 * each byte in bitmask below represents one timeslot (bitmask[0] is for
112 * timeslot 0 and so on), each bit in the byte selects timeslot bits for
113 * this channel (0xff - whole timeslot, 0x7f - 56kbps mode)
114 */
115
116 u_int8_t ts_bitmask[32];
117#endif
118 spinlock_t ch_rxlock;
119 spinlock_t ch_txlock;
120 atomic_t tx_pending;
121
122 struct sbecom_chan_stats s;
123 struct sbecom_chan_param p;
124};
125typedef struct c4_chan_info mch_t;
126
127struct c4_port_info
128{
129
130 struct musycc_globalr *reg;
131 struct musycc_groupr *regram;
132 void *regram_saved; /* Original malloc value may have non-2KB
133 * boundary. Need to save for use when
134 * freeing. */
135 comet_t *cometbase;
136 struct sbe_card_info *up;
137
138 /*
139 * The workqueue is used for TX restart of ONR'd channels when in
140 * Transparent mode.
141 */
142
143 struct workqueue_struct *wq_port; /* chan restart work queue */
144 struct semaphore sr_sem_busy; /* service request exclusion
145 * semaphore */
146 struct semaphore sr_sem_wait; /* service request handshake
147 * semaphore */
148 u_int32_t sr_last;
149 short openchans;
150 char portnum;
151 char group_is_set; /* GROUP_INIT command issued to MUSYCC,
152 * otherwise SET_CHAN Ioctl fails */
153
154 mch_t *chan[MUSYCC_NCHANS];
155 struct sbecom_port_param p;
156
157 /*
158 * The MUSYCC timeslot mappings are maintained within the driver and are
159 * modified and reloaded as each of a group's channels are configured.
160 */
161 u_int8_t tsm[32]; /* tsm (time slot map) */
162 int fifomap[32];
163};
164typedef struct c4_port_info mpi_t;
165
166
167#define COMET_OFFSET(x) (0x80000+(x)*0x10000)
168#define EEPROM_OFFSET 0xC0000
169#define ISPLD_OFFSET 0xD0000
170
171/* iSPLD control chip registers */
172#define ISPLD_MCSR 0x0
173#define ISPLD_MCLK 0x1
174#define ISPLD_LEDS 0x2
175#define ISPLD_INTR 0x3
176#define ISPLD_MAX 0x3
177
178struct sbe_card_info
179{
180 struct musycc_globalr *reg;
181 struct musycc_groupr *regram;
182 u_int32_t *iqd_p; /* pointer to dword aligned interrupt queue
183 * descriptors */
184 void *iqd_p_saved; /* Original malloc value may have non-dword
185 * aligned boundary. Need to save for use
186 * when freeing. */
187 unsigned int iqp_headx, iqp_tailx;
188
189 struct semaphore sem_wdbusy;/* watchdog exclusion semaphore */
190 struct watchdog wd; /* statically allocated watchdog structure */
191 atomic_t bh_pending; /* bh queued, but not yet running */
192 u_int32_t brd_id; /* unique PCI ID */
193 u_int16_t hdw_bid; /* on/board hardware ID */
194 unsigned short wdcount;
195 unsigned char max_port;
196 unsigned char brdno; /* our board number */
197 unsigned char wd_notify;
198#define WD_NOTIFY_1TX 1
199#define WD_NOTIFY_BUF 2
200#define WD_NOTIFY_ONR 4
201 enum /* state as regards interrupt processing */
202 {
203 C_INIT, /* of-board-address not configured or are in
204 * process of being removed, don't access
205 * hardware */
206 C_IDLE, /* off-board-addresses are configured, but
207 * don't service interrupts, just clear them
208 * from hardware */
209 C_RUNNING /* life is good, service away */
210 } state;
211
212 struct sbe_card_info *next;
213 u_int32_t *eeprombase; /* mapped address of board's EEPROM */
214 c4cpld_t *cpldbase; /* mapped address of board's CPLD hardware */
215 char *release; /* SBE ID string w/in sbeRelease.c */
216 void *hdw_info;
217#ifdef CONFIG_PROC_FS
218 struct proc_dir_entry *dir_dev;
219#endif
220
221 /* saved off interface assignments which bound a board */
222 hdlc_device *first_if;
223 hdlc_device *last_if;
224 short first_channum, last_channum;
225
226 struct intlog
227 {
228 u_int32_t this_status_new;
229 u_int32_t last_status_new;
230 u_int32_t drvr_intr_thcount;
231 u_int32_t drvr_intr_bhcount;
232 u_int32_t drvr_int_failure;
233 } intlog;
234
235 mpi_t port[MUSYCC_NPORTS];
236 char devname[SBE_IFACETMPL_SIZE + 1];
237 atomic_t tx_pending;
238 u_int32_t alarmed[4]; /* dpm211 */
239
240#if defined(SBE_ISR_TASKLET)
241 struct tasklet_struct ci_musycc_isr_tasklet;
242#elif defined(SBE_ISR_IMMEDIATE)
243 struct tq_struct ci_musycc_isr_tq;
244#endif
245};
246typedef struct sbe_card_info ci_t;
247
248struct s_hdw_info
249{
250 u_int8_t pci_busno;
251 u_int8_t pci_slot;
252 u_int8_t pci_pin[2];
253 u_int8_t revid[2];
254 u_int8_t mfg_info_sts;
255#define EEPROM_OK 0x00
256#define EEPROM_CRCERR 0x01
257 char promfmt; /* prom type, from sbe_promformat.h */
258
259 char devname[SBE_IFACETMPL_SIZE];
260 struct pci_bus *bus;
261 struct net_device *ndev;
262 struct pci_dev *pdev[2];
263
264 unsigned long addr[2];
265 unsigned long addr_mapped[2];
266 unsigned long len[2];
267
268 union
269 {
270 char data[128];
271 FLD_TYPE1 pft1; /* prom field, type #1 */
272 FLD_TYPE2 pft2; /* prom field, type #2 */
273 } mfg_info;
274};
275typedef struct s_hdw_info hdw_info_t;
276
277/*****************************************************************/
278
279struct c4_priv
280{
281 int channum;
282 struct sbe_card_info *ci;
283};
284
285
286/*****************************************************************/
287
288extern ci_t *c4_list;
289
290mch_t *c4_find_chan (int);
291int c4_set_chan (int channum, struct sbecom_chan_param *);
292int c4_get_chan (int channum, struct sbecom_chan_param *);
293int c4_get_chan_stats (int channum, struct sbecom_chan_stats *);
294
295#endif /* _INC_PMCC4_PRIVATE_H_ */
diff --git a/drivers/staging/cxt1e1/pmcc4_sysdep.h b/drivers/staging/cxt1e1/pmcc4_sysdep.h
new file mode 100644
index 00000000000..697f1943670
--- /dev/null
+++ b/drivers/staging/cxt1e1/pmcc4_sysdep.h
@@ -0,0 +1,62 @@
1#ifndef _INC_PMCC4_SYSDEP_H_
2#define _INC_PMCC4_SYSDEP_H_
3
4/*-----------------------------------------------------------------------------
5 * pmcc4_sysdep.h -
6 *
7 * Copyright (C) 2005 SBE, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20/* reduce multiple autoconf entries to a single definition */
21
22#ifdef CONFIG_SBE_PMCC4_HDLC_V7_MODULE
23#undef CONFIG_SBE_PMCC4_HDLC_V7
24#define CONFIG_SBE_PMCC4_HDLC_V7 1
25#endif
26
27#ifdef CONFIG_SBE_PMCC4_NCOMM_MODULE
28#undef CONFIG_SBE_PMCC4_NCOMM
29#define CONFIG_SBE_PMCC4_NCOMM 1
30#endif
31
32
33/* FLUSH MACROS - if using ioremap_nocache(), then these can be NOOPS,
34 * otherwise a memory barrier needs to be inserted.
35 */
36
37#define FLUSH_PCI_READ() rmb()
38#define FLUSH_PCI_WRITE() wmb()
39#define FLUSH_MEM_READ() rmb()
40#define FLUSH_MEM_WRITE() wmb()
41
42
43/*
44 * System dependent callbacks routines, not inlined...
45 * For inlined system dependent routines, see include/sbecom_inlinux_linux.h
46 */
47
48/*
49 * passes received memory token back to the system, <user> is parameter from
50 * sd_new_chan() used to create the channel which the data arrived on
51 */
52
53void sd_recv_consume(void *token, size_t len, void *user);
54
55void sd_disable_xmit (void *user);
56void sd_enable_xmit (void *user);
57int sd_line_is_ok (void *user);
58void sd_line_is_up (void *user);
59void sd_line_is_down (void *user);
60int sd_queue_stopped (void *user);
61
62#endif /*** _INC_PMCC4_SYSDEP_H_ ***/
diff --git a/drivers/staging/cxt1e1/sbe_bid.h b/drivers/staging/cxt1e1/sbe_bid.h
new file mode 100644
index 00000000000..1f49b4061fb
--- /dev/null
+++ b/drivers/staging/cxt1e1/sbe_bid.h
@@ -0,0 +1,61 @@
1/*
2 * $Id: sbe_bid.h,v 1.0 2005/09/28 00:10:09 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_SBEBID_H_
6#define _INC_SBEBID_H_
7
8/*-----------------------------------------------------------------------------
9 * sbe_bid.h -
10 *
11 * Copyright (C) 2004-2005 SBE, Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * For further information, contact via email: support@sbei.com
24 * SBE, Inc. San Ramon, California U.S.A.
25 *
26 *-----------------------------------------------------------------------------
27 * RCS info:
28 * RCS revision: $Revision: 1.0 $
29 * Last changed on $Date: 2005/09/28 00:10:09 $
30 * Changed by $Author: rickd $
31 *-----------------------------------------------------------------------------
32 * $Log: sbe_bid.h,v $
33 * Revision 1.0 2005/09/28 00:10:09 rickd
34 * Initial revision
35 *
36 *-----------------------------------------------------------------------------
37 */
38
39#define SBE_BID_REG 0x00000000 /* Board ID Register */
40
41#define SBE_BID_256T3_E1 0x46 /* SBE wanPTMC-256T3 (E1 Version) */
42#define SBE_BID_256T3_T1 0x42 /* SBE wanPTMC-256T3 (T1 Version) */
43#define SBE_BID_2T3E3 0x43 /* SBE wanPMC-2T3E3 */
44#define SBE_BID_C1T3 0x45 /* SBE wanPMC-C1T3 */
45#define SBE_BID_C24TE1 0x47 /* SBE wanPTMC-C24TE1 */
46#define SBE_BID_C24TE1_RTM_24 0x48 /* C24TE1 RTM (24 Port) */
47#define SBE_BID_C24TE1_RTM_12 0x49 /* C24TE1 RTM (12 Port) */
48#define SBE_BID_C24TE1_RTM_12DSU 0x4A /* C24TE1 RTM (12 Port/DSU) */
49#define SBE_BID_C24TE1_RTM_T3 0x4B /* C24TE1 RTM (T3) */
50#define SBE_BID_C4T1E1 0x41 /* SBE wanPTMC-C4T1E1 */
51#define SBE_BID_HC4T1E1 0x44 /* SBE wanADAPT-HC4T1E1 */
52
53/* bogus temporary usage values */
54#define SBE_BID_PMC_C4T1E1 0xC4 /* SBE wanPMC-C4T1E1 (4 Port) */
55#define SBE_BID_PMC_C2T1E1 0xC2 /* SBE wanPMC-C2T1E1 (2 Port) */
56#define SBE_BID_PMC_C1T1E1 0xC1 /* SBE wanPMC-C1T1E1 (1 Port) */
57#define SBE_BID_PCI_C4T1E1 0x04 /* SBE wanPCI-C4T1E1 (4 Port) */
58#define SBE_BID_PCI_C2T1E1 0x02 /* SBE wanPCI-C2T1E1 (2 Port) */
59#define SBE_BID_PCI_C1T1E1 0x01 /* SBE wanPCI-C1T1E1 (1 Port) */
60
61#endif /*** _INC_SBEBID_H_ ***/
diff --git a/drivers/staging/cxt1e1/sbe_promformat.h b/drivers/staging/cxt1e1/sbe_promformat.h
new file mode 100644
index 00000000000..746f81b15c7
--- /dev/null
+++ b/drivers/staging/cxt1e1/sbe_promformat.h
@@ -0,0 +1,157 @@
1/*
2 * $Id: sbe_promformat.h,v 2.2 2005/09/28 00:10:09 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_SBE_PROMFORMAT_H_
6#define _INC_SBE_PROMFORMAT_H_
7
8/*-----------------------------------------------------------------------------
9 * sbe_promformat.h - Contents of seeprom used by dvt and manufacturing tests
10 *
11 * Copyright (C) 2002-2005 SBE, Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * For further information, contact via email: support@sbei.com
24 * SBE, Inc. San Ramon, California U.S.A.
25 *
26 *-----------------------------------------------------------------------------
27 * RCS info:
28 * RCS revision: $Revision: 2.2 $
29 * Last changed on $Date: 2005/09/28 00:10:09 $
30 * Changed by $Author: rickd $
31 *-----------------------------------------------------------------------------
32 * $Log: sbe_promformat.h,v $
33 * Revision 2.2 2005/09/28 00:10:09 rickd
34 * Add EEPROM sample from C4T1E1 board.
35 *
36 * Revision 2.1 2005/05/04 17:18:24 rickd
37 * Initial CI.
38 *
39 *-----------------------------------------------------------------------------
40 */
41
42
43/***
44 * PMCC4 SAMPLE EEPROM IMAGE
45 *
46 * eeprom[00]: 01 11 76 07 01 00 a0 d6
47 * eeprom[08]: 22 34 56 3e 5b c1 1c 3e
48 * eeprom[16]: 5b e1 b6 00 00 00 01 00
49 * eeprom[24]: 00 08 46 d3 7b 5e a8 fb
50 * eeprom[32]: f7 ef df bf 7f 55 00 01
51 * eeprom[40]: 02 04 08 10 20 40 80 ff
52 * eeprom[48]: fe fd fb f7 ef df bf 7f
53 *
54 ***/
55
56
57/*------------------------------------------------------------------------
58 * Type 1 Format
59 * byte:
60 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
61 * -------------------------------------------------------------------------
62 * 01 11 76 SS SS 00 0A D6 <SERIAL NUM> <Create TIME> <Heatrun TIME>
63 * SBE SUB SERIAL # (BCD) (time_t) (time_t)
64 * ID VENDOR (format) (format)
65 *
66 * 19 20 21 22 23 24 25 26
67 * Heat Run Heat Run
68 * Iterations Errors
69 *------------------------------------------------------------------------
70 *
71 *
72 *
73 * Type 2 Format - Added length, CRC in fixed position
74 * byte:
75 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
76 * -------------------------------------------------------------------------
77 * 02 00 1A CC CC CC CC 11 76 07 03 00 0A D6 <SERIAL NUM>
78 * Payload SBE Crc32 SUB System System SERIAL/MAC
79 * Length VENDOR ID ID
80 *
81 * 17 18 19 20 21 22 23 24 25 26 27 28 29 39 31 32
82 * --------------------------------------------------------------------------
83 * <Create TIME> <Heatrun TIME> Heat Run Heat Run
84 * (time_t) (time_t) Iterations Errors
85 *
86 */
87
88#ifdef __cplusplus
89extern "C"
90{
91#endif
92
93
94#define STRUCT_OFFSET(type, symbol) ((long)&(((type *)0)->symbol))
95
96/*------------------------------------------------------------------------
97 * Historically different Prom format types.
98 *
99 * For diagnostic and failure purposes, do not create a type 0x00 or a
100 * type 0xff
101 *------------------------------------------------------------------------
102 */
103#define PROM_FORMAT_Unk (-1)
104#define PROM_FORMAT_TYPE1 1
105#define PROM_FORMAT_TYPE2 2
106
107
108/****** bit fields for a type 1 formatted seeprom **************************/
109 typedef struct
110 {
111 char type; /* 0x00 */
112 char Id[2]; /* 0x01-0x02 */
113 char SubId[2]; /* 0x03-0x04 */
114 char Serial[6]; /* 0x05-0x0a */
115 char CreateTime[4]; /* 0x0b-0x0e */
116 char HeatRunTime[4]; /* 0x0f-0x12 */
117 char HeatRunIterations[4]; /* 0x13-0x16 */
118 char HeatRunErrors[4]; /* 0x17-0x1a */
119 char Crc32[4]; /* 0x1b-0x1e */
120 } FLD_TYPE1;
121
122
123/****** bit fields for a type 2 formatted seeprom **************************/
124 typedef struct
125 {
126 char type; /* 0x00 */
127 char length[2]; /* 0x01-0x02 */
128 char Crc32[4]; /* 0x03-0x06 */
129 char Id[2]; /* 0x07-0x08 */
130 char SubId[2]; /* 0x09-0x0a */
131 char Serial[6]; /* 0x0b-0x10 */
132 char CreateTime[4]; /* 0x11-0x14 */
133 char HeatRunTime[4]; /* 0x15-0x18 */
134 char HeatRunIterations[4]; /* 0x19-0x1c */
135 char HeatRunErrors[4]; /* 0x1d-0x20 */
136 } FLD_TYPE2;
137
138
139
140/***** this union allows us to access the seeprom as an array of bytes ***/
141/***** or as individual fields ***/
142
143#define SBE_EEPROM_SIZE 128
144#define SBE_MFG_INFO_SIZE sizeof(FLD_TYPE2)
145
146 typedef union
147 {
148 char bytes[128];
149 FLD_TYPE1 fldType1;
150 FLD_TYPE2 fldType2;
151 } PROMFORMAT;
152
153#ifdef __cplusplus
154}
155#endif
156
157#endif /*** _INC_SBE_PROMFORMAT_H_ ***/
diff --git a/drivers/staging/cxt1e1/sbecom_inline_linux.h b/drivers/staging/cxt1e1/sbecom_inline_linux.h
new file mode 100644
index 00000000000..2ab1eb12ed3
--- /dev/null
+++ b/drivers/staging/cxt1e1/sbecom_inline_linux.h
@@ -0,0 +1,310 @@
1/*
2 * $Id: sbecom_inline_linux.h,v 1.2 2007/08/15 22:51:35 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_SBECOM_INLNX_H_
6#define _INC_SBECOM_INLNX_H_
7
8/*-----------------------------------------------------------------------------
9 * sbecom_inline_linux.h - SBE common Linux inlined routines
10 *
11 * Copyright (C) 2007 One Stop Systems, Inc.
12 * Copyright (C) 2005 SBE, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * For further information, contact via email: support@onestopsystems.com
25 * One Stop Systems, Inc. Escondido, California U.S.A.
26 *-----------------------------------------------------------------------------
27 * RCS info:
28 * RCS revision: $Revision: 1.2 $
29 * Last changed on $Date: 2007/08/15 22:51:35 $
30 * Changed by $Author: rickd $
31 *-----------------------------------------------------------------------------
32 * $Log: sbecom_inline_linux.h,v $
33 * Revision 1.2 2007/08/15 22:51:35 rickd
34 * Remove duplicate version.h entry.
35 *
36 * Revision 1.1 2007/08/15 22:50:29 rickd
37 * Update linux/config for 2.6.18 and later.
38 *
39 * Revision 1.0 2005/09/28 00:10:09 rickd
40 * Initial revision
41 *
42 *-----------------------------------------------------------------------------
43 */
44
45
46#if defined (__FreeBSD__) || defined (__NetBSD__)
47#include <sys/types.h>
48#else
49#include <linux/types.h>
50#include <linux/version.h>
51#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
52#include <linux/config.h>
53#endif
54#if defined(CONFIG_SMP) && ! defined(__SMP__)
55#define __SMP__
56#endif
57#if defined(CONFIG_MODVERSIONS) && defined(MODULE) && ! defined(MODVERSIONS)
58#define MODVERSIONS
59#endif
60
61#ifdef MODULE
62#ifdef MODVERSIONS
63#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
64#include <linux/modversions.h>
65#else
66#include <config/modversions.h>
67#endif
68#endif
69#include <linux/module.h>
70#endif
71#endif
72
73#include <linux/kernel.h> /* resolves kmalloc references */
74#include <linux/skbuff.h> /* resolves skb references */
75#include <linux/netdevice.h> /* resolves dev_kree_skb_any */
76#include <asm/byteorder.h> /* resolves cpu_to_le32 */
77
78#if 0
79
80/*** PORT POINT WARNING
81 ***
82 *** Under Linux 2.6 it has been found that compiler is re-ordering
83 *** in-lined pci_write_32() functions to the detrement of correct
84 *** hardware setup. Therefore, inlining of PCI accesses has been
85 *** de-implemented, and subroutine calls have been implemented.
86 ***/
87
88static inline u_int32_t
89pci_read_32 (u_int32_t *p)
90{
91#ifdef FLOW_DEBUG
92 u_int32_t v;
93
94 FLUSH_PCI_READ ();
95 v = le32_to_cpu (*p);
96 if (log_level >= LOG_DEBUG)
97 printk ("pci_read : %x = %x\n", (u_int32_t) p, v);
98 return v;
99#else
100 FLUSH_PCI_READ (); /* */
101 return le32_to_cpu (*p);
102#endif
103}
104
105static inline void
106pci_write_32 (u_int32_t *p, u_int32_t v)
107{
108#ifdef FLOW_DEBUG
109 if (log_level >= LOG_DEBUG)
110 printk ("pci_write: %x = %x\n", (u_int32_t) p, v);
111#endif
112 *p = cpu_to_le32 (v);
113 FLUSH_PCI_WRITE (); /* This routine is called from routines
114 * which do multiple register writes
115 * which themselves need flushing between
116 * writes in order to guarantee write
117 * ordering. It is less code-cumbersome
118 * to flush here-in then to investigate
119 * and code the many other register
120 * writing routines. */
121}
122#else
123/* forward reference */
124u_int32_t pci_read_32 (u_int32_t *p);
125void pci_write_32 (u_int32_t *p, u_int32_t v);
126
127#endif
128
129
130/*
131 * system dependent callbacks
132 */
133
134/**********/
135/* malloc */
136/**********/
137
138static inline void *
139OS_kmalloc (size_t size)
140{
141 char *ptr = kmalloc (size, GFP_KERNEL | GFP_DMA);
142
143 if (ptr)
144 memset (ptr, 0, size);
145 return ptr;
146}
147
148static inline void
149OS_kfree (void *x)
150{
151 kfree (x);
152}
153
154
155/****************/
156/* memory token */
157/****************/
158
159static inline void *
160OS_mem_token_alloc (size_t size)
161{
162 struct sk_buff *skb;
163
164 skb = dev_alloc_skb (size);
165 if (!skb)
166 {
167 //printk (KERN_WARNING "no mem in OS_mem_token_alloc !");
168 return 0;
169 }
170 return skb;
171}
172
173
174static inline void
175OS_mem_token_free (void *token)
176{
177 dev_kfree_skb_any (token);
178}
179
180
181static inline void
182OS_mem_token_free_irq (void *token)
183{
184 dev_kfree_skb_irq (token);
185}
186
187
188static inline void *
189OS_mem_token_data (void *token)
190{
191 return ((struct sk_buff *) token)->data;
192}
193
194
195static inline void *
196OS_mem_token_next (void *token)
197{
198 return 0;
199}
200
201
202static inline int
203OS_mem_token_len (void *token)
204{
205 return ((struct sk_buff *) token)->len;
206}
207
208
209static inline int
210OS_mem_token_tlen (void *token)
211{
212 return ((struct sk_buff *) token)->len;
213}
214
215
216/***************************************/
217/* virtual to physical addr conversion */
218/***************************************/
219
220static inline u_long
221OS_phystov (void *addr)
222{
223 return (u_long) __va (addr);
224}
225
226
227static inline u_long
228OS_vtophys (void *addr)
229{
230 return __pa (addr);
231}
232
233
234/**********/
235/* semops */
236/**********/
237
238void OS_sem_init (void *, int);
239
240
241static inline void
242OS_sem_free (void *sem)
243{
244 /*
245 * NOOP - since semaphores structures predeclared w/in structures, no
246 * longer malloc'd
247 */
248}
249
250#define SD_SEM_TAKE(sem,desc) down(sem)
251#define SD_SEM_GIVE(sem) up(sem)
252#define SEM_AVAILABLE 1
253#define SEM_TAKEN 0
254
255
256/**********************/
257/* watchdog functions */
258/**********************/
259
260struct watchdog
261{
262 struct timer_list h;
263#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
264 struct tq_struct tq;
265#else
266 struct work_struct work;
267#endif
268 void *softc;
269 void (*func) (void *softc);
270 int ticks;
271 int init_tq;
272};
273
274
275static inline int
276OS_start_watchdog (struct watchdog * wd)
277{
278 wd->h.expires = jiffies + wd->ticks;
279 add_timer (&wd->h);
280 return 0;
281}
282
283
284static inline int
285OS_stop_watchdog (struct watchdog * wd)
286{
287 del_timer_sync (&wd->h);
288 return 0;
289}
290
291
292static inline int
293OS_free_watchdog (struct watchdog * wd)
294{
295 OS_stop_watchdog (wd);
296 OS_kfree (wd);
297 return 0;
298}
299
300
301/* sleep in microseconds */
302void OS_uwait (int usec, char *description);
303void OS_uwait_dummy (void);
304
305
306/* watchdog functions */
307int OS_init_watchdog(struct watchdog *wdp, void (*f) (void *), void *ci, int usec);
308
309
310#endif /*** _INC_SBECOM_INLNX_H_ ***/
diff --git a/drivers/staging/cxt1e1/sbecrc.c b/drivers/staging/cxt1e1/sbecrc.c
new file mode 100644
index 00000000000..51232948091
--- /dev/null
+++ b/drivers/staging/cxt1e1/sbecrc.c
@@ -0,0 +1,137 @@
1/* Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobbs'
2 * Journal, May 1992, pp. 64-67. This algorithm generates the same CRC
3 * values as ZMODEM and PKZIP
4 *
5 * Copyright (C) 2002-2005 SBE, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/types.h>
19#include "pmcc4_sysdep.h"
20#include "sbecom_inline_linux.h"
21#include "sbe_promformat.h"
22
23/* defines */
24#define CRC32_POLYNOMIAL 0xEDB88320L
25#define CRC_TABLE_ENTRIES 256
26
27
28
29static u_int32_t crcTableInit;
30
31#ifdef STATIC_CRC_TABLE
32static u_int32_t CRCTable[CRC_TABLE_ENTRIES];
33
34#endif
35
36
37/***************************************************************************
38*
39* genCrcTable - fills in CRCTable, as used by sbeCrc()
40*
41* RETURNS: N/A
42*
43* ERRNO: N/A
44***************************************************************************/
45
46static void
47genCrcTable (u_int32_t *CRCTable)
48{
49 int ii, jj;
50 u_int32_t crc;
51
52 for (ii = 0; ii < CRC_TABLE_ENTRIES; ii++)
53 {
54 crc = ii;
55 for (jj = 8; jj > 0; jj--)
56 {
57 if (crc & 1)
58 crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
59 else
60 crc >>= 1;
61 }
62 CRCTable[ii] = crc;
63 }
64
65 crcTableInit++;
66}
67
68
69/***************************************************************************
70*
71* sbeCrc - generates a CRC on a given buffer, and initial CRC
72*
73* This routine calculates the CRC for a buffer of data using the
74* table lookup method. It accepts an original value for the crc,
75* and returns the updated value. This permits "catenation" of
76* discontiguous buffers. An original value of 0 for the "first"
77* buffer is the norm.
78*
79* Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobb's
80* Journal, May 1992, pp. 64-67. This algorithm generates the same CRC
81* values as ZMODEM and PKZIP.
82*
83* RETURNS: calculated crc of block
84*
85*/
86
87void
88sbeCrc (u_int8_t *buffer, /* data buffer to crc */
89 u_int32_t count, /* length of block in bytes */
90 u_int32_t initialCrc, /* starting CRC */
91 u_int32_t *result)
92{
93 u_int32_t *tbl = 0;
94 u_int32_t temp1, temp2, crc;
95
96 /*
97 * if table not yet created, do so. Don't care about "extra" time
98 * checking this everytime sbeCrc() is called, since CRC calculations are
99 * already time consuming
100 */
101 if (!crcTableInit)
102 {
103#ifdef STATIC_CRC_TABLE
104 tbl = &CRCTable;
105 genCrcTable (tbl);
106#else
107 tbl = (u_int32_t *) OS_kmalloc (CRC_TABLE_ENTRIES * sizeof (u_int32_t));
108 if (tbl == 0)
109 {
110 *result = 0; /* dummy up return value due to malloc
111 * failure */
112 return;
113 }
114 genCrcTable (tbl);
115#endif
116 }
117 /* inverting bits makes ZMODEM & PKZIP compatible */
118 crc = initialCrc ^ 0xFFFFFFFFL;
119
120 while (count-- != 0)
121 {
122 temp1 = (crc >> 8) & 0x00FFFFFFL;
123 temp2 = tbl[((int) crc ^ *buffer++) & 0xff];
124 crc = temp1 ^ temp2;
125 }
126
127 crc ^= 0xFFFFFFFFL;
128
129 *result = crc;
130
131#ifndef STATIC_CRC_TABLE
132 crcTableInit = 0;
133 OS_kfree (tbl);
134#endif
135}
136
137/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/sbeid.c b/drivers/staging/cxt1e1/sbeid.c
new file mode 100644
index 00000000000..a2243b10ef0
--- /dev/null
+++ b/drivers/staging/cxt1e1/sbeid.c
@@ -0,0 +1,217 @@
1/* Copyright (C) 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/types.h>
15#include "pmcc4_sysdep.h"
16#include "sbecom_inline_linux.h"
17#include "libsbew.h"
18#include "pmcc4_private.h"
19#include "pmcc4.h"
20#include "sbe_bid.h"
21
22#ifdef SBE_INCLUDE_SYMBOLS
23#define STATIC
24#else
25#define STATIC static
26#endif
27
28
29char *
30sbeid_get_bdname (ci_t * ci)
31{
32 char *np = 0;
33
34 switch (ci->brd_id)
35 {
36 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
37 np = "wanPTMC-256T3 <E1>";
38 break;
39 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
40 np = "wanPTMC-256T3 <T1>";
41 break;
42 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
43 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
44 np = "wanPMC-C4T1E1";
45 break;
46 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
47 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
48 np = "wanPMC-C2T1E1";
49 break;
50 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
51 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
52 np = "wanPMC-C1T1E1";
53 break;
54 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
55 np = "wanPCI-C4T1E1";
56 break;
57 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
58 np = "wanPCI-C2T1E1";
59 break;
60 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
61 np = "wanPCI-C1T1E1";
62 break;
63 default:
64 /*** np = "<unknown>"; ***/
65 np = "wanPCI-CxT1E1";
66 break;
67 }
68
69 return np;
70}
71
72
73/* given the presetting of brd_id, set the corresponding hdw_id */
74
75void
76sbeid_set_hdwbid (ci_t * ci)
77{
78 /*
79 * set SBE's unique hardware identification (for legacy boards might not
80 * have this register implemented)
81 */
82
83 switch (ci->brd_id)
84 {
85 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
86 ci->hdw_bid = SBE_BID_256T3_E1; /* 0x46 - SBE wanPTMC-256T3 (E1
87 * Version) */
88 break;
89 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
90 ci->hdw_bid = SBE_BID_256T3_T1; /* 0x42 - SBE wanPTMC-256T3 (T1
91 * Version) */
92 break;
93 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
94 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
95 /*
96 * This Board ID is a generic identification. Use the found number
97 * of ports to further define this hardware.
98 */
99 switch (ci->max_port)
100 {
101 default: /* shouldn't need a default, but have one
102 * anyway */
103 case 4:
104 ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0xC4 - SBE wanPMC-C4T1E1 */
105 break;
106 case 2:
107 ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */
108 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1);
109 break;
110 case 1:
111 ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */
112 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1);
113 break;
114 }
115 break;
116 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
117 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
118 ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */
119 break;
120 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
121 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
122 ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */
123 break;
124#ifdef SBE_PMCC4_ENABLE
125 /*
126 * This case is entered as a result of the inability to obtain the
127 * <bid> from the board's EEPROM. Assume a PCI board and set
128 * <hdsbid> according to the number ofr found ports.
129 */
130 case 0:
131 /* start by assuming 4-port for ZERO casing */
132 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
133 /* drop thru to set hdw_bid and alternate PCI CxT1E1 settings */
134#endif
135 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
136 /*
137 * This Board ID is a generic identification. Use the number of
138 * found ports to further define this hardware.
139 */
140 switch (ci->max_port)
141 {
142 default: /* shouldn't need a default, but have one
143 * anyway */
144 case 4:
145 ci->hdw_bid = SBE_BID_PCI_C4T1E1; /* 0x04 - SBE wanPCI-C4T1E1 */
146 break;
147 case 2:
148 ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */
149 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1);
150 break;
151 case 1:
152 ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */
153 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1);
154 break;
155 }
156 break;
157 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
158 ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */
159 break;
160 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
161 ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */
162 break;
163 default:
164 /*** bid = "<unknown>"; ***/
165 ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0x41 - SBE wanPTMC-C4T1E1 */
166 break;
167 }
168}
169
170/* given the presetting of hdw_bid, set the corresponding brd_id */
171
172void
173sbeid_set_bdtype (ci_t * ci)
174{
175 /* set SBE's unique PCI VENDOR/DEVID */
176 switch (ci->hdw_bid)
177 {
178 case SBE_BID_C1T3: /* SBE wanPMC-C1T3 */
179 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3);
180 break;
181 case SBE_BID_C24TE1: /* SBE wanPTMC-C24TE1 */
182 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1);
183 break;
184 case SBE_BID_256T3_E1: /* SBE wanPTMC-256T3 E1 Version */
185 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1);
186 break;
187 case SBE_BID_256T3_T1: /* SBE wanPTMC-256T3 T1 Version */
188 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1);
189 break;
190 case SBE_BID_PMC_C4T1E1: /* 0xC4 - SBE wanPMC-C4T1E1 */
191 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1);
192 break;
193 case SBE_BID_PMC_C2T1E1: /* 0xC2 - SBE wanPMC-C2T1E1 */
194 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1);
195 break;
196 case SBE_BID_PMC_C1T1E1: /* 0xC1 - SBE wanPMC-C1T1E1 */
197 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1);
198 break;
199 case SBE_BID_PCI_C4T1E1: /* 0x04 - SBE wanPCI-C4T1E1 */
200 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
201 break;
202 case SBE_BID_PCI_C2T1E1: /* 0x02 - SBE wanPCI-C2T1E1 */
203 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1);
204 break;
205 case SBE_BID_PCI_C1T1E1: /* 0x01 - SBE wanPCI-C1T1E1 */
206 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1);
207 break;
208
209 default:
210 /*** hdw_bid = "<unknown>"; ***/
211 ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
212 break;
213 }
214}
215
216
217/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/sbeproc.c b/drivers/staging/cxt1e1/sbeproc.c
new file mode 100644
index 00000000000..61ca639c184
--- /dev/null
+++ b/drivers/staging/cxt1e1/sbeproc.c
@@ -0,0 +1,358 @@
1/* Copyright (C) 2004-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/types.h>
15#include <linux/module.h>
16#include <linux/errno.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/proc_fs.h>
20#include <linux/sched.h>
21#include <asm/uaccess.h>
22#include "pmcc4_sysdep.h"
23#include "sbecom_inline_linux.h"
24#include "pmcc4_private.h"
25#include "sbeproc.h"
26
27/* forwards */
28void sbecom_get_brdinfo (ci_t *, struct sbe_brd_info *, u_int8_t *);
29extern struct s_hdw_info hdw_info[MAX_BOARDS];
30
31#ifdef CONFIG_PROC_FS
32
33/********************************************************************/
34/* procfs stuff */
35/********************************************************************/
36
37
38void
39sbecom_proc_brd_cleanup (ci_t * ci)
40{
41 if (ci->dir_dev)
42 {
43 char dir[7 + SBE_IFACETMPL_SIZE + 1];
44 snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
45 remove_proc_entry("info", ci->dir_dev);
46 remove_proc_entry(dir, NULL);
47 ci->dir_dev = NULL;
48 }
49}
50
51
52static int
53sbecom_proc_get_sbe_info (char *buffer, char **start, off_t offset,
54 int length, int *eof, void *priv)
55{
56 ci_t *ci = (ci_t *) priv;
57 int len = 0;
58 char *spd;
59 struct sbe_brd_info *bip;
60
61 if (!(bip = OS_kmalloc (sizeof (struct sbe_brd_info))))
62 {
63 return -ENOMEM;
64 }
65#if 0
66 /** RLD DEBUG **/
67 printk (">> sbecom_proc_get_sbe_info: entered, offset %d. length %d.\n",
68 (int) offset, (int) length);
69#endif
70
71 {
72 hdw_info_t *hi = &hdw_info[ci->brdno];
73
74 u_int8_t *bsn = 0;
75
76 switch (hi->promfmt)
77 {
78 case PROM_FORMAT_TYPE1:
79 bsn = (u_int8_t *) hi->mfg_info.pft1.Serial;
80 break;
81 case PROM_FORMAT_TYPE2:
82 bsn = (u_int8_t *) hi->mfg_info.pft2.Serial;
83 break;
84 }
85
86 sbecom_get_brdinfo (ci, bip, bsn);
87 }
88
89#if 0
90 /** RLD DEBUG **/
91 printk (">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n",
92 (char *) &bip->first_iname, (char *) &bip->first_iname,
93 (char *) &bip->last_iname, (char *) &bip->last_iname);
94#endif
95 len += sprintf (buffer + len, "Board Type: ");
96 switch (bip->brd_id)
97 {
98 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3):
99 len += sprintf (buffer + len, "wanPMC-C1T3");
100 break;
101 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
102 len += sprintf (buffer + len, "wanPTMC-256T3 <E1>");
103 break;
104 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
105 len += sprintf (buffer + len, "wanPTMC-256T3 <T1>");
106 break;
107 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1):
108 len += sprintf (buffer + len, "wanPTMC-C24TE1");
109 break;
110
111 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
112 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
113 len += sprintf (buffer + len, "wanPMC-C4T1E1");
114 break;
115 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
116 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
117 len += sprintf (buffer + len, "wanPMC-C2T1E1");
118 break;
119 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
120 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
121 len += sprintf (buffer + len, "wanPMC-C1T1E1");
122 break;
123
124 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
125 len += sprintf (buffer + len, "wanPCI-C4T1E1");
126 break;
127 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
128 len += sprintf (buffer + len, "wanPCI-C2T1E1");
129 break;
130 case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
131 len += sprintf (buffer + len, "wanPCI-C1T1E1");
132 break;
133
134 default:
135 len += sprintf (buffer + len, "unknown");
136 break;
137 }
138 len += sprintf (buffer + len, " [%08X]\n", bip->brd_id);
139
140 len += sprintf (buffer + len, "Board Number: %d\n", bip->brdno);
141 len += sprintf (buffer + len, "Hardware ID: 0x%02X\n", ci->hdw_bid);
142 len += sprintf (buffer + len, "Board SN: %06X\n", bip->brd_sn);
143 len += sprintf (buffer + len, "Board MAC: %02X-%02X-%02X-%02X-%02X-%02X\n",
144 bip->brd_mac_addr[0], bip->brd_mac_addr[1], bip->brd_mac_addr[2],
145 bip->brd_mac_addr[3], bip->brd_mac_addr[4], bip->brd_mac_addr[5]);
146 len += sprintf (buffer + len, "Ports: %d\n", ci->max_port);
147 len += sprintf (buffer + len, "Channels: %d\n", bip->brd_chan_cnt);
148#if 1
149 len += sprintf (buffer + len, "Interface: %s -> %s\n",
150 (char *) &bip->first_iname, (char *) &bip->last_iname);
151#else
152 len += sprintf (buffer + len, "Interface: <not available> 1st %p lst %p\n",
153 (char *) &bip->first_iname, (char *) &bip->last_iname);
154#endif
155
156 switch (bip->brd_pci_speed)
157 {
158 case BINFO_PCI_SPEED_33:
159 spd = "33Mhz";
160 break;
161 case BINFO_PCI_SPEED_66:
162 spd = "66Mhz";
163 break;
164 default:
165 spd = "<not available>";
166 break;
167 }
168 len += sprintf (buffer + len, "PCI Bus Speed: %s\n", spd);
169 len += sprintf (buffer + len, "Release: %s\n", ci->release);
170
171#ifdef SBE_PMCC4_ENABLE
172 {
173 extern int max_mru;
174#if 0
175 extern int max_chans_used;
176 extern int max_mtu;
177#endif
178 extern int max_rxdesc_used, max_txdesc_used;
179
180 len += sprintf (buffer + len, "\nmax_mru: %d\n", max_mru);
181#if 0
182 len += sprintf (buffer + len, "\nmax_chans_used: %d\n", max_chans_used);
183 len += sprintf (buffer + len, "max_mtu: %d\n", max_mtu);
184#endif
185 len += sprintf (buffer + len, "max_rxdesc_used: %d\n", max_rxdesc_used);
186 len += sprintf (buffer + len, "max_txdesc_used: %d\n", max_txdesc_used);
187 }
188#endif
189
190 OS_kfree (bip); /* cleanup */
191
192 /***
193 * How to be a proc read function
194 * ------------------------------
195 * Prototype:
196 * int f(char *buffer, char **start, off_t offset,
197 * int count, int *peof, void *dat)
198 *
199 * Assume that the buffer is "count" bytes in size.
200 *
201 * If you know you have supplied all the data you
202 * have, set *peof.
203 *
204 * You have three ways to return data:
205 * 0) Leave *start = NULL. (This is the default.)
206 * Put the data of the requested offset at that
207 * offset within the buffer. Return the number (n)
208 * of bytes there are from the beginning of the
209 * buffer up to the last byte of data. If the
210 * number of supplied bytes (= n - offset) is
211 * greater than zero and you didn't signal eof
212 * and the reader is prepared to take more data
213 * you will be called again with the requested
214 * offset advanced by the number of bytes
215 * absorbed. This interface is useful for files
216 * no larger than the buffer.
217 * 1) Set *start = an unsigned long value less than
218 * the buffer address but greater than zero.
219 * Put the data of the requested offset at the
220 * beginning of the buffer. Return the number of
221 * bytes of data placed there. If this number is
222 * greater than zero and you didn't signal eof
223 * and the reader is prepared to take more data
224 * you will be called again with the requested
225 * offset advanced by *start. This interface is
226 * useful when you have a large file consisting
227 * of a series of blocks which you want to count
228 * and return as wholes.
229 * (Hack by Paul.Russell@rustcorp.com.au)
230 * 2) Set *start = an address within the buffer.
231 * Put the data of the requested offset at *start.
232 * Return the number of bytes of data placed there.
233 * If this number is greater than zero and you
234 * didn't signal eof and the reader is prepared to
235 * take more data you will be called again with the
236 * requested offset advanced by the number of bytes
237 * absorbed.
238 */
239
240#if 1
241 /* #4 - intepretation of above = set EOF, return len */
242 *eof = 1;
243#endif
244
245#if 0
246 /*
247 * #1 - from net/wireless/atmel.c RLD NOTE -there's something wrong with
248 * this plagarized code which results in this routine being called TWICE.
249 * The second call returns ZERO, resulting in hidden failure, but at
250 * least only a single message set is being displayed.
251 */
252 if (len <= offset + length)
253 *eof = 1;
254 *start = buffer + offset;
255 len -= offset;
256 if (len > length)
257 len = length;
258 if (len < 0)
259 len = 0;
260#endif
261
262#if 0 /* #2 from net/tokenring/olympic.c +
263 * lanstreamer.c */
264 {
265 off_t begin = 0;
266 int size = 0;
267 off_t pos = 0;
268
269 size = len;
270 pos = begin + size;
271 if (pos < offset)
272 {
273 len = 0;
274 begin = pos;
275 }
276 *start = buffer + (offset - begin); /* Start of wanted data */
277 len -= (offset - begin); /* Start slop */
278 if (len > length)
279 len = length; /* Ending slop */
280 }
281#endif
282
283#if 0 /* #3 from
284 * char/ftape/lowlevel/ftape-proc.c */
285 len = strlen (buffer);
286 *start = NULL;
287 if (offset + length >= len)
288 *eof = 1;
289 else
290 *eof = 0;
291#endif
292
293#if 0
294 printk (">> proc_fs: returned len = %d., start %p\n", len, start); /* RLD DEBUG */
295#endif
296
297/***
298 using NONE: returns = 314.314.314.
299 using #1 : returns = 314, 0.
300 using #2 : returns = 314, 0, 0.
301 using #3 : returns = 314, 314.
302 using #4 : returns = 314, 314.
303***/
304
305 return len;
306}
307
308/* initialize the /proc subsystem for the specific SBE driver */
309
310int __init
311sbecom_proc_brd_init (ci_t * ci)
312{
313 struct proc_dir_entry *e;
314 char dir[7 + SBE_IFACETMPL_SIZE + 1];
315
316 /* create a directory in the root procfs */
317 snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
318 ci->dir_dev = proc_mkdir(dir, NULL);
319 if (!ci->dir_dev)
320 {
321 printk (KERN_ERR "%s: Unable to create directory /proc/driver/%s\n",
322 THIS_MODULE->name, ci->devname);
323 goto fail;
324 }
325 e = create_proc_read_entry ("info", S_IFREG | S_IRUGO,
326 ci->dir_dev, sbecom_proc_get_sbe_info, ci);
327 if (!e)
328 {
329 printk (KERN_ERR "%s: Unable to create entry /proc/driver/%s/info\n",
330 THIS_MODULE->name, ci->devname);
331 goto fail;
332 }
333 return 0;
334
335fail:
336 sbecom_proc_brd_cleanup (ci);
337 return 1;
338}
339
340#else /*** ! CONFIG_PROC_FS ***/
341
342/* stubbed off dummy routines */
343
344void
345sbecom_proc_brd_cleanup (ci_t * ci)
346{
347}
348
349int __init
350sbecom_proc_brd_init (ci_t * ci)
351{
352 return 0;
353}
354
355#endif /*** CONFIG_PROC_FS ***/
356
357
358/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/sbeproc.h b/drivers/staging/cxt1e1/sbeproc.h
new file mode 100644
index 00000000000..4aa53f44ec0
--- /dev/null
+++ b/drivers/staging/cxt1e1/sbeproc.h
@@ -0,0 +1,52 @@
1/*
2 * $Id: sbeproc.h,v 1.2 2005/10/17 23:55:28 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_SBEPROC_H_
6#define _INC_SBEPROC_H_
7
8/*-----------------------------------------------------------------------------
9 * sbeproc.h -
10 *
11 * Copyright (C) 2004-2005 SBE, Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * For further information, contact via email: support@sbei.com
24 * SBE, Inc. San Ramon, California U.S.A.
25 *-----------------------------------------------------------------------------
26 * RCS info:
27 * RCS revision: $Revision: 1.2 $
28 * Last changed on $Date: 2005/10/17 23:55:28 $
29 * Changed by $Author: rickd $
30 *-----------------------------------------------------------------------------
31 * $Log: sbeproc.h,v $
32 * Revision 1.2 2005/10/17 23:55:28 rickd
33 * sbecom_proc_brd_init() is an declared an __init function.
34 *
35 * Revision 1.1 2005/09/28 00:10:09 rickd
36 * Remove unneeded inclusion of c4_private.h.
37 *
38 * Revision 1.0 2005/05/10 22:21:46 rickd
39 * Initial check-in.
40 *
41 *-----------------------------------------------------------------------------
42 */
43
44
45#ifdef CONFIG_PROC_FS
46#ifdef __KERNEL__
47void sbecom_proc_brd_cleanup (ci_t *);
48int __init sbecom_proc_brd_init (ci_t *);
49
50#endif /*** __KERNEL__ ***/
51#endif /*** CONFIG_PROC_FS ***/
52#endif /*** _INC_SBEPROC_H_ ***/
diff --git a/drivers/staging/cxt1e1/sbew_ioc.h b/drivers/staging/cxt1e1/sbew_ioc.h
new file mode 100644
index 00000000000..14d371904d1
--- /dev/null
+++ b/drivers/staging/cxt1e1/sbew_ioc.h
@@ -0,0 +1,136 @@
1/*
2 * $Id: sbew_ioc.h,v 1.0 2005/09/28 00:10:10 rickd PMCC4_3_1B $
3 */
4
5#ifndef _INC_SBEWIOC_H_
6#define _INC_SBEWIOC_H_
7
8/*-----------------------------------------------------------------------------
9 * sbew_ioc.h -
10 *
11 * Copyright (C) 2002-2005 SBE, Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * For further information, contact via email: support@sbei.com
24 * SBE, Inc. San Ramon, California U.S.A.
25 *
26 *-----------------------------------------------------------------------------
27 * RCS info:
28 * RCS revision: $Revision: 1.0 $
29 * Last changed on $Date: 2005/09/28 00:10:10 $
30 * Changed by $Author: rickd $
31 *-----------------------------------------------------------------------------
32 * $Log: sbew_ioc.h,v $
33 * Revision 1.0 2005/09/28 00:10:10 rickd
34 * Initial revision
35 *
36 * Revision 1.6 2005/01/11 18:41:01 rickd
37 * Add BRDADDR_GET Ioctl.
38 *
39 * Revision 1.5 2004/09/16 18:55:59 rickd
40 * Start setting up for generic framer configuration Ioctl by switch
41 * from tect3_framer_param[] to sbecom_framer_param[].
42 *
43 * Revision 1.4 2004/06/28 17:58:15 rickd
44 * Rename IOC_TSMAP_[GS] to IOC_TSIOC_[GS] to support need for
45 * multiple formats of data when setting up TimeSlots.
46 *
47 * Revision 1.3 2004/06/22 21:18:13 rickd
48 * read_vec now() ONLY handles a single common wrt_vec array.
49 *
50 * Revision 1.1 2004/06/10 18:11:34 rickd
51 * Add IID_GET Ioctl reference.
52 *
53 * Revision 1.0 2004/06/08 22:59:38 rickd
54 * Initial revision
55 *
56 * Revision 2.0 2004/06/07 17:49:47 rickd
57 * Initial library release following merge of wanc1t3/wan256 into
58 * common elements for lib.
59 *
60 *-----------------------------------------------------------------------------
61 */
62
63#ifndef __KERNEL__
64#include <sys/types.h>
65#endif
66#ifdef SunOS
67#include <sys/ioccom.h>
68#else
69#include <linux/ioctl.h>
70#endif
71
72#ifdef __cplusplus
73extern "C"
74{
75#endif
76
77#define SBE_LOCKFILE "/tmp/.sbewan.LCK"
78
79#define SBE_IOC_COOKIE 0x19780926
80#define SBE_IOC_MAGIC ('s')
81
82/* IOW write - data has to go into driver from application */
83/* IOR read - data has to be returned to application from driver */
84
85/*
86 * Note: for an IOWR Ioctl, the read and write data do not have to
87 * be the same size, but the entity declared within the IOC must be
88 * the larger of the two.
89 */
90
91#define SBE_IOC_LOGLEVEL _IOW(SBE_IOC_MAGIC, 0x00, int)
92#define SBE_IOC_CHAN_NEW _IOW(SBE_IOC_MAGIC, 0x01,int) /* unused */
93#define SBE_IOC_CHAN_UP _IOW(SBE_IOC_MAGIC, 0x02,int) /* unused */
94#define SBE_IOC_CHAN_DOWN _IOW(SBE_IOC_MAGIC, 0x03,int) /* unused */
95#define SBE_IOC_CHAN_GET _IOWR(SBE_IOC_MAGIC,0x04, struct sbecom_chan_param)
96#define SBE_IOC_CHAN_SET _IOW(SBE_IOC_MAGIC, 0x05, struct sbecom_chan_param)
97#define SBE_IOC_CHAN_GET_STAT _IOWR(SBE_IOC_MAGIC,0x06, struct sbecom_chan_stats)
98#define SBE_IOC_CHAN_DEL_STAT _IOW(SBE_IOC_MAGIC, 0x07, int)
99#define SBE_IOC_PORTS_ENABLE _IOW(SBE_IOC_MAGIC, 0x0A, int)
100#define SBE_IOC_PORT_GET _IOWR(SBE_IOC_MAGIC,0x0C, struct sbecom_port_param)
101#define SBE_IOC_PORT_SET _IOW(SBE_IOC_MAGIC, 0x0D, struct sbecom_port_param)
102#define SBE_IOC_READ_VEC _IOWR(SBE_IOC_MAGIC,0x10, struct sbecom_wrt_vec)
103#define SBE_IOC_WRITE_VEC _IOWR(SBE_IOC_MAGIC,0x11, struct sbecom_wrt_vec)
104#define SBE_IOC_GET_SN _IOR(SBE_IOC_MAGIC, 0x12, u_int32_t)
105#define SBE_IOC_RESET_DEV _IOW(SBE_IOC_MAGIC, 0x13, int)
106#define SBE_IOC_FRAMER_GET _IOWR(SBE_IOC_MAGIC,0x14, struct sbecom_framer_param)
107#define SBE_IOC_FRAMER_SET _IOW(SBE_IOC_MAGIC, 0x15, struct sbecom_framer_param)
108#define SBE_IOC_CARD_GET _IOR(SBE_IOC_MAGIC, 0x20, struct sbecom_card_param)
109#define SBE_IOC_CARD_SET _IOW(SBE_IOC_MAGIC, 0x21, struct sbecom_card_param)
110#define SBE_IOC_CARD_GET_STAT _IOR(SBE_IOC_MAGIC, 0x22, struct temux_card_stats)
111#define SBE_IOC_CARD_DEL_STAT _IO(SBE_IOC_MAGIC, 0x23)
112#define SBE_IOC_CARD_CHAN_STAT _IOR(SBE_IOC_MAGIC, 0x24, struct sbecom_chan_stats)
113#define SBE_IOC_CARD_BLINK _IOW(SBE_IOC_MAGIC, 0x30, int)
114#define SBE_IOC_DRVINFO_GET _IOWR(SBE_IOC_MAGIC,0x31, struct sbe_drv_info)
115#define SBE_IOC_BRDINFO_GET _IOR(SBE_IOC_MAGIC, 0x32, struct sbe_brd_info)
116#define SBE_IOC_IID_GET _IOWR(SBE_IOC_MAGIC,0x33, struct sbe_iid_info)
117#define SBE_IOC_BRDADDR_GET _IOWR(SBE_IOC_MAGIC, 0x34, struct sbe_brd_addr)
118
119#ifdef NOT_YET_COMMON
120#define SBE_IOC_TSIOC_GET _IOWR(SBE_IOC_MAGIC,0x16, struct wanc1t3_ts_param)
121#define SBE_IOC_TSIOC_SET _IOW(SBE_IOC_MAGIC, 0x17, struct wanc1t3_ts_param)
122#endif
123
124/*
125 * Restrict SBE_IOC_WRITE_VEC & READ_VEC to a single parameter pair, application
126 * then must issue multiple Ioctls for large blocks of contiguous data.
127 */
128
129#define SBE_IOC_MAXVEC 1
130
131
132#ifdef __cplusplus
133}
134#endif
135
136#endif /*** _INC_SBEWIOC_H_ ***/