diff options
author | Bob Beers <bob.beers@gmail.com> | 2010-03-04 08:40:46 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-11 14:35:31 -0400 |
commit | 50ee11fe383255db8e5c3307319d470015616f27 (patch) | |
tree | d6900a217a10602d53199d360487548650e100e2 | |
parent | 588063a10f4e21cd3a2cc693c0c1ebb846ac4ce5 (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>
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 | ||
140 | source "drivers/staging/crystalhd/Kconfig" | 140 | source "drivers/staging/crystalhd/Kconfig" |
141 | 141 | ||
142 | source "drivers/staging/cxt1e1/Kconfig" | ||
143 | |||
142 | endif # !STAGING_EXCLUDE_BUILD | 144 | endif # !STAGING_EXCLUDE_BUILD |
143 | endif # STAGING | 145 | endif # 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/ | |||
51 | obj-$(CONFIG_FB_SM7XX) += sm7xx/ | 51 | obj-$(CONFIG_FB_SM7XX) += sm7xx/ |
52 | obj-$(CONFIG_DT3155) += dt3155/ | 52 | obj-$(CONFIG_DT3155) += dt3155/ |
53 | obj-$(CONFIG_CRYSTALHD) += crystalhd/ | 53 | obj-$(CONFIG_CRYSTALHD) += crystalhd/ |
54 | obj-$(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 @@ | |||
1 | config 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 | |||
15 | config 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 @@ | |||
1 | obj-$(CONFIG_CXT1E1) += cxt1e1.o | ||
2 | |||
3 | EXTRA_CFLAGS += -DSBE_PMCC4_ENABLE | ||
4 | EXTRA_CFLAGS += -DSBE_ISR_TASKLET | ||
5 | EXTRA_CFLAGS += -DSBE_INCLUDE_SYMBOLS | ||
6 | |||
7 | cxt1e1-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 | |||
30 | extern 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 */ | ||
36 | STATIC void SetPwrLevel (comet_t * comet); | ||
37 | STATIC void WrtRcvEqualizerTbl (ci_t * ci, comet_t * comet, u_int32_t *table); | ||
38 | STATIC void WrtXmtWaveformTbl (ci_t * ci, comet_t * comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]); | ||
39 | |||
40 | |||
41 | void *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 | |||
50 | static int | ||
51 | lbo_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 | |||
65 | void | ||
66 | init_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 | */ | ||
382 | STATIC void | ||
383 | WrtXmtWaveform (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 | */ | ||
400 | STATIC void | ||
401 | WrtXmtWaveformTbl (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 | |||
427 | STATIC void | ||
428 | WrtRcvEqualizerTbl (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 | |||
491 | STATIC void | ||
492 | SetPwrLevel (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 | ||
535 | STATIC void | ||
536 | SetCometOps (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 | |||
50 | struct 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 | |||
346 | typedef 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__ | ||
362 | extern void | ||
363 | init_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 | |||
41 | char 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 | |||
68 | u_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 | |||
98 | u_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 | |||
128 | u_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 | |||
157 | u_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 | |||
186 | u_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 | |||
215 | u_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 | |||
244 | u_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 | |||
273 | u_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 | |||
302 | u_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 | |||
331 | u_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 | |||
360 | u_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 | |||
392 | u_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 | |||
424 | u_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 | |||
493 | u_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 | |||
70 | extern u_int8_t TWVLongHaul0DB[25][5]; /* T1 Long Haul 0 DB */ | ||
71 | extern u_int8_t TWVLongHaul7_5DB[25][5]; /* T1 Long Haul 7.5 DB */ | ||
72 | extern u_int8_t TWVLongHaul15DB[25][5]; /* T1 Long Haul 15 DB */ | ||
73 | extern u_int8_t TWVLongHaul22_5DB[25][5]; /* T1 Long Haul 22.5 DB */ | ||
74 | extern u_int8_t TWVShortHaul0[25][5]; /* T1 Short Haul 0-110 ft */ | ||
75 | extern u_int8_t TWVShortHaul1[25][5]; /* T1 Short Haul 110-220 ft */ | ||
76 | extern u_int8_t TWVShortHaul2[25][5]; /* T1 Short Haul 220-330 ft */ | ||
77 | extern u_int8_t TWVShortHaul3[25][5]; /* T1 Short Haul 330-440 ft */ | ||
78 | extern u_int8_t TWVShortHaul4[25][5]; /* T1 Short Haul 440-550 ft */ | ||
79 | extern u_int8_t TWVShortHaul5[25][5]; /* T1 Short Haul 550-660 ft */ | ||
80 | extern u_int8_t TWV_E1_75Ohm[25][5]; /* E1 75 Ohm */ | ||
81 | extern u_int8_t TWV_E1_120Ohm[25][5]; /* E1 120 Ohm */ | ||
82 | extern u_int32_t T1_Equalizer[256]; /* T1 Receiver Equalizer */ | ||
83 | extern 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) | ||
41 | extern int hdlc_netif_rx_v7 (hdlc_device *, struct sk_buff *); | ||
42 | extern int register_hdlc_device_v7 (hdlc_device *); | ||
43 | extern 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 | ||
51 | static int dummy = 0; | ||
52 | |||
53 | #endif | ||
54 | |||
55 | extern int log_level; | ||
56 | extern int drvr_state; | ||
57 | |||
58 | |||
59 | #if 1 | ||
60 | u_int32_t | ||
61 | pci_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 | |||
77 | void | ||
78 | pci_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 | |||
97 | void | ||
98 | pci_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 | |||
112 | STATIC void | ||
113 | watchdog_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 | |||
139 | int 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 | |||
155 | void | ||
156 | OS_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 | |||
180 | void | ||
181 | OS_uwait_dummy (void) | ||
182 | { | ||
183 | #ifndef USE_MAX_INT_DELAY | ||
184 | dummy++; | ||
185 | #else | ||
186 | udelay (1); | ||
187 | #endif | ||
188 | } | ||
189 | |||
190 | |||
191 | void | ||
192 | OS_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 | |||
210 | int | ||
211 | sd_line_is_ok (void *user) | ||
212 | { | ||
213 | struct net_device *ndev = (struct net_device *) user; | ||
214 | |||
215 | return (netif_carrier_ok (ndev)); | ||
216 | } | ||
217 | |||
218 | void | ||
219 | sd_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 | |||
227 | void | ||
228 | sd_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 | |||
236 | void | ||
237 | sd_disable_xmit (void *user) | ||
238 | { | ||
239 | struct net_device *dev = (struct net_device *) user; | ||
240 | |||
241 | netif_stop_queue (dev); | ||
242 | return; | ||
243 | } | ||
244 | |||
245 | void | ||
246 | sd_enable_xmit (void *user) | ||
247 | { | ||
248 | struct net_device *dev = (struct net_device *) user; | ||
249 | |||
250 | netif_wake_queue (dev); | ||
251 | return; | ||
252 | } | ||
253 | |||
254 | int | ||
255 | sd_queue_stopped (void *user) | ||
256 | { | ||
257 | struct net_device *ndev = (struct net_device *) user; | ||
258 | |||
259 | return (netif_queue_stopped (ndev)); | ||
260 | } | ||
261 | |||
262 | void 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 | |||
281 | extern ci_t *CI; /* dummy pointer to board ZERO's data */ | ||
282 | void | ||
283 | VMETRO_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 | |||
291 | void | ||
292 | VMETRO_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 | |||
38 | extern int log_level; | ||
39 | extern int error_flag; | ||
40 | extern int drvr_state; | ||
41 | |||
42 | /* forward references */ | ||
43 | void c4_stopwd (ci_t *); | ||
44 | struct net_device * __init c4_add_dev (hdw_info_t *, int, unsigned long, unsigned long, int, int); | ||
45 | |||
46 | |||
47 | struct s_hdw_info hdw_info[MAX_BOARDS]; | ||
48 | |||
49 | |||
50 | void __init | ||
51 | show_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 | |||
102 | void __init | ||
103 | hdw_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 | |||
152 | void __init | ||
153 | prep_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 | |||
172 | void | ||
173 | cleanup_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 | |||
198 | void | ||
199 | cleanup_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 | |||
222 | STATIC int __init | ||
223 | c4_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 | |||
297 | status_t __init | ||
298 | c4hw_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 | ||
50 | extern "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 | |||
227 | struct 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 */ | ||
62 | status_t c4_chan_work_init (mpi_t *, mch_t *); | ||
63 | void musycc_wq_chan_restart (void *); | ||
64 | status_t __init c4_init (ci_t *, u_char *, u_char *); | ||
65 | status_t __init c4_init2 (ci_t *); | ||
66 | ci_t *__init c4_new (void *); | ||
67 | int __init c4hw_attach_all (void); | ||
68 | void __init hdw_sn_get (hdw_info_t *, int); | ||
69 | |||
70 | #ifdef CONFIG_SBE_PMCC4_NCOMM | ||
71 | irqreturn_t c4_ebus_intr_th_handler (void *); | ||
72 | |||
73 | #endif | ||
74 | int c4_frame_rw (ci_t *, struct sbecom_port_param *); | ||
75 | status_t c4_get_port (ci_t *, int); | ||
76 | int c4_loop_port (ci_t *, int, u_int8_t); | ||
77 | int c4_musycc_rw (ci_t *, struct c4_musycc_param *); | ||
78 | int c4_new_chan (ci_t *, int, int, void *); | ||
79 | status_t c4_set_port (ci_t *, int); | ||
80 | int c4_pld_rw (ci_t *, struct sbecom_port_param *); | ||
81 | void cleanup_devs (void); | ||
82 | void cleanup_ioremap (void); | ||
83 | status_t musycc_chan_down (ci_t *, int); | ||
84 | irqreturn_t musycc_intr_th_handler (void *); | ||
85 | int musycc_start_xmit (ci_t *, int, void *); | ||
86 | |||
87 | extern char pmcc4_OSSI_release[]; | ||
88 | extern ci_t *CI; | ||
89 | extern 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) | ||
100 | extern int hdlc_netif_rx_v7 (hdlc_device *, struct sk_buff *); | ||
101 | extern int register_hdlc_device_v7 (hdlc_device *); | ||
102 | extern int unregister_hdlc_device_v7 (hdlc_device *); | ||
103 | |||
104 | #else | ||
105 | #define V7(x) x | ||
106 | #endif | ||
107 | |||
108 | int error_flag; /* module load error reporting */ | ||
109 | int log_level = LOG_ERROR; | ||
110 | int log_level_default = LOG_ERROR; | ||
111 | module_param(log_level, int, 0444); | ||
112 | |||
113 | int max_mru = MUSYCC_MRU; | ||
114 | int max_mru_default = MUSYCC_MRU; | ||
115 | module_param(max_mru, int, 0444); | ||
116 | |||
117 | int max_mtu = MUSYCC_MTU; | ||
118 | int max_mtu_default = MUSYCC_MTU; | ||
119 | module_param(max_mtu, int, 0444); | ||
120 | |||
121 | int max_txdesc_used = MUSYCC_TXDESC_MIN; | ||
122 | int max_txdesc_default = MUSYCC_TXDESC_MIN; | ||
123 | module_param(max_txdesc_used, int, 0444); | ||
124 | |||
125 | int max_rxdesc_used = MUSYCC_RXDESC_MIN; | ||
126 | int max_rxdesc_default = MUSYCC_RXDESC_MIN; | ||
127 | module_param(max_rxdesc_used, int, 0444); | ||
128 | |||
129 | /****************************************************************************/ | ||
130 | /****************************************************************************/ | ||
131 | /****************************************************************************/ | ||
132 | |||
133 | void * | ||
134 | getuserbychan (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 | |||
147 | char * | ||
148 | get_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 | |||
158 | static status_t | ||
159 | mkret (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 | */ | ||
190 | void | ||
191 | c4_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 | |||
207 | status_t | ||
208 | c4_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 | |||
222 | status_t | ||
223 | c4_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 | |||
244 | void | ||
245 | c4_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 | |||
262 | irqreturn_t | ||
263 | c4_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 | ||
272 | irqreturn_t | ||
273 | c4_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 | |||
282 | static int | ||
283 | void_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 **/ | ||
294 | STATIC int | ||
295 | chan_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 **/ | ||
309 | STATIC int | ||
310 | chan_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 **/ | ||
332 | STATIC int | ||
333 | chan_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 **/ | ||
357 | STATIC void | ||
358 | chan_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 **/ | ||
367 | STATIC int | ||
368 | chan_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 **/ | ||
383 | STATIC int | ||
384 | chan_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 **/ | ||
401 | STATIC int | ||
402 | chan_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) | ||
415 | STATIC int | ||
416 | chan_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 | ||
426 | STATIC int | ||
427 | chan_dev_ioctl (struct net_device * dev, struct ifreq * ifr, int cmd) | ||
428 | { | ||
429 | return hdlc_ioctl (dev, ifr, cmd); | ||
430 | } | ||
431 | |||
432 | |||
433 | STATIC int | ||
434 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
435 | chan_attach_noop (hdlc_device * hdlc, unsigned short foo_1, unsigned short foo_2) | ||
436 | #else | ||
437 | chan_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 | |||
446 | STATIC struct net_device_stats * | ||
447 | chan_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 | |||
503 | static ci_t * | ||
504 | get_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) | ||
511 | STATIC int | ||
512 | c4_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 */ | ||
520 | STATIC int | ||
521 | c4_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 | |||
539 | static 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 | |||
547 | STATIC struct net_device * | ||
548 | create_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) */ | ||
640 | STATIC status_t | ||
641 | do_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 */ | ||
665 | STATIC status_t | ||
666 | do_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 */ | ||
687 | STATIC status_t | ||
688 | do_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 */ | ||
702 | STATIC status_t | ||
703 | do_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 */ | ||
723 | STATIC status_t | ||
724 | do_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 */ | ||
744 | STATIC status_t | ||
745 | do_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 | |||
764 | STATIC status_t | ||
765 | do_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 | |||
782 | STATIC status_t | ||
783 | do_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 | |||
803 | STATIC status_t | ||
804 | do_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 | |||
838 | STATIC status_t | ||
839 | do_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 | } | ||
859 | STATIC status_t | ||
860 | do_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 | |||
870 | STATIC status_t | ||
871 | do_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 | |||
915 | int | ||
916 | do_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 | } | ||
935 | int c4_reset_board (void *); | ||
936 | |||
937 | int | ||
938 | do_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 | |||
966 | int | ||
967 | do_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 | |||
977 | STATIC status_t | ||
978 | c4_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 | |||
1092 | static 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 | |||
1098 | static void c4_setup(struct net_device *dev) | ||
1099 | { | ||
1100 | dev->type = ARPHRD_VOID; | ||
1101 | dev->netdev_ops = &c4_ops; | ||
1102 | } | ||
1103 | |||
1104 | struct net_device *__init | ||
1105 | c4_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 | |||
1261 | STATIC int __init | ||
1262 | c4_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 | |||
1303 | STATIC void __exit | ||
1304 | cleanup_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 | |||
1327 | STATIC void __exit | ||
1328 | c4_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 | |||
1337 | module_init (c4_mod_init); | ||
1338 | module_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) | ||
1343 | EXPORT_NO_SYMBOLS; | ||
1344 | #endif | ||
1345 | #endif | ||
1346 | #endif | ||
1347 | |||
1348 | MODULE_AUTHOR ("SBE Technical Services <support@sbei.com>"); | ||
1349 | MODULE_DESCRIPTION ("wanPCI-CxT1E1 Generic HDLC WAN Driver module"); | ||
1350 | #ifdef MODULE_LICENSE | ||
1351 | MODULE_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 | |||
5 | unsigned int max_intcnt = 0; | ||
6 | unsigned 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 | |||
71 | char 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 */ | ||
97 | extern ci_t *c4_list; | ||
98 | extern int drvr_state; | ||
99 | extern int log_level; | ||
100 | |||
101 | extern int max_mru; | ||
102 | extern int max_mtu; | ||
103 | extern int max_rxdesc_used; | ||
104 | extern int max_txdesc_used; | ||
105 | extern ci_t *CI; /* dummy pointr to board ZEROE's data - DEBUG | ||
106 | * USAGE */ | ||
107 | |||
108 | |||
109 | /*******************************************************************/ | ||
110 | /* forward references */ | ||
111 | void c4_fifo_free (mpi_t *, int); | ||
112 | void c4_wk_chan_restart (mch_t *); | ||
113 | void musycc_bh_tx_eom (mpi_t *, int); | ||
114 | int musycc_chan_up (ci_t *, int); | ||
115 | status_t __init musycc_init (ci_t *); | ||
116 | STATIC void __init musycc_init_port (mpi_t *); | ||
117 | void musycc_intr_bh_tasklet (ci_t *); | ||
118 | void musycc_serv_req (mpi_t *, u_int32_t); | ||
119 | void musycc_update_timeslots (mpi_t *); | ||
120 | |||
121 | /*******************************************************************/ | ||
122 | |||
123 | #if 1 | ||
124 | STATIC int | ||
125 | musycc_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 | ||
197 | STATIC int | ||
198 | musycc_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 | |||
270 | status_t | ||
271 | musycc_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 | |||
316 | status_t | ||
317 | musycc_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 | |||
332 | void | ||
333 | musycc_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 | |||
358 | void | ||
359 | musycc_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 | |||
417 | void | ||
418 | musycc_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 | |||
525 | void | ||
526 | musycc_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 | ||
555 | void | ||
556 | musycc_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 | |||
586 | void | ||
587 | rld_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 | |||
602 | void | ||
603 | musycc_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; | ||
656 | rewrite: | ||
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 | ||
710 | void | ||
711 | musycc_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 | ||
780 | void | ||
781 | musycc_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 | */ | ||
818 | u_int32_t | ||
819 | musycc_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 | ||
845 | STATIC void __init | ||
846 | musycc_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 | |||
879 | status_t __init | ||
880 | musycc_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 | |||
981 | void | ||
982 | musycc_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 | |||
1170 | STATIC void | ||
1171 | musycc_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 | |||
1260 | irqreturn_t | ||
1261 | musycc_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) | ||
1408 | unsigned long | ||
1409 | #else | ||
1410 | void | ||
1411 | #endif | ||
1412 | musycc_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 | ||
1725 | int __init | ||
1726 | musycc_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 | ||
1754 | status_t | ||
1755 | musycc_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 | |||
1809 | int | ||
1810 | musycc_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 | |||
1825 | int | ||
1826 | musycc_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 | |||
1840 | int | ||
1841 | musycc_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 | ||
2046 | int | ||
2047 | musycc_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 | |||
2099 | int | ||
2100 | musycc_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 | |||
2115 | int | ||
2116 | musycc_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 | ||
2132 | int | ||
2133 | musycc_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 | ||
53 | extern "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 | |||
37 | char 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 | |||
89 | static unsigned char ByteReverse[256]; | ||
90 | static int ByteReverseBuilt = FALSE; | ||
91 | |||
92 | |||
93 | /*------------------------------------------------------------------------ | ||
94 | * mfg_template - initial serial EEPROM data structure | ||
95 | *------------------------------------------------------------------------ | ||
96 | */ | ||
97 | |||
98 | short 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 | |||
121 | STATIC void | ||
122 | BuildByteReverse (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 | |||
142 | STATIC void | ||
143 | eeprom_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 | |||
162 | void | ||
163 | eeprom_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 | |||
187 | u_int32_t | ||
188 | eeprom_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 | |||
225 | STATIC void | ||
226 | disable_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 | |||
242 | STATIC void | ||
243 | enable_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 | |||
260 | u_int32_t | ||
261 | pmc_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 | |||
300 | int | ||
301 | pmc_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 | |||
368 | long | ||
369 | pmcGetBuffValue (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 | |||
389 | void | ||
390 | pmcSetBuffValue (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 | |||
407 | void | ||
408 | pmc_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 | |||
420 | void | ||
421 | pmc_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 | |||
437 | u_int32_t | ||
438 | pmcCalcCrc_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 | |||
456 | u_int32_t | ||
457 | pmcCalcCrc_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 | |||
493 | void | ||
494 | pmc_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 | |||
531 | char | ||
532 | pmc_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 | |||
51 | void pmc_eeprom_read_buffer (long, long, char *, int); | ||
52 | void pmc_eeprom_write_buffer (long, long, char *, int); | ||
53 | void pmc_init_seeprom (u_int32_t, u_int32_t); | ||
54 | char 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 | |||
58 | typedef int status_t; | ||
59 | |||
60 | #define SBE_DRVR_FAIL 0 | ||
61 | #define SBE_DRVR_SUCCESS 1 | ||
62 | |||
63 | #ifdef __cplusplus | ||
64 | extern "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)) | ||
121 | char *get_hdlc_name (hdlc_device *); | ||
122 | |||
123 | #endif | ||
124 | |||
125 | |||
126 | /* | ||
127 | * external interface | ||
128 | */ | ||
129 | |||
130 | void c4_cleanup (void); | ||
131 | status_t c4_chan_up (ci_t *, int channum); | ||
132 | status_t c4_del_chan_stats (int channum); | ||
133 | status_t c4_del_chan (int channum); | ||
134 | status_t c4_get_iidinfo (ci_t * ci, struct sbe_iid_info * iip); | ||
135 | int c4_is_chan_up (int channum); | ||
136 | |||
137 | void *getuserbychan (int channum); | ||
138 | void pci_flush_write (ci_t * ci); | ||
139 | void sbecom_set_loglevel (int debuglevel); | ||
140 | char *sbeid_get_bdname (ci_t * ci); | ||
141 | void sbeid_set_bdtype (ci_t * ci); | ||
142 | void sbeid_set_hdwbid (ci_t * ci); | ||
143 | u_int32_t sbeCrc (u_int8_t *, u_int32_t, u_int32_t, u_int32_t *); | ||
144 | |||
145 | void VMETRO_TRACE (void *); /* put data into 8 LEDs */ | ||
146 | void VMETRO_TRIGGER (ci_t *, int); /* Note: int = 0(default) | ||
147 | * thru 15 */ | ||
148 | |||
149 | #if defined (SBE_ISR_TASKLET) | ||
150 | void 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 | ||
50 | extern "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 | |||
83 | char 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) | ||
122 | status_t c4_wk_chan_init (mpi_t *, mch_t *); | ||
123 | void c4_wq_port_cleanup (mpi_t *); | ||
124 | status_t c4_wq_port_init (mpi_t *); | ||
125 | |||
126 | #endif | ||
127 | int c4_loop_port (ci_t *, int, u_int8_t); | ||
128 | status_t c4_set_port (ci_t *, int); | ||
129 | status_t musycc_chan_down (ci_t *, int); | ||
130 | |||
131 | u_int32_t musycc_chan_proto (int); | ||
132 | status_t musycc_dump_ring (ci_t *, unsigned int); | ||
133 | status_t __init musycc_init (ci_t *); | ||
134 | void musycc_init_mdt (mpi_t *); | ||
135 | void musycc_serv_req (mpi_t *, u_int32_t); | ||
136 | void musycc_update_timeslots (mpi_t *); | ||
137 | |||
138 | extern void musycc_update_tx_thp (mch_t *); | ||
139 | extern int log_level; | ||
140 | extern int max_mru; | ||
141 | extern int max_mtu; | ||
142 | extern int max_rxdesc_used, max_rxdesc_default; | ||
143 | extern int max_txdesc_used, max_txdesc_default; | ||
144 | |||
145 | #if defined (__powerpc__) | ||
146 | extern void *memset (void *s, int c, size_t n); | ||
147 | |||
148 | #endif | ||
149 | |||
150 | int drvr_state = SBE_DRVR_INIT; | ||
151 | ci_t *c4_list = 0; | ||
152 | ci_t *CI; /* dummy pointer to board ZEROE's data - | ||
153 | * DEBUG USAGE */ | ||
154 | |||
155 | |||
156 | void | ||
157 | sbecom_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 | |||
182 | mch_t * | ||
183 | c4_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 | |||
204 | ci_t *__init | ||
205 | c4_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 | |||
266 | void | ||
267 | checkPorts (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 | |||
538 | STATIC void | ||
539 | c4_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 | |||
679 | void | ||
680 | c4_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 | |||
723 | int | ||
724 | c4_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 | |||
747 | status_t __init | ||
748 | c4_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 | |||
879 | status_t __init | ||
880 | c4_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 | |||
907 | int | ||
908 | c4_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 | |||
965 | status_t | ||
966 | c4_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 | |||
1004 | status_t | ||
1005 | c4_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 | |||
1042 | status_t | ||
1043 | c4_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 | |||
1106 | status_t | ||
1107 | c4_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 | |||
1121 | status_t | ||
1122 | c4_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 | |||
1226 | unsigned int max_int = 0; | ||
1227 | |||
1228 | status_t | ||
1229 | c4_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 | |||
1294 | status_t | ||
1295 | c4_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 | |||
1310 | status_t | ||
1311 | c4_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 | |||
1323 | status_t | ||
1324 | c4_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 | |||
1374 | status_t | ||
1375 | c4_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 | |||
1385 | status_t | ||
1386 | c4_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 | |||
1397 | STATIC int | ||
1398 | c4_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 | |||
1435 | void | ||
1436 | c4_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 | |||
1449 | status_t | ||
1450 | c4_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 | |||
1657 | errfree: | ||
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 | |||
1676 | void | ||
1677 | c4_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 | |||
1685 | void | ||
1686 | sbecom_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 | |||
1752 | status_t | ||
1753 | c4_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 | ||
1772 | void (*nciInterrupt[MAX_BOARDS][4]) (void); | ||
1773 | extern void wanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler); | ||
1774 | |||
1775 | void | ||
1776 | wanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler) | ||
1777 | { | ||
1778 | if (cardID < MAX_BOARDS) /* sanity check */ | ||
1779 | nciInterrupt[cardID][deviceID] = handler; | ||
1780 | } | ||
1781 | |||
1782 | irqreturn_t | ||
1783 | c4_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 | |||
1832 | unsigned long | ||
1833 | wanpmcC4T1E1_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 | |||
42 | enum | ||
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 | |||
75 | struct 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 | |||
47 | struct 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 | |||
61 | struct 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 | }; | ||
125 | typedef struct c4_chan_info mch_t; | ||
126 | |||
127 | struct 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 | }; | ||
164 | typedef 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 | |||
178 | struct 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 | }; | ||
246 | typedef struct sbe_card_info ci_t; | ||
247 | |||
248 | struct 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 | }; | ||
275 | typedef struct s_hdw_info hdw_info_t; | ||
276 | |||
277 | /*****************************************************************/ | ||
278 | |||
279 | struct c4_priv | ||
280 | { | ||
281 | int channum; | ||
282 | struct sbe_card_info *ci; | ||
283 | }; | ||
284 | |||
285 | |||
286 | /*****************************************************************/ | ||
287 | |||
288 | extern ci_t *c4_list; | ||
289 | |||
290 | mch_t *c4_find_chan (int); | ||
291 | int c4_set_chan (int channum, struct sbecom_chan_param *); | ||
292 | int c4_get_chan (int channum, struct sbecom_chan_param *); | ||
293 | int 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 | |||
53 | void sd_recv_consume(void *token, size_t len, void *user); | ||
54 | |||
55 | void sd_disable_xmit (void *user); | ||
56 | void sd_enable_xmit (void *user); | ||
57 | int sd_line_is_ok (void *user); | ||
58 | void sd_line_is_up (void *user); | ||
59 | void sd_line_is_down (void *user); | ||
60 | int 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 | ||
89 | extern "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 | |||
88 | static inline u_int32_t | ||
89 | pci_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 | |||
105 | static inline void | ||
106 | pci_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 */ | ||
124 | u_int32_t pci_read_32 (u_int32_t *p); | ||
125 | void 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 | |||
138 | static inline void * | ||
139 | OS_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 | |||
148 | static inline void | ||
149 | OS_kfree (void *x) | ||
150 | { | ||
151 | kfree (x); | ||
152 | } | ||
153 | |||
154 | |||
155 | /****************/ | ||
156 | /* memory token */ | ||
157 | /****************/ | ||
158 | |||
159 | static inline void * | ||
160 | OS_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 | |||
174 | static inline void | ||
175 | OS_mem_token_free (void *token) | ||
176 | { | ||
177 | dev_kfree_skb_any (token); | ||
178 | } | ||
179 | |||
180 | |||
181 | static inline void | ||
182 | OS_mem_token_free_irq (void *token) | ||
183 | { | ||
184 | dev_kfree_skb_irq (token); | ||
185 | } | ||
186 | |||
187 | |||
188 | static inline void * | ||
189 | OS_mem_token_data (void *token) | ||
190 | { | ||
191 | return ((struct sk_buff *) token)->data; | ||
192 | } | ||
193 | |||
194 | |||
195 | static inline void * | ||
196 | OS_mem_token_next (void *token) | ||
197 | { | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | |||
202 | static inline int | ||
203 | OS_mem_token_len (void *token) | ||
204 | { | ||
205 | return ((struct sk_buff *) token)->len; | ||
206 | } | ||
207 | |||
208 | |||
209 | static inline int | ||
210 | OS_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 | |||
220 | static inline u_long | ||
221 | OS_phystov (void *addr) | ||
222 | { | ||
223 | return (u_long) __va (addr); | ||
224 | } | ||
225 | |||
226 | |||
227 | static inline u_long | ||
228 | OS_vtophys (void *addr) | ||
229 | { | ||
230 | return __pa (addr); | ||
231 | } | ||
232 | |||
233 | |||
234 | /**********/ | ||
235 | /* semops */ | ||
236 | /**********/ | ||
237 | |||
238 | void OS_sem_init (void *, int); | ||
239 | |||
240 | |||
241 | static inline void | ||
242 | OS_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 | |||
260 | struct 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 | |||
275 | static inline int | ||
276 | OS_start_watchdog (struct watchdog * wd) | ||
277 | { | ||
278 | wd->h.expires = jiffies + wd->ticks; | ||
279 | add_timer (&wd->h); | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | |||
284 | static inline int | ||
285 | OS_stop_watchdog (struct watchdog * wd) | ||
286 | { | ||
287 | del_timer_sync (&wd->h); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | |||
292 | static inline int | ||
293 | OS_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 */ | ||
302 | void OS_uwait (int usec, char *description); | ||
303 | void OS_uwait_dummy (void); | ||
304 | |||
305 | |||
306 | /* watchdog functions */ | ||
307 | int 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 | |||
29 | static u_int32_t crcTableInit; | ||
30 | |||
31 | #ifdef STATIC_CRC_TABLE | ||
32 | static 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 | |||
46 | static void | ||
47 | genCrcTable (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 | |||
87 | void | ||
88 | sbeCrc (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 | |||
29 | char * | ||
30 | sbeid_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 | |||
75 | void | ||
76 | sbeid_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 | |||
172 | void | ||
173 | sbeid_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 */ | ||
28 | void sbecom_get_brdinfo (ci_t *, struct sbe_brd_info *, u_int8_t *); | ||
29 | extern struct s_hdw_info hdw_info[MAX_BOARDS]; | ||
30 | |||
31 | #ifdef CONFIG_PROC_FS | ||
32 | |||
33 | /********************************************************************/ | ||
34 | /* procfs stuff */ | ||
35 | /********************************************************************/ | ||
36 | |||
37 | |||
38 | void | ||
39 | sbecom_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 | |||
52 | static int | ||
53 | sbecom_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 | |||
310 | int __init | ||
311 | sbecom_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 | |||
335 | fail: | ||
336 | sbecom_proc_brd_cleanup (ci); | ||
337 | return 1; | ||
338 | } | ||
339 | |||
340 | #else /*** ! CONFIG_PROC_FS ***/ | ||
341 | |||
342 | /* stubbed off dummy routines */ | ||
343 | |||
344 | void | ||
345 | sbecom_proc_brd_cleanup (ci_t * ci) | ||
346 | { | ||
347 | } | ||
348 | |||
349 | int __init | ||
350 | sbecom_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__ | ||
47 | void sbecom_proc_brd_cleanup (ci_t *); | ||
48 | int __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 | ||
73 | extern "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_ ***/ | ||