Commit 921a86e0e306e42452e16894f2cc792659ede16b
Committed by
Greg Kroah-Hartman
1 parent
b0b5763308
Exists in
master
and in
7 other branches
Staging: Add SBE 2T3E3 WAN driver
This is a driver for SBE Inc.'s dual port T3/E3 WAN cards. Based on their original GPLed driver. The original driver tarball is now accessible at http://userweb.kernel.org/~chris/SBE_2T3_Linux_2.0c.tgz It needs at least a new generic HDLC setup code (not yet written) before moving to drivers/net/wan. Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Showing 18 changed files with 4294 additions and 0 deletions Side-by-side Diff
- drivers/staging/Kconfig
- drivers/staging/Makefile
- drivers/staging/sbe-2t3e3/2t3e3.h
- drivers/staging/sbe-2t3e3/Kconfig
- drivers/staging/sbe-2t3e3/Makefile
- drivers/staging/sbe-2t3e3/TODO
- drivers/staging/sbe-2t3e3/cpld.c
- drivers/staging/sbe-2t3e3/ctrl.c
- drivers/staging/sbe-2t3e3/ctrl.h
- drivers/staging/sbe-2t3e3/dc.c
- drivers/staging/sbe-2t3e3/exar7250.c
- drivers/staging/sbe-2t3e3/exar7300.c
- drivers/staging/sbe-2t3e3/intr.c
- drivers/staging/sbe-2t3e3/io.c
- drivers/staging/sbe-2t3e3/main.c
- drivers/staging/sbe-2t3e3/maps.c
- drivers/staging/sbe-2t3e3/module.c
- drivers/staging/sbe-2t3e3/netdev.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/sbe-2t3e3/2t3e3.h
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#ifndef T3E3_H | |
14 | +#define T3E3_H | |
15 | + | |
16 | +#include <linux/hdlc.h> | |
17 | +#include <linux/interrupt.h> | |
18 | +#include <linux/netdevice.h> | |
19 | +#include <linux/pci.h> | |
20 | +#include <linux/io.h> | |
21 | +#include "ctrl.h" | |
22 | + | |
23 | +/************************************************************** | |
24 | + * 21143 | |
25 | + **************************************************************/ | |
26 | + | |
27 | +/* CSR */ | |
28 | +#define SBE_2T3E3_21143_REG_BUS_MODE 0 | |
29 | +#define SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND 1 | |
30 | +#define SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND 2 | |
31 | +#define SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS 3 | |
32 | +#define SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS 4 | |
33 | +#define SBE_2T3E3_21143_REG_STATUS 5 | |
34 | +#define SBE_2T3E3_21143_REG_OPERATION_MODE 6 | |
35 | +#define SBE_2T3E3_21143_REG_INTERRUPT_ENABLE 7 | |
36 | +#define SBE_2T3E3_21143_REG_MISSED_FRAMES_AND_OVERFLOW_COUNTER 8 | |
37 | +#define SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT 9 | |
38 | +#define SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS 10 | |
39 | +#define SBE_2T3E3_21143_REG_GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL 11 | |
40 | +#define SBE_2T3E3_21143_REG_SIA_STATUS 12 | |
41 | +#define SBE_2T3E3_21143_REG_SIA_CONNECTIVITY 13 | |
42 | +#define SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE 14 | |
43 | +#define SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT 15 | |
44 | +#define SBE_2T3E3_21143_REG_MAX 16 | |
45 | + | |
46 | +/* CSR0 - BUS_MODE */ | |
47 | +#define SBE_2T3E3_21143_VAL_WRITE_AND_INVALIDATE_ENABLE 0x01000000 | |
48 | +#define SBE_2T3E3_21143_VAL_READ_LINE_ENABLE 0x00800000 | |
49 | +#define SBE_2T3E3_21143_VAL_READ_MULTIPLE_ENABLE 0x00200000 | |
50 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_200us 0x00020000 | |
51 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_DISABLED 0x00000000 | |
52 | +#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_32 0x0000c000 | |
53 | +#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_16 0x00008000 | |
54 | +#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_8 0x00004000 | |
55 | +#define SBE_2T3E3_21143_VAL_BUS_ARBITRATION_RR 0x00000002 | |
56 | +#define SBE_2T3E3_21143_VAL_SOFTWARE_RESET 0x00000001 | |
57 | + | |
58 | +/* CSR5 - STATUS */ | |
59 | +#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_PORT_INTERRUPT 0x04000000 | |
60 | +#define SBE_2T3E3_21143_VAL_ERROR_BITS 0x03800000 | |
61 | +#define SBE_2T3E3_21143_VAL_PARITY_ERROR 0x00000000 | |
62 | +#define SBE_2T3E3_21143_VAL_MASTER_ABORT 0x00800000 | |
63 | +#define SBE_2T3E3_21143_VAL_TARGET_ABORT 0x01000000 | |
64 | +#define SBE_2T3E3_21143_VAL_TRANSMISSION_PROCESS_STATE 0x00700000 | |
65 | +#define SBE_2T3E3_21143_VAL_TX_STOPPED 0x00000000 | |
66 | +#define SBE_2T3E3_21143_VAL_TX_SUSPENDED 0x00600000 | |
67 | +#define SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STATE 0x000e0000 | |
68 | +#define SBE_2T3E3_21143_VAL_RX_STOPPED 0x00000000 | |
69 | +#define SBE_2T3E3_21143_VAL_RX_SUSPENDED 0x000a0000 | |
70 | +#define SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY 0x00010000 | |
71 | +#define SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY 0x00008000 | |
72 | +#define SBE_2T3E3_21143_VAL_EARLY_RECEIVE_INTERRUPT 0x00004000 | |
73 | +#define SBE_2T3E3_21143_VAL_FATAL_BUS_ERROR 0x00002000 | |
74 | +#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_TIMER_EXPIRED 0x00000800 | |
75 | +#define SBE_2T3E3_21143_VAL_EARLY_TRANSMIT_INTERRUPT 0x00000400 | |
76 | +#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_TIMEOUT 0x00000200 | |
77 | +#define SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED 0x00000100 | |
78 | +#define SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE 0x00000080 | |
79 | +#define SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT 0x00000040 | |
80 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW 0x00000020 | |
81 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_JABBER_TIMEOUT 0x00000008 | |
82 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE 0x00000004 | |
83 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED 0x00000002 | |
84 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT 0x00000001 | |
85 | + | |
86 | +/* CSR6 - OPERATION_MODE */ | |
87 | +#define SBE_2T3E3_21143_VAL_SPECIAL_CAPTURE_EFFECT_ENABLE 0x80000000 | |
88 | +#define SBE_2T3E3_21143_VAL_RECEIVE_ALL 0x40000000 | |
89 | +#define SBE_2T3E3_21143_VAL_MUST_BE_ONE 0x02000000 | |
90 | +#define SBE_2T3E3_21143_VAL_SCRAMBLER_MODE 0x01000000 | |
91 | +#define SBE_2T3E3_21143_VAL_PCS_FUNCTION 0x00800000 | |
92 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_10Mbs 0x00400000 | |
93 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_100Mbs 0x00000000 | |
94 | +#define SBE_2T3E3_21143_VAL_STORE_AND_FORWARD 0x00200000 | |
95 | +#define SBE_2T3E3_21143_VAL_HEARTBEAT_DISABLE 0x00080000 | |
96 | +#define SBE_2T3E3_21143_VAL_PORT_SELECT 0x00040000 | |
97 | +#define SBE_2T3E3_21143_VAL_CAPTURE_EFFECT_ENABLE 0x00020000 | |
98 | +#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS 0x0000c000 | |
99 | +#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1 0x00000000 | |
100 | +#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2 0x00004000 | |
101 | +#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3 0x00008000 | |
102 | +#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4 0x0000c000 | |
103 | +#define SBE_2T3E3_21143_VAL_TRANSMISSION_START 0x00002000 | |
104 | +#define SBE_2T3E3_21143_VAL_OPERATING_MODE 0x00000c00 | |
105 | +#define SBE_2T3E3_21143_VAL_LOOPBACK_OFF 0x00000000 | |
106 | +#define SBE_2T3E3_21143_VAL_LOOPBACK_EXTERNAL 0x00000800 | |
107 | +#define SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL 0x00000400 | |
108 | +#define SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE 0x00000200 | |
109 | +#define SBE_2T3E3_21143_VAL_PASS_ALL_MULTICAST 0x00000080 | |
110 | +#define SBE_2T3E3_21143_VAL_PROMISCUOUS_MODE 0x00000040 | |
111 | +#define SBE_2T3E3_21143_VAL_PASS_BAD_FRAMES 0x00000008 | |
112 | +#define SBE_2T3E3_21143_VAL_RECEIVE_START 0x00000002 | |
113 | + | |
114 | +/* CSR7 - INTERRUPT_ENABLE */ | |
115 | +#define SBE_2T3E3_21143_VAL_LINK_CHANGED_ENABLE 0x08000000 | |
116 | +#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_PORT_ENABLE 0x04000000 | |
117 | +#define SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY_ENABLE 0x00010000 | |
118 | +#define SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY_ENABLE 0x00008000 | |
119 | +#define SBE_2T3E3_21143_VAL_EARLY_RECEIVE_INTERRUPT_ENABLE 0x00004000 | |
120 | +#define SBE_2T3E3_21143_VAL_FATAL_BUS_ERROR_ENABLE 0x00002000 | |
121 | +#define SBE_2T3E3_21143_VAL_LINK_FAIL_ENABLE 0x00001000 | |
122 | +#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_TIMER_ENABLE 0x00000800 | |
123 | +#define SBE_2T3E3_21143_VAL_EARLY_TRANSMIT_INTERRUPT_ENABLE 0x00000400 | |
124 | +#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_TIMEOUT_ENABLE 0x00000200 | |
125 | +#define SBE_2T3E3_21143_VAL_RECEIVE_STOPPED_ENABLE 0x00000100 | |
126 | +#define SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE_ENABLE 0x00000080 | |
127 | +#define SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT_ENABLE 0x00000040 | |
128 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW_INTERRUPT_ENABLE 0x00000020 | |
129 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_JABBER_TIMEOUT_ENABLE 0x00000008 | |
130 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE_ENABLE 0x00000004 | |
131 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_STOPPED_ENABLE 0x00000002 | |
132 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT_ENABLE 0x00000001 | |
133 | + | |
134 | +/* CSR8 - MISSED_FRAMES_AND_OVERFLOW_COUNTER */ | |
135 | +#define SBE_2T3E3_21143_VAL_OVERFLOW_COUNTER_OVERFLOW 0x10000000 | |
136 | +#define SBE_2T3E3_21143_VAL_OVERFLOW_COUNTER 0x0ffe0000 | |
137 | +#define SBE_2T3E3_21143_VAL_MISSED_FRAME_OVERFLOW 0x00010000 | |
138 | +#define SBE_2T3E3_21143_VAL_MISSED_FRAMES_COUNTER 0x0000ffff | |
139 | + | |
140 | +/* CSR9 - BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT */ | |
141 | +#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_DATA_IN 0x00080000 | |
142 | +#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_READ_MODE 0x00040000 | |
143 | +#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_DATA_OUT 0x00020000 | |
144 | +#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_CLOCK 0x00010000 | |
145 | +#define SBE_2T3E3_21143_VAL_READ_OPERATION 0x00004000 | |
146 | +#define SBE_2T3E3_21143_VAL_WRITE_OPERATION 0x00002000 | |
147 | +#define SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT 0x00001000 | |
148 | +#define SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT 0x00000800 | |
149 | +#define SBE_2T3E3_21143_VAL_BOOT_ROM_DATA 0x000000ff | |
150 | +#define SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_OUT 0x00000008 | |
151 | +#define SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_IN 0x00000004 | |
152 | +#define SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK 0x00000002 | |
153 | +#define SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT 0x00000001 | |
154 | + | |
155 | +/* CSR11 - GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL */ | |
156 | +#define SBE_2T3E3_21143_VAL_CYCLE_SIZE 0x80000000 | |
157 | +#define SBE_2T3E3_21143_VAL_TRANSMIT_TIMER 0x78000000 | |
158 | +#define SBE_2T3E3_21143_VAL_NUMBER_OF_TRANSMIT_PACKETS 0x07000000 | |
159 | +#define SBE_2T3E3_21143_VAL_RECEIVE_TIMER 0x00f00000 | |
160 | +#define SBE_2T3E3_21143_VAL_NUMBER_OF_RECEIVE_PACKETS 0x000e0000 | |
161 | +#define SBE_2T3E3_21143_VAL_CONTINUOUS_MODE 0x00010000 | |
162 | +#define SBE_2T3E3_21143_VAL_TIMER_VALUE 0x0000ffff | |
163 | + | |
164 | +/* CSR12 - SIA_STATUS */ | |
165 | +#define SBE_2T3E3_21143_VAL_10BASE_T_RECEIVE_PORT_ACTIVITY 0x00000200 | |
166 | +#define SBE_2T3E3_21143_VAL_AUI_RECEIVE_PORT_ACTIVITY 0x00000100 | |
167 | +#define SBE_2T3E3_21143_VAL_10Mbs_LINK_STATUS 0x00000004 | |
168 | +#define SBE_2T3E3_21143_VAL_100Mbs_LINK_STATUS 0x00000002 | |
169 | +#define SBE_2T3E3_21143_VAL_MII_RECEIVE_PORT_ACTIVITY 0x00000001 | |
170 | + | |
171 | +/* CSR13 - SIA_CONNECTIVITY */ | |
172 | +#define SBE_2T3E3_21143_VAL_10BASE_T_OR_AUI 0x00000008 | |
173 | +#define SBE_2T3E3_21143_VAL_SIA_RESET 0x00000001 | |
174 | + | |
175 | +/* CSR14 - SIA_TRANSMIT_AND_RECEIVE */ | |
176 | +#define SBE_2T3E3_21143_VAL_100BASE_TX_FULL_DUPLEX 0x00020000 | |
177 | +#define SBE_2T3E3_21143_VAL_COLLISION_DETECT_ENABLE 0x00000400 | |
178 | +#define SBE_2T3E3_21143_VAL_COLLISION_SQUELCH_ENABLE 0x00000200 | |
179 | +#define SBE_2T3E3_21143_VAL_RECEIVE_SQUELCH_ENABLE 0x00000100 | |
180 | +#define SBE_2T3E3_21143_VAL_LINK_PULSE_SEND_ENABLE 0x00000004 | |
181 | +#define SBE_2T3E3_21143_VAL_ENCODER_ENABLE 0x00000001 | |
182 | + | |
183 | +/* CSR15 - SIA_AND_GENERAL_PURPOSE_PORT */ | |
184 | +#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_DISABLE 0x00000010 | |
185 | +#define SBE_2T3E3_21143_VAL_AUI_BNC_MODE 0x00000008 | |
186 | +#define SBE_2T3E3_21143_VAL_HOST_UNJAB 0x00000002 | |
187 | +#define SBE_2T3E3_21143_VAL_JABBER_DISABLE 0x00000001 | |
188 | + | |
189 | +/************************************************************** | |
190 | + * CPLD | |
191 | + **************************************************************/ | |
192 | + | |
193 | +/* reg_map indexes */ | |
194 | +#define SBE_2T3E3_CPLD_REG_PCRA 0 | |
195 | +#define SBE_2T3E3_CPLD_REG_PCRB 1 | |
196 | +#define SBE_2T3E3_CPLD_REG_PLCR 2 | |
197 | +#define SBE_2T3E3_CPLD_REG_PLTR 3 | |
198 | +#define SBE_2T3E3_CPLD_REG_PPFR 4 | |
199 | +#define SBE_2T3E3_CPLD_REG_BOARD_ID 5 | |
200 | +#define SBE_2T3E3_CPLD_REG_FPGA_VERSION 6 | |
201 | +#define SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS 7 | |
202 | +#define SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT 8 | |
203 | +#define SBE_2T3E3_CPLD_REG_STATIC_RESET 9 | |
204 | +#define SBE_2T3E3_CPLD_REG_PULSE_RESET 10 | |
205 | +#define SBE_2T3E3_CPLD_REG_FPGA_RECONFIGURATION 11 | |
206 | +#define SBE_2T3E3_CPLD_REG_LEDR 12 | |
207 | +#define SBE_2T3E3_CPLD_REG_PICSR 13 | |
208 | +#define SBE_2T3E3_CPLD_REG_PIER 14 | |
209 | +#define SBE_2T3E3_CPLD_REG_PCRC 15 | |
210 | +#define SBE_2T3E3_CPLD_REG_PBWF 16 | |
211 | +#define SBE_2T3E3_CPLD_REG_PBWL 17 | |
212 | + | |
213 | +#define SBE_2T3E3_CPLD_REG_MAX 18 | |
214 | + | |
215 | +/**********/ | |
216 | + | |
217 | +/* val_map indexes */ | |
218 | +#define SBE_2T3E3_CPLD_VAL_LIU_SELECT 0 | |
219 | +#define SBE_2T3E3_CPLD_VAL_DAC_SELECT 1 | |
220 | +#define SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE 2 | |
221 | +#define SBE_2T3E3_CPLD_VAL_LIU_FRAMER_RESET 3 | |
222 | + | |
223 | +/* PCRA */ | |
224 | +#define SBE_2T3E3_CPLD_VAL_CRC32 0x40 | |
225 | +#define SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE 0x20 | |
226 | +#define SBE_2T3E3_CPLD_VAL_REAR_PANEL 0x10 | |
227 | +#define SBE_2T3E3_CPLD_VAL_RAW_MODE 0x08 | |
228 | +#define SBE_2T3E3_CPLD_VAL_ALT 0x04 | |
229 | +#define SBE_2T3E3_CPLD_VAL_LOOP_TIMING 0x02 | |
230 | +#define SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3 0x01 | |
231 | + | |
232 | +/* PCRB */ | |
233 | +#define SBE_2T3E3_CPLD_VAL_PAD_COUNT 0x30 | |
234 | +#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_1 0x00 | |
235 | +#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_2 0x10 | |
236 | +#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_3 0x20 | |
237 | +#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_4 0x30 | |
238 | +#define SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE 0x02 | |
239 | +#define SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE 0x01 | |
240 | + | |
241 | +/* PCRC */ | |
242 | +#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE 0x00 | |
243 | +#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0 0x01 | |
244 | +#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1 0x11 | |
245 | +#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2 0x21 | |
246 | + | |
247 | +/* PLTR */ | |
248 | +#define SBE_2T3E3_CPLD_VAL_LCV_COUNTER 0xff | |
249 | + | |
250 | +/* SCSR */ | |
251 | +#define SBE_2T3E3_CPLD_VAL_EEPROM_SELECT 0x10 | |
252 | + | |
253 | +/* PICSR */ | |
254 | +#define SBE_2T3E3_CPLD_VAL_LOSS_OF_SIGNAL_THRESHOLD_LEVEL_1 0x80 | |
255 | +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_CHANGE 0x40 | |
256 | +#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ASSERTED 0x20 | |
257 | +#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ASSERTED 0x10 | |
258 | +#define SBE_2T3E3_CPLD_VAL_LCV_LIMIT_EXCEEDED 0x08 | |
259 | +#define SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED 0x04 | |
260 | +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED 0x02 | |
261 | +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED 0x01 | |
262 | + | |
263 | +/* PIER */ | |
264 | +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOS_CHANGE_ENABLE 0x40 | |
265 | +#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE 0x20 | |
266 | +#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE 0x10 | |
267 | +#define SBE_2T3E3_CPLD_VAL_LCV_INTERRUPT_ENABLE 0x08 | |
268 | +#define SBE_2T3E3_CPLD_VAL_DMO_ENABLE 0x04 | |
269 | +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_ENABLE 0x02 | |
270 | +#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_ENABLE 0x01 | |
271 | + | |
272 | +/************************************************************** | |
273 | + * Framer | |
274 | + **************************************************************/ | |
275 | + | |
276 | +/* reg_map indexes */ | |
277 | +/* common */ | |
278 | +#define SBE_2T3E3_FRAMER_REG_OPERATING_MODE 0 | |
279 | +#define SBE_2T3E3_FRAMER_REG_IO_CONTROL 1 | |
280 | +#define SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE 2 | |
281 | +#define SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS 3 | |
282 | +#define SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_MSB 28 | |
283 | +#define SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_LSB 29 | |
284 | +#define SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB 30 | |
285 | +#define SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_LSB 31 | |
286 | +#define SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_MSB 32 | |
287 | +#define SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_LSB 33 | |
288 | +#define SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_MSB 34 | |
289 | +#define SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_LSB 35 | |
290 | +#define SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_MSB 36 | |
291 | +#define SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_LSB 37 | |
292 | +#define SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER 38 | |
293 | +#define SBE_2T3E3_FRAMER_REG_ONE_SECOND_ERROR_STATUS 39 | |
294 | +#define SBE_2T3E3_FRAMER_REG_LCV_ONE_SECOND_ACCUMULATOR_MSB 40 | |
295 | +#define SBE_2T3E3_FRAMER_REG_LCV_ONE_SECOND_ACCUMULATOR_LSB 41 | |
296 | +#define SBE_2T3E3_FRAMER_REG_FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_MSB 42 | |
297 | +#define SBE_2T3E3_FRAMER_REG_FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_LSB 43 | |
298 | +#define SBE_2T3E3_FRAMER_REG_FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_MSB 44 | |
299 | +#define SBE_2T3E3_FRAMER_REG_FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_LSB 45 | |
300 | +#define SBE_2T3E3_FRAMER_REG_LINE_INTERFACE_DRIVE 46 | |
301 | +#define SBE_2T3E3_FRAMER_REG_LINE_INTERFACE_SCAN 47 | |
302 | + | |
303 | +/* T3 */ | |
304 | +#define SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS 4 | |
305 | +#define SBE_2T3E3_FRAMER_REG_T3_RX_STATUS 5 | |
306 | +#define SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE 6 | |
307 | +#define SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS 7 | |
308 | +#define SBE_2T3E3_FRAMER_REG_T3_RX_SYNC_DETECT_ENABLE 8 | |
309 | +#define SBE_2T3E3_FRAMER_REG_T3_RX_FEAC 10 | |
310 | +#define SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS 11 | |
311 | +#define SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL 12 | |
312 | +#define SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_STATUS 13 | |
313 | +#define SBE_2T3E3_FRAMER_REG_T3_TX_CONFIGURATION 16 | |
314 | +#define SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS 17 | |
315 | +#define SBE_2T3E3_FRAMER_REG_T3_TX_FEAC 18 | |
316 | +#define SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_CONFIGURATION 19 | |
317 | +#define SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS 20 | |
318 | +#define SBE_2T3E3_FRAMER_REG_T3_TX_MBIT_MASK 21 | |
319 | +#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK 22 | |
320 | +#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK_2 23 | |
321 | +#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK_3 24 | |
322 | + | |
323 | +/* E3 */ | |
324 | +#define SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_1 4 | |
325 | +#define SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2 5 | |
326 | +#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1 6 | |
327 | +#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2 7 | |
328 | +#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1 8 | |
329 | +#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2 9 | |
330 | +#define SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL 12 | |
331 | +#define SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_STATUS 13 | |
332 | +#define SBE_2T3E3_FRAMER_REG_E3_RX_NR_BYTE 14 | |
333 | +#define SBE_2T3E3_FRAMER_REG_E3_RX_SERVICE_BITS 14 | |
334 | +#define SBE_2T3E3_FRAMER_REG_E3_RX_GC_BYTE 15 | |
335 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_CONFIGURATION 16 | |
336 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_CONFIGURATION 19 | |
337 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS 19 | |
338 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_GC_BYTE 21 | |
339 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_SERVICE_BITS 21 | |
340 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_MA_BYTE 22 | |
341 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_NR_BYTE 23 | |
342 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_FA1_ERROR_MASK 25 | |
343 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_FAS_ERROR_MASK_UPPER 25 | |
344 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_FA2_ERROR_MASK 26 | |
345 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_FAS_ERROR_MASK_LOWER 26 | |
346 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_BIP8_MASK 27 | |
347 | +#define SBE_2T3E3_FRAMER_REG_E3_TX_BIP4_MASK 27 | |
348 | + | |
349 | +#define SBE_2T3E3_FRAMER_REG_MAX 48 | |
350 | + | |
351 | +/**********/ | |
352 | + | |
353 | +/* OPERATING_MODE */ | |
354 | +#define SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE 0x80 | |
355 | +#define SBE_2T3E3_FRAMER_VAL_T3_E3_SELECT 0x40 | |
356 | +#define SBE_2T3E3_FRAMER_VAL_INTERNAL_LOS_ENABLE 0x20 | |
357 | +#define SBE_2T3E3_FRAMER_VAL_RESET 0x10 | |
358 | +#define SBE_2T3E3_FRAMER_VAL_INTERRUPT_ENABLE_RESET 0x08 | |
359 | +#define SBE_2T3E3_FRAMER_VAL_FRAME_FORMAT_SELECT 0x04 | |
360 | +#define SBE_2T3E3_FRAMER_VAL_TIMING_ASYNCH_TXINCLK 0x03 | |
361 | +#define SBE_2T3E3_FRAMER_VAL_E3_G751 0x00 | |
362 | +#define SBE_2T3E3_FRAMER_VAL_E3_G832 0x04 | |
363 | +#define SBE_2T3E3_FRAMER_VAL_T3_CBIT 0x40 | |
364 | +#define SBE_2T3E3_FRAMER_VAL_T3_M13 0x44 | |
365 | +#define SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON 0x80 | |
366 | +#define SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF 0x00 | |
367 | + | |
368 | +/* IO_CONTROL */ | |
369 | +#define SBE_2T3E3_FRAMER_VAL_DISABLE_TX_LOSS_OF_CLOCK 0x80 | |
370 | +#define SBE_2T3E3_FRAMER_VAL_LOSS_OF_CLOCK_STATUS 0x40 | |
371 | +#define SBE_2T3E3_FRAMER_VAL_DISABLE_RX_LOSS_OF_CLOCK 0x20 | |
372 | +#define SBE_2T3E3_FRAMER_VAL_AMI_LINE_CODE 0x10 | |
373 | +#define SBE_2T3E3_FRAMER_VAL_UNIPOLAR 0x08 | |
374 | +#define SBE_2T3E3_FRAMER_VAL_TX_LINE_CLOCK_INVERT 0x04 | |
375 | +#define SBE_2T3E3_FRAMER_VAL_RX_LINE_CLOCK_INVERT 0x02 | |
376 | +#define SBE_2T3E3_FRAMER_VAL_REFRAME 0x01 | |
377 | + | |
378 | +/* BLOCK_INTERRUPT_ENABLE */ | |
379 | +#define SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE 0x80 | |
380 | +#define SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE 0x02 | |
381 | +#define SBE_2T3E3_FRAMER_VAL_ONE_SECOND_INTERRUPT_ENABLE 0x01 | |
382 | + | |
383 | +/* BLOCK_INTERRUPT_STATUS */ | |
384 | +#define SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS 0x80 | |
385 | +#define SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS 0x02 | |
386 | +#define SBE_2T3E3_FRAMER_VAL_ONE_SECOND_INTERRUPT_STATUS 0x01 | |
387 | + | |
388 | +/**********/ | |
389 | + | |
390 | +/* T3_RX_CONFIGURATION_STATUS */ | |
391 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS 0x80 | |
392 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS 0x40 | |
393 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE 0x20 | |
394 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF 0x10 | |
395 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FRAMING_ON_PARITY 0x04 | |
396 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_F_SYNC_ALGO 0x02 | |
397 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_M_SYNC_ALGO 0x01 | |
398 | + | |
399 | +/* T3_RX_STATUS */ | |
400 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF 0x10 | |
401 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC 0x04 | |
402 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEBE 0x07 | |
403 | + | |
404 | +/* T3_RX_INTERRUPT_ENABLE */ | |
405 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_ENABLE 0x80 | |
406 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE 0x40 | |
407 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_ENABLE 0x20 | |
408 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_ENABLE 0x10 | |
409 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_ENABLE 0x08 | |
410 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_ENABLE 0x04 | |
411 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE 0x02 | |
412 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_ENABLE 0x01 | |
413 | + | |
414 | +/* T3_RX_INTERRUPT_STATUS */ | |
415 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_STATUS 0x80 | |
416 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_STATUS 0x40 | |
417 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_STATUS 0x20 | |
418 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_STATUS 0x10 | |
419 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_STATUS 0x08 | |
420 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_STATUS 0x04 | |
421 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_STATUS 0x02 | |
422 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_STATUS 0x01 | |
423 | + | |
424 | +/* T3_RX_FEAC_INTERRUPT_ENABLE_STATUS */ | |
425 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID 0x10 | |
426 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_ENABLE 0x08 | |
427 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_STATUS 0x04 | |
428 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_ENABLE 0x02 | |
429 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_STATUS 0x01 | |
430 | + | |
431 | +/* T3_RX_LAPD_CONTROL */ | |
432 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_ENABLE 0x04 | |
433 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_INTERRUPT_ENABLE 0x02 | |
434 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_INTERRUPT_STATUS 0x01 | |
435 | + | |
436 | +/* T3_RX_LAPD_STATUS */ | |
437 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_ABORT 0x40 | |
438 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_TYPE 0x30 | |
439 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_CR_TYPE 0x08 | |
440 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FCS_ERROR 0x04 | |
441 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_END_OF_MESSAGE 0x02 | |
442 | +#define SBE_2T3E3_FRAMER_VAL_T3_RX_FLAG_PRESENT 0x01 | |
443 | + | |
444 | +/* T3_TX_CONFIGURATION */ | |
445 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_YELLOW_ALARM 0x80 | |
446 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_X_BIT 0x40 | |
447 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_IDLE 0x20 | |
448 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_AIS 0x10 | |
449 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_LOS 0x08 | |
450 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_LOS 0x04 | |
451 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_OOF 0x02 | |
452 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_AIS 0x01 | |
453 | + | |
454 | +/* T3_TX_FEAC_CONFIGURATION_STATUS */ | |
455 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_INTERRUPT_ENABLE 0x10 | |
456 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_INTERRUPT_STATUS 0x08 | |
457 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_ENABLE 0x04 | |
458 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_GO 0x02 | |
459 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_BUSY 0x01 | |
460 | + | |
461 | +/* T3_TX_LAPD_STATUS */ | |
462 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_DL_START 0x08 | |
463 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_DL_BUSY 0x04 | |
464 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_LAPD_INTERRUPT_ENABLE 0x02 | |
465 | +#define SBE_2T3E3_FRAMER_VAL_T3_TX_LAPD_INTERRUPT_STATUS 0x01 | |
466 | + | |
467 | +/**********/ | |
468 | + | |
469 | +/* E3_RX_CONFIGURATION_STATUS_1 */ | |
470 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_TYPE 0xe0 | |
471 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_ALGO 0x10 | |
472 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_T_MARK_ALGO 0x08 | |
473 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_EXPECTED 0x07 | |
474 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4 0x01 | |
475 | + | |
476 | +/* E3_RX_CONFIGURATION_STATUS_2 */ | |
477 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_ALGO 0x80 | |
478 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF 0x40 | |
479 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF 0x20 | |
480 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS 0x10 | |
481 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS 0x08 | |
482 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_UNSTABLE 0x04 | |
483 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_T_MARK 0x02 | |
484 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF 0x01 | |
485 | + | |
486 | +/* E3_RX_INTERRUPT_ENABLE_1 */ | |
487 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_ENABLE 0x10 | |
488 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE 0x08 | |
489 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_ENABLE 0x04 | |
490 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE 0x02 | |
491 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_ENABLE 0x01 | |
492 | + | |
493 | +/* E3_RX_INTERRUPT_ENABLE_2 */ | |
494 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_TTB_CHANGE_INTERRUPT_ENABLE 0x40 | |
495 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_ENABLE 0x10 | |
496 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_ENABLE 0x08 | |
497 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP8_ERROR_INTERRUPT_ENABLE 0x04 | |
498 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4_ERROR_INTERRUPT_ENABLE 0x04 | |
499 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_ENABLE 0x02 | |
500 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_MISMATCH_INTERRUPT_ENABLE 0x01 | |
501 | + | |
502 | +/* E3_RX_INTERRUPT_STATUS_1 */ | |
503 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_STATUS 0x10 | |
504 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_STATUS 0x08 | |
505 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_STATUS 0x04 | |
506 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_STATUS 0x02 | |
507 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_STATUS 0x01 | |
508 | + | |
509 | +/* E3_RX_INTERRUPT_STATUS_2 */ | |
510 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_TTB_CHANGE_INTERRUPT_STATUS 0x40 | |
511 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_STATUS 0x10 | |
512 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_STATUS 0x08 | |
513 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP8_ERROR_INTERRUPT_STATUS 0x04 | |
514 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4_ERROR_INTERRUPT_STATUS 0x04 | |
515 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_STATUS 0x02 | |
516 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_MISMATCH_INTERRUPT_STATUS 0x01 | |
517 | + | |
518 | +/* E3_RX_LAPD_CONTROL */ | |
519 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_DL_FROM_NR 0x08 | |
520 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_ENABLE 0x04 | |
521 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_INTERRUPT_ENABLE 0x02 | |
522 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_INTERRUPT_STATUS 0x01 | |
523 | + | |
524 | +/* E3_RX_LAPD_STATUS */ | |
525 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_ABORT 0x40 | |
526 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_TYPE 0x30 | |
527 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_CR_TYPE 0x08 | |
528 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FCS_ERROR 0x04 | |
529 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_END_OF_MESSAGE 0x02 | |
530 | +#define SBE_2T3E3_FRAMER_VAL_E3_RX_FLAG_PRESENT 0x01 | |
531 | + | |
532 | +/* E3_TX_CONFIGURATION */ | |
533 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_BIP4_ENABLE 0x80 | |
534 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_A_SOURCE_SELECT 0x60 | |
535 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_IN_NR 0x10 | |
536 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_N_SOURCE_SELECT 0x18 | |
537 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_AIS_ENABLE 0x04 | |
538 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_LOS_ENABLE 0x02 | |
539 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_MA_RX 0x01 | |
540 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_FAS_SOURCE_SELECT 0x01 | |
541 | + | |
542 | +/* E3_TX_LAPD_CONFIGURATION */ | |
543 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_AUTO_RETRANSMIT 0x08 | |
544 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_MESSAGE_LENGTH 0x02 | |
545 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_ENABLE 0x01 | |
546 | + | |
547 | +/* E3_TX_LAPD_STATUS_INTERRUPT */ | |
548 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_START 0x08 | |
549 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_BUSY 0x04 | |
550 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_INTERRUPT_ENABLE 0x02 | |
551 | +#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_INTERRUPT_STATUS 0x01 | |
552 | + | |
553 | + | |
554 | + | |
555 | + | |
556 | + | |
557 | + | |
558 | +/************************************************************** | |
559 | + * LIU | |
560 | + **************************************************************/ | |
561 | + | |
562 | +/* reg_map indexes */ | |
563 | +#define SBE_2T3E3_LIU_REG_REG0 0 | |
564 | +#define SBE_2T3E3_LIU_REG_REG1 1 | |
565 | +#define SBE_2T3E3_LIU_REG_REG2 2 | |
566 | +#define SBE_2T3E3_LIU_REG_REG3 3 | |
567 | +#define SBE_2T3E3_LIU_REG_REG4 4 | |
568 | + | |
569 | +#define SBE_2T3E3_LIU_REG_MAX 5 | |
570 | + | |
571 | +/**********/ | |
572 | + | |
573 | +/* REG0 */ | |
574 | +#define SBE_2T3E3_LIU_VAL_RECEIVE_LOSS_OF_LOCK_STATUS 0x10 | |
575 | +#define SBE_2T3E3_LIU_VAL_RECEIVE_LOSS_OF_SIGNAL_STATUS 0x08 | |
576 | +#define SBE_2T3E3_LIU_VAL_ANALOG_LOSS_OF_SIGNAL_STATUS 0x04 | |
577 | +#define SBE_2T3E3_LIU_VAL_DIGITAL_LOSS_OF_SIGNAL_STATUS 0x02 | |
578 | +#define SBE_2T3E3_LIU_VAL_DMO_STATUS 0x01 | |
579 | + | |
580 | +/* REG1 */ | |
581 | +#define SBE_2T3E3_LIU_VAL_TRANSMITTER_OFF 0x10 | |
582 | +#define SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES 0x08 | |
583 | +#define SBE_2T3E3_LIU_VAL_TRANSMIT_CLOCK_INVERT 0x04 | |
584 | +#define SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT 0x02 | |
585 | +#define SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA 0x01 | |
586 | + | |
587 | +/* REG2 */ | |
588 | +#define SBE_2T3E3_LIU_VAL_DECODER_DISABLE 0x10 | |
589 | +#define SBE_2T3E3_LIU_VAL_ENCODER_DISABLE 0x08 | |
590 | +#define SBE_2T3E3_LIU_VAL_ANALOG_LOSS_OF_SIGNAL_DISABLE 0x04 | |
591 | +#define SBE_2T3E3_LIU_VAL_DIGITAL_LOSS_OF_SIGNAL_DISABLE 0x02 | |
592 | +#define SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE 0x01 | |
593 | + | |
594 | +/* REG3 */ | |
595 | +#define SBE_2T3E3_LIU_VAL_RECEIVE_BINARY_DATA 0x10 | |
596 | +#define SBE_2T3E3_LIU_VAL_RECOVERED_DATA_MUTING 0x08 | |
597 | +#define SBE_2T3E3_LIU_VAL_RECEIVE_CLOCK_OUTPUT_2 0x04 | |
598 | +#define SBE_2T3E3_LIU_VAL_INVERT_RECEIVE_CLOCK_2 0x02 | |
599 | +#define SBE_2T3E3_LIU_VAL_INVERT_RECEIVE_CLOCK_1 0x01 | |
600 | + | |
601 | +/* REG4 */ | |
602 | +#define SBE_2T3E3_LIU_VAL_T3_MODE_SELECT 0x00 | |
603 | +#define SBE_2T3E3_LIU_VAL_E3_MODE_SELECT 0x04 | |
604 | +#define SBE_2T3E3_LIU_VAL_LOCAL_LOOPBACK 0x02 | |
605 | +#define SBE_2T3E3_LIU_VAL_REMOTE_LOOPBACK 0x01 | |
606 | +#define SBE_2T3E3_LIU_VAL_LOOPBACK_OFF 0x00 | |
607 | +#define SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE 0x01 | |
608 | +#define SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG 0x02 | |
609 | +#define SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL 0x03 | |
610 | + | |
611 | +/********************************************************************** | |
612 | + * | |
613 | + * descriptor list and data buffer | |
614 | + * | |
615 | + **********************************************************************/ | |
616 | +typedef struct { | |
617 | + u32 rdes0; | |
618 | + u32 rdes1; | |
619 | + u32 rdes2; | |
620 | + u32 rdes3; | |
621 | +} t3e3_rx_desc_t; | |
622 | + | |
623 | +#define SBE_2T3E3_RX_DESC_RING_SIZE 64 | |
624 | + | |
625 | +/* RDES0 */ | |
626 | +#define SBE_2T3E3_RX_DESC_21143_OWN 0X80000000 | |
627 | +#define SBE_2T3E3_RX_DESC_FRAME_LENGTH 0x3fff0000 | |
628 | +#define SBE_2T3E3_RX_DESC_FRAME_LENGTH_SHIFT 16 | |
629 | +#define SBE_2T3E3_RX_DESC_ERROR_SUMMARY 0x00008000 | |
630 | +#define SBE_2T3E3_RX_DESC_DESC_ERROR 0x00004000 | |
631 | +#define SBE_2T3E3_RX_DESC_DATA_TYPE 0x00003000 | |
632 | +#define SBE_2T3E3_RX_DESC_RUNT_FRAME 0x00000800 | |
633 | +#define SBE_2T3E3_RX_DESC_FIRST_DESC 0x00000200 | |
634 | +#define SBE_2T3E3_RX_DESC_LAST_DESC 0x00000100 | |
635 | +#define SBE_2T3E3_RX_DESC_FRAME_TOO_LONG 0x00000080 | |
636 | +#define SBE_2T3E3_RX_DESC_COLLISION_SEEN 0x00000040 | |
637 | +#define SBE_2T3E3_RX_DESC_FRAME_TYPE 0x00000020 | |
638 | +#define SBE_2T3E3_RX_DESC_RECEIVE_WATCHDOG 0x00000010 | |
639 | +#define SBE_2T3E3_RX_DESC_MII_ERROR 0x00000008 | |
640 | +#define SBE_2T3E3_RX_DESC_DRIBBLING_BIT 0x00000004 | |
641 | +#define SBE_2T3E3_RX_DESC_CRC_ERROR 0x00000002 | |
642 | + | |
643 | +/* RDES1 */ | |
644 | +#define SBE_2T3E3_RX_DESC_END_OF_RING 0x02000000 | |
645 | +#define SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED 0x01000000 | |
646 | +#define SBE_2T3E3_RX_DESC_BUFFER_2_SIZE 0x003ff800 | |
647 | +#define SBE_2T3E3_RX_DESC_BUFFER_1_SIZE 0x000007ff | |
648 | + | |
649 | +/*********************/ | |
650 | + | |
651 | +typedef struct { | |
652 | + u32 tdes0; | |
653 | + u32 tdes1; | |
654 | + u32 tdes2; | |
655 | + u32 tdes3; | |
656 | +} t3e3_tx_desc_t; | |
657 | + | |
658 | +#define SBE_2T3E3_TX_DESC_RING_SIZE 256 | |
659 | + | |
660 | +/* TDES0 */ | |
661 | +#define SBE_2T3E3_TX_DESC_21143_OWN 0x80000000 | |
662 | +#define SBE_2T3E3_TX_DESC_ERROR_SUMMARY 0x00008000 | |
663 | +#define SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT 0x00004000 | |
664 | +#define SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER 0x00000800 | |
665 | +#define SBE_2T3E3_TX_DESC_NO_CARRIER 0x00000400 | |
666 | +#define SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT 0x00000004 | |
667 | +#define SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR 0x00000002 | |
668 | +#define SBE_2T3E3_TX_DESC_DEFFERED 0x00000001 | |
669 | + | |
670 | +/* TDES1 */ | |
671 | +#define SBE_2T3E3_TX_DESC_INTERRUPT_ON_COMPLETION 0x80000000 | |
672 | +#define SBE_2T3E3_TX_DESC_LAST_SEGMENT 0x40000000 | |
673 | +#define SBE_2T3E3_TX_DESC_FIRST_SEGMENT 0x20000000 | |
674 | +#define SBE_2T3E3_TX_DESC_CRC_DISABLE 0x04000000 | |
675 | +#define SBE_2T3E3_TX_DESC_END_OF_RING 0x02000000 | |
676 | +#define SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED 0x01000000 | |
677 | +#define SBE_2T3E3_TX_DESC_DISABLE_PADDING 0x00800000 | |
678 | +#define SBE_2T3E3_TX_DESC_BUFFER_2_SIZE 0x003ff800 | |
679 | +#define SBE_2T3E3_TX_DESC_BUFFER_1_SIZE 0x000007ff | |
680 | + | |
681 | + | |
682 | +#define SBE_2T3E3_MTU 1600 | |
683 | +#define SBE_2T3E3_CRC16_LENGTH 2 | |
684 | +#define SBE_2T3E3_CRC32_LENGTH 4 | |
685 | + | |
686 | +#define MCLBYTES (SBE_2T3E3_MTU + 128) | |
687 | + | |
688 | +struct channel { | |
689 | + struct pci_dev *pdev; | |
690 | + struct net_device *dev; | |
691 | + struct card *card; | |
692 | + unsigned long addr; /* DECchip */ | |
693 | + | |
694 | + int leds; | |
695 | + | |
696 | + /* pci specific */ | |
697 | + struct { | |
698 | + u32 slot; /* should be 0 or 1 */ | |
699 | + u32 command; | |
700 | + u8 cache_size; | |
701 | + } h; | |
702 | + | |
703 | + /* statistics */ | |
704 | + t3e3_stats_t s; | |
705 | + | |
706 | + /* running */ | |
707 | + struct { | |
708 | + u32 flags; | |
709 | + } r; | |
710 | + | |
711 | + /* parameters */ | |
712 | + t3e3_param_t p; | |
713 | + | |
714 | + u32 liu_regs[SBE_2T3E3_LIU_REG_MAX]; /* LIU registers */ | |
715 | + u32 framer_regs[SBE_2T3E3_FRAMER_REG_MAX]; /* Framer registers */ | |
716 | + | |
717 | + /* Ethernet Controller */ | |
718 | + struct { | |
719 | + u_int16_t card_serial_number[3]; | |
720 | + | |
721 | + u32 reg[SBE_2T3E3_21143_REG_MAX]; /* registers i.e. CSR */ | |
722 | + | |
723 | + u32 interrupt_enable_mask; | |
724 | + | |
725 | + /* receive chain/ring */ | |
726 | + t3e3_rx_desc_t *rx_ring; | |
727 | + struct sk_buff *rx_data[SBE_2T3E3_RX_DESC_RING_SIZE]; | |
728 | + u32 rx_ring_current_read; | |
729 | + | |
730 | + /* transmit chain/ring */ | |
731 | + t3e3_tx_desc_t *tx_ring; | |
732 | + struct sk_buff *tx_data[SBE_2T3E3_TX_DESC_RING_SIZE]; | |
733 | + u32 tx_ring_current_read; | |
734 | + u32 tx_ring_current_write; | |
735 | + int tx_full; | |
736 | + int tx_free_cnt; | |
737 | + spinlock_t tx_lock; | |
738 | + } ether; | |
739 | + | |
740 | + int32_t interrupt_active; | |
741 | + int32_t rcv_count; | |
742 | +}; | |
743 | + | |
744 | +struct card { | |
745 | + spinlock_t bootrom_lock; | |
746 | + unsigned long bootrom_addr; | |
747 | + struct timer_list timer; /* for updating LEDs */ | |
748 | + struct channel channels[0]; | |
749 | +}; | |
750 | + | |
751 | +#define SBE_2T3E3_FLAG_NETWORK_UP 0x00000001 | |
752 | +#define SBE_2T3E3_FLAG_NO_ERROR_MESSAGES 0x00000002 | |
753 | + | |
754 | +extern const u32 cpld_reg_map[][2]; | |
755 | +extern const u32 cpld_val_map[][2]; | |
756 | +extern const u32 t3e3_framer_reg_map[]; | |
757 | +extern const u32 t3e3_liu_reg_map[]; | |
758 | + | |
759 | +void t3e3_init(struct channel *); | |
760 | +void t3e3_if_up(struct channel *); | |
761 | +void t3e3_if_down(struct channel *); | |
762 | +int t3e3_if_start_xmit(struct sk_buff *skb, struct net_device *dev); | |
763 | +void t3e3_if_config(struct channel *, u32, char *, | |
764 | + t3e3_resp_t *, int *); | |
765 | +void t3e3_set_frame_type(struct channel *, u32); | |
766 | +u32 t3e3_eeprom_read_word(struct channel *, u32); | |
767 | +void t3e3_read_card_serial_number(struct channel *); | |
768 | + | |
769 | +/* interrupt handlers */ | |
770 | +irqreturn_t t3e3_intr(int irq, void *dev_instance); | |
771 | +void dc_intr(struct channel *); | |
772 | +void dc_intr_rx(struct channel *); | |
773 | +void dc_intr_tx(struct channel *); | |
774 | +void dc_intr_tx_underflow(struct channel *); | |
775 | +void exar7250_intr(struct channel *); | |
776 | +void exar7250_E3_intr(struct channel *, u32); | |
777 | +void exar7250_T3_intr(struct channel *, u32); | |
778 | + | |
779 | +/* Ethernet controller */ | |
780 | +u32 bootrom_read(struct channel *, u32); | |
781 | +void bootrom_write(struct channel *, u32, u32); | |
782 | +void dc_init(struct channel *); | |
783 | +void dc_start(struct channel *); | |
784 | +void dc_stop(struct channel *); | |
785 | +void dc_start_intr(struct channel *); | |
786 | +void dc_stop_intr(struct channel *); | |
787 | +void dc_reset(struct channel *); | |
788 | +void dc_restart(struct channel *); | |
789 | +void dc_receiver_onoff(struct channel *, u32); | |
790 | +void dc_transmitter_onoff(struct channel *, u32); | |
791 | +void dc_set_loopback(struct channel *, u32); | |
792 | +u32 dc_init_descriptor_list(struct channel *); | |
793 | +void dc_clear_descriptor_list(struct channel *); | |
794 | +void dc_drop_descriptor_list(struct channel *); | |
795 | +void dc_set_output_port(struct channel *); | |
796 | +void t3e3_sc_init(struct channel *); | |
797 | + | |
798 | +/* CPLD */ | |
799 | +void cpld_init(struct channel *sc); | |
800 | +u32 cpld_read(struct channel *sc, u32 reg); | |
801 | +void cpld_set_crc(struct channel *, u32); | |
802 | +void cpld_start_intr(struct channel *); | |
803 | +void cpld_stop_intr(struct channel *); | |
804 | +#if 0 | |
805 | +void cpld_led_onoff(struct channel *, u32, u32, u32, u32); | |
806 | +#endif | |
807 | +void cpld_set_clock(struct channel *sc, u32 mode); | |
808 | +void cpld_set_scrambler(struct channel *, u32); | |
809 | +void cpld_select_panel(struct channel *, u32); | |
810 | +void cpld_set_frame_mode(struct channel *, u32); | |
811 | +void cpld_set_frame_type(struct channel *, u32); | |
812 | +void cpld_set_pad_count(struct channel *, u32); | |
813 | +void cpld_set_fractional_mode(struct channel *, u32, u32, u32); | |
814 | +void cpld_LOS_update(struct channel *); | |
815 | + | |
816 | +/* Framer */ | |
817 | +extern u32 exar7250_read(struct channel *, u32); | |
818 | +extern void exar7250_write(struct channel *, u32, u32); | |
819 | +void exar7250_init(struct channel *); | |
820 | +void exar7250_start_intr(struct channel *, u32); | |
821 | +void exar7250_stop_intr(struct channel *, u32); | |
822 | +void exar7250_set_frame_type(struct channel *, u32); | |
823 | +void exar7250_set_loopback(struct channel *, u32); | |
824 | +void exar7250_unipolar_onoff(struct channel *, u32); | |
825 | + | |
826 | +/* LIU */ | |
827 | +u32 exar7300_read(struct channel *, u32); | |
828 | +void exar7300_write(struct channel *, u32, u32); | |
829 | +void exar7300_init(struct channel *); | |
830 | +void exar7300_line_build_out_onoff(struct channel *, u32); | |
831 | +void exar7300_set_frame_type(struct channel *, u32); | |
832 | +void exar7300_set_loopback(struct channel *, u32); | |
833 | +void exar7300_transmit_all_ones_onoff(struct channel *, u32); | |
834 | +void exar7300_receive_equalization_onoff(struct channel *, u32); | |
835 | +void exar7300_unipolar_onoff(struct channel *, u32); | |
836 | + | |
837 | +void update_led(struct channel *, int); | |
838 | +int setup_device(struct net_device *dev, struct channel *sc); | |
839 | + | |
840 | +static inline int has_two_ports(struct pci_dev *pdev) | |
841 | +{ | |
842 | + return pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P0; | |
843 | +} | |
844 | + | |
845 | +#define dev_to_priv(dev) (*(struct channel **) ((hdlc_device*)(dev) + 1)) | |
846 | + | |
847 | +static inline u32 dc_read(unsigned long addr, u32 reg) | |
848 | +{ | |
849 | + return inl(addr + (reg << 3)); | |
850 | +} | |
851 | + | |
852 | +static inline void dc_write(unsigned long addr, u32 reg, u32 val) | |
853 | +{ | |
854 | + outl(val, addr + (reg << 3)); | |
855 | +} | |
856 | + | |
857 | +static inline void dc_set_bits(unsigned long addr, u32 reg, u32 bits) | |
858 | +{ | |
859 | + dc_write(addr, reg, dc_read(addr, reg) | bits); | |
860 | +} | |
861 | + | |
862 | +static inline void dc_clear_bits(unsigned long addr, u32 reg, u32 bits) | |
863 | +{ | |
864 | + dc_write(addr, reg, dc_read(addr, reg) & ~bits); | |
865 | +} | |
866 | + | |
867 | +#define CPLD_MAP_REG(reg, sc) (cpld_reg_map[(reg)][(sc)->h.slot]) | |
868 | + | |
869 | +static inline void cpld_write(struct channel *channel, unsigned reg, u32 val) | |
870 | +{ | |
871 | + unsigned long flags; | |
872 | + spin_lock_irqsave(&channel->card->bootrom_lock, flags); | |
873 | + bootrom_write(channel, CPLD_MAP_REG(reg, channel), val); | |
874 | + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags); | |
875 | +} | |
876 | + | |
877 | +#define exar7250_set_bit(sc, reg, bit) \ | |
878 | + exar7250_write((sc), (reg), \ | |
879 | + exar7250_read(sc, reg) | (bit)) | |
880 | + | |
881 | +#define exar7250_clear_bit(sc, reg, bit) \ | |
882 | + exar7250_write((sc), (reg), \ | |
883 | + exar7250_read(sc, reg) & ~(bit)) | |
884 | + | |
885 | +#define exar7300_set_bit(sc, reg, bit) \ | |
886 | + exar7300_write((sc), (reg), \ | |
887 | + exar7300_read(sc, reg) | (bit)) | |
888 | + | |
889 | +#define exar7300_clear_bit(sc, reg, bit) \ | |
890 | + exar7300_write((sc), (reg), \ | |
891 | + exar7300_read(sc, reg) & ~(bit)) | |
892 | + | |
893 | + | |
894 | +#endif /* T3E3_H */ |
drivers/staging/sbe-2t3e3/Kconfig
1 | +config SBE_2T3E3 | |
2 | + tristate "SBE wanPMC-2T3E3 support" | |
3 | + depends on HDLC && PCI | |
4 | + help | |
5 | + Driver for wanPMC-2T3E3 cards by SBE Inc. | |
6 | + | |
7 | + If you have such a card, say Y here and see | |
8 | + <http://www.kernel.org/pub/linux/utils/net/hdlc/>. | |
9 | + | |
10 | + To compile this as a module, choose M here: the | |
11 | + module will be called sbe-2t3e3. | |
12 | + | |
13 | + If unsure, say N. |
drivers/staging/sbe-2t3e3/Makefile
drivers/staging/sbe-2t3e3/TODO
drivers/staging/sbe-2t3e3/cpld.c
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#include <linux/delay.h> | |
14 | +#include "2t3e3.h" | |
15 | +#include "ctrl.h" | |
16 | + | |
17 | +#define bootrom_set_bit(sc, reg, bit) \ | |
18 | + bootrom_write((sc), (reg), \ | |
19 | + bootrom_read((sc), (reg)) | (bit)) | |
20 | + | |
21 | +#define bootrom_clear_bit(sc, reg, bit) \ | |
22 | + bootrom_write((sc), (reg), \ | |
23 | + bootrom_read((sc), (reg)) & ~(bit)) | |
24 | + | |
25 | +static inline void cpld_set_bit(struct channel *channel, unsigned reg, u32 bit) | |
26 | +{ | |
27 | + unsigned long flags; | |
28 | + spin_lock_irqsave(&channel->card->bootrom_lock, flags); | |
29 | + bootrom_set_bit(channel, CPLD_MAP_REG(reg, channel), bit); | |
30 | + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags); | |
31 | +} | |
32 | + | |
33 | +static inline void cpld_clear_bit(struct channel *channel, unsigned reg, u32 bit) | |
34 | +{ | |
35 | + unsigned long flags; | |
36 | + spin_lock_irqsave(&channel->card->bootrom_lock, flags); | |
37 | + bootrom_clear_bit(channel, CPLD_MAP_REG(reg, channel), bit); | |
38 | + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags); | |
39 | +} | |
40 | + | |
41 | +void cpld_init(struct channel *sc) | |
42 | +{ | |
43 | + u32 val; | |
44 | +#if 0 | |
45 | + /* reset LIU and Framer */ | |
46 | + val = cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_FRAMER_RESET][sc->h.slot]; | |
47 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_STATIC_RESET, val); | |
48 | + udelay(10000); /* TODO - how long? */ | |
49 | + val = 0; | |
50 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_STATIC_RESET, val); | |
51 | +#endif | |
52 | + | |
53 | + /* PCRA */ | |
54 | + val = SBE_2T3E3_CPLD_VAL_CRC32 | | |
55 | + cpld_val_map[SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE][sc->h.slot]; | |
56 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRA, val); | |
57 | + | |
58 | + /* PCRB */ | |
59 | + val = 0; | |
60 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRB, val); | |
61 | + | |
62 | + /* PCRC */ | |
63 | + val = 0; | |
64 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, val); | |
65 | + | |
66 | + /* PBWF */ | |
67 | + val = 0; | |
68 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, val); | |
69 | + | |
70 | + /* PBWL */ | |
71 | + val = 0; | |
72 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, val); | |
73 | + | |
74 | + /* PLTR */ | |
75 | + val = SBE_2T3E3_CPLD_VAL_LCV_COUNTER; | |
76 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PLTR, val); | |
77 | + udelay(1000); | |
78 | + | |
79 | + /* PLCR */ | |
80 | + val = 0; | |
81 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PLCR, val); | |
82 | + udelay(1000); | |
83 | + | |
84 | + /* PPFR */ | |
85 | + val = 0x55; | |
86 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PPFR, val); | |
87 | + /* TODO: this doesn't work!!! */ | |
88 | + | |
89 | + /* SERIAL_CHIP_SELECT */ | |
90 | + val = 0; | |
91 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, val); | |
92 | + | |
93 | + /* PICSR */ | |
94 | + val = SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED | | |
95 | + SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED | | |
96 | + SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED; | |
97 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR, val); | |
98 | + | |
99 | + cpld_start_intr(sc); | |
100 | + | |
101 | + udelay(1000); | |
102 | +} | |
103 | + | |
104 | +void cpld_start_intr(struct channel *sc) | |
105 | +{ | |
106 | + u32 val; | |
107 | + | |
108 | + /* PIER */ | |
109 | + val = SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE | | |
110 | + SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE; | |
111 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val); | |
112 | +#if 0 | |
113 | + /* | |
114 | + do you want to hang up your computer? | |
115 | + ENABLE REST OF INTERRUPTS !!! | |
116 | + you have been warned :). | |
117 | + */ | |
118 | +#endif | |
119 | +} | |
120 | + | |
121 | +void cpld_stop_intr(struct channel *sc) | |
122 | +{ | |
123 | + u32 val; | |
124 | + | |
125 | + /* PIER */ | |
126 | + val = 0; | |
127 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val); | |
128 | +} | |
129 | + | |
130 | +void cpld_set_frame_mode(struct channel *sc, u32 mode) | |
131 | +{ | |
132 | + if (sc->p.frame_mode == mode) | |
133 | + return; | |
134 | + | |
135 | + switch (mode) { | |
136 | + case SBE_2T3E3_FRAME_MODE_HDLC: | |
137 | + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
138 | + SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE | | |
139 | + SBE_2T3E3_CPLD_VAL_RAW_MODE); | |
140 | + exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF); | |
141 | + exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF); | |
142 | + break; | |
143 | + case SBE_2T3E3_FRAME_MODE_TRANSPARENT: | |
144 | + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
145 | + SBE_2T3E3_CPLD_VAL_RAW_MODE); | |
146 | + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
147 | + SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE); | |
148 | + exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF); | |
149 | + exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF); | |
150 | + break; | |
151 | + case SBE_2T3E3_FRAME_MODE_RAW: | |
152 | + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
153 | + SBE_2T3E3_CPLD_VAL_RAW_MODE); | |
154 | + exar7250_unipolar_onoff(sc, SBE_2T3E3_ON); | |
155 | + exar7300_unipolar_onoff(sc, SBE_2T3E3_ON); | |
156 | + break; | |
157 | + default: | |
158 | + return; | |
159 | + } | |
160 | + | |
161 | + sc->p.frame_mode = mode; | |
162 | +} | |
163 | + | |
164 | +/* set rate of the local clock */ | |
165 | +void cpld_set_frame_type(struct channel *sc, u32 type) | |
166 | +{ | |
167 | + switch (type) { | |
168 | + case SBE_2T3E3_FRAME_TYPE_E3_G751: | |
169 | + case SBE_2T3E3_FRAME_TYPE_E3_G832: | |
170 | + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
171 | + SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3); | |
172 | + break; | |
173 | + case SBE_2T3E3_FRAME_TYPE_T3_CBIT: | |
174 | + case SBE_2T3E3_FRAME_TYPE_T3_M13: | |
175 | + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
176 | + SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3); | |
177 | + break; | |
178 | + default: | |
179 | + return; | |
180 | + } | |
181 | +} | |
182 | + | |
183 | +void cpld_set_scrambler(struct channel *sc, u32 mode) | |
184 | +{ | |
185 | + if (sc->p.scrambler == mode) | |
186 | + return; | |
187 | + | |
188 | + switch (mode) { | |
189 | + case SBE_2T3E3_SCRAMBLER_OFF: | |
190 | + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, | |
191 | + SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE); | |
192 | + break; | |
193 | + case SBE_2T3E3_SCRAMBLER_LARSCOM: | |
194 | + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, | |
195 | + SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE); | |
196 | + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, | |
197 | + SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE); | |
198 | + break; | |
199 | + case SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL: | |
200 | + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, | |
201 | + SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE); | |
202 | + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, | |
203 | + SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE); | |
204 | + break; | |
205 | + default: | |
206 | + return; | |
207 | + } | |
208 | + | |
209 | + sc->p.scrambler = mode; | |
210 | +} | |
211 | + | |
212 | + | |
213 | +void cpld_set_crc(struct channel *sc, u32 crc) | |
214 | +{ | |
215 | + if (sc->p.crc == crc) | |
216 | + return; | |
217 | + | |
218 | + switch (crc) { | |
219 | + case SBE_2T3E3_CRC_16: | |
220 | + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
221 | + SBE_2T3E3_CPLD_VAL_CRC32); | |
222 | + break; | |
223 | + case SBE_2T3E3_CRC_32: | |
224 | + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
225 | + SBE_2T3E3_CPLD_VAL_CRC32); | |
226 | + break; | |
227 | + default: | |
228 | + return; | |
229 | + } | |
230 | + | |
231 | + sc->p.crc = crc; | |
232 | +} | |
233 | + | |
234 | + | |
235 | +void cpld_select_panel(struct channel *sc, u32 panel) | |
236 | +{ | |
237 | + if (sc->p.panel == panel) | |
238 | + return; | |
239 | + switch (panel) { | |
240 | + case SBE_2T3E3_PANEL_FRONT: | |
241 | + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
242 | + SBE_2T3E3_CPLD_VAL_REAR_PANEL); | |
243 | + break; | |
244 | + case SBE_2T3E3_PANEL_REAR: | |
245 | + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
246 | + SBE_2T3E3_CPLD_VAL_REAR_PANEL); | |
247 | + break; | |
248 | + default: | |
249 | + return; | |
250 | + } | |
251 | + | |
252 | + udelay(100); | |
253 | + | |
254 | + sc->p.panel = panel; | |
255 | +} | |
256 | + | |
257 | + | |
258 | +extern void cpld_set_clock(struct channel *sc, u32 mode) | |
259 | +{ | |
260 | + if (sc->p.clock_source == mode) | |
261 | + return; | |
262 | + | |
263 | + switch (mode) { | |
264 | + case SBE_2T3E3_TIMING_LOCAL: | |
265 | + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
266 | + SBE_2T3E3_CPLD_VAL_ALT); | |
267 | + break; | |
268 | + case SBE_2T3E3_TIMING_LOOP: | |
269 | + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA, | |
270 | + SBE_2T3E3_CPLD_VAL_ALT); | |
271 | + break; | |
272 | + default: | |
273 | + return; | |
274 | + } | |
275 | + | |
276 | + sc->p.clock_source = mode; | |
277 | +} | |
278 | + | |
279 | +void cpld_set_pad_count(struct channel *sc, u32 count) | |
280 | +{ | |
281 | + u32 val; | |
282 | + | |
283 | + if (sc->p.pad_count == count) | |
284 | + return; | |
285 | + | |
286 | + switch (count) { | |
287 | + case SBE_2T3E3_PAD_COUNT_1: | |
288 | + val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_1; | |
289 | + break; | |
290 | + case SBE_2T3E3_PAD_COUNT_2: | |
291 | + val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_2; | |
292 | + break; | |
293 | + case SBE_2T3E3_PAD_COUNT_3: | |
294 | + val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_3; | |
295 | + break; | |
296 | + case SBE_2T3E3_PAD_COUNT_4: | |
297 | + val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_4; | |
298 | + break; | |
299 | + default: | |
300 | + return; | |
301 | + } | |
302 | + | |
303 | + cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, | |
304 | + SBE_2T3E3_CPLD_VAL_PAD_COUNT); | |
305 | + cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, val); | |
306 | + sc->p.pad_count = count; | |
307 | +} | |
308 | + | |
309 | +void cpld_LOS_update(struct channel *sc) | |
310 | +{ | |
311 | + u_int8_t los; | |
312 | + | |
313 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR, | |
314 | + SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED | | |
315 | + SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED | | |
316 | + SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED); | |
317 | + los = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR) & | |
318 | + SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED; | |
319 | + | |
320 | + if (los != sc->s.LOS) | |
321 | + dev_info(&sc->pdev->dev, "SBE 2T3E3: LOS status: %s\n", | |
322 | + los ? "Loss of signal" : "Signal OK"); | |
323 | + sc->s.LOS = los; | |
324 | +} | |
325 | + | |
326 | +void cpld_set_fractional_mode(struct channel *sc, u32 mode, | |
327 | + u32 start, u32 stop) | |
328 | +{ | |
329 | + if (mode == SBE_2T3E3_FRACTIONAL_MODE_NONE) { | |
330 | + start = 0; | |
331 | + stop = 0; | |
332 | + } | |
333 | + | |
334 | + if (sc->p.fractional_mode == mode && sc->p.bandwidth_start == start && | |
335 | + sc->p.bandwidth_stop == stop) | |
336 | + return; | |
337 | + | |
338 | + switch (mode) { | |
339 | + case SBE_2T3E3_FRACTIONAL_MODE_NONE: | |
340 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, | |
341 | + SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE); | |
342 | + break; | |
343 | + case SBE_2T3E3_FRACTIONAL_MODE_0: | |
344 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, | |
345 | + SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0); | |
346 | + break; | |
347 | + case SBE_2T3E3_FRACTIONAL_MODE_1: | |
348 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, | |
349 | + SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1); | |
350 | + break; | |
351 | + case SBE_2T3E3_FRACTIONAL_MODE_2: | |
352 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, | |
353 | + SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2); | |
354 | + break; | |
355 | + default: | |
356 | + printk(KERN_ERR "wrong mode in set_fractional_mode\n"); | |
357 | + return; | |
358 | + } | |
359 | + | |
360 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, start); | |
361 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, stop); | |
362 | + | |
363 | + sc->p.fractional_mode = mode; | |
364 | + sc->p.bandwidth_start = start; | |
365 | + sc->p.bandwidth_stop = stop; | |
366 | +} |
drivers/staging/sbe-2t3e3/ctrl.c
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#include <linux/types.h> | |
14 | +#include "2t3e3.h" | |
15 | +#include "ctrl.h" | |
16 | + | |
17 | +void t3e3_set_frame_type(struct channel *sc, u32 mode) | |
18 | +{ | |
19 | + if (sc->p.frame_type == mode) | |
20 | + return; | |
21 | + | |
22 | + if (sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP) { | |
23 | + dev_err(&sc->pdev->dev, "SBE 2T3E3: changing frame type during active connection\n"); | |
24 | + return; | |
25 | + } | |
26 | + | |
27 | + exar7300_set_frame_type(sc, mode); | |
28 | + exar7250_set_frame_type(sc, mode); | |
29 | + cpld_set_frame_type(sc, mode); | |
30 | + | |
31 | + sc->p.frame_type = mode; | |
32 | +} | |
33 | + | |
34 | +void t3e3_set_loopback(struct channel *sc, u32 mode) | |
35 | +{ | |
36 | + u32 tx, rx; | |
37 | + | |
38 | + if (sc->p.loopback == mode) | |
39 | + return; | |
40 | + | |
41 | + tx = sc->p.transmitter_on; | |
42 | + rx = sc->p.receiver_on; | |
43 | + if (tx == SBE_2T3E3_ON) | |
44 | + dc_transmitter_onoff(sc, SBE_2T3E3_OFF); | |
45 | + if (rx == SBE_2T3E3_ON) | |
46 | + dc_receiver_onoff(sc, SBE_2T3E3_OFF); | |
47 | + | |
48 | + /* stop current loopback if any exists */ | |
49 | + switch (sc->p.loopback) { | |
50 | + case SBE_2T3E3_LOOPBACK_NONE: | |
51 | + break; | |
52 | + case SBE_2T3E3_LOOPBACK_ETHERNET: | |
53 | + dc_set_loopback(sc, SBE_2T3E3_21143_VAL_LOOPBACK_OFF); | |
54 | + break; | |
55 | + case SBE_2T3E3_LOOPBACK_FRAMER: | |
56 | + exar7250_set_loopback(sc, SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF); | |
57 | + break; | |
58 | + case SBE_2T3E3_LOOPBACK_LIU_DIGITAL: | |
59 | + case SBE_2T3E3_LOOPBACK_LIU_ANALOG: | |
60 | + case SBE_2T3E3_LOOPBACK_LIU_REMOTE: | |
61 | + exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_OFF); | |
62 | + break; | |
63 | + default: | |
64 | + return; | |
65 | + } | |
66 | + | |
67 | + switch (mode) { | |
68 | + case SBE_2T3E3_LOOPBACK_NONE: | |
69 | + break; | |
70 | + case SBE_2T3E3_LOOPBACK_ETHERNET: | |
71 | + dc_set_loopback(sc, SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL); | |
72 | + break; | |
73 | + case SBE_2T3E3_LOOPBACK_FRAMER: | |
74 | + exar7250_set_loopback(sc, SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON); | |
75 | + break; | |
76 | + case SBE_2T3E3_LOOPBACK_LIU_DIGITAL: | |
77 | + exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL); | |
78 | + break; | |
79 | + case SBE_2T3E3_LOOPBACK_LIU_ANALOG: | |
80 | + exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG); | |
81 | + break; | |
82 | + case SBE_2T3E3_LOOPBACK_LIU_REMOTE: | |
83 | + exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE); | |
84 | + break; | |
85 | + default: | |
86 | + return; | |
87 | + } | |
88 | + | |
89 | + sc->p.loopback = mode; | |
90 | + | |
91 | + if (tx == SBE_2T3E3_ON) | |
92 | + dc_transmitter_onoff(sc, SBE_2T3E3_ON); | |
93 | + if (rx == SBE_2T3E3_ON) | |
94 | + dc_receiver_onoff(sc, SBE_2T3E3_ON); | |
95 | +} | |
96 | + | |
97 | + | |
98 | +void t3e3_reg_read(struct channel *sc, u32 *reg, u32 *val) | |
99 | +{ | |
100 | + u32 i; | |
101 | + | |
102 | + *val = 0; | |
103 | + | |
104 | + switch (reg[0]) { | |
105 | + case SBE_2T3E3_CHIP_21143: | |
106 | + if (!(reg[1] & 7)) | |
107 | + *val = dc_read(sc->addr, reg[1] / 8); | |
108 | + break; | |
109 | + case SBE_2T3E3_CHIP_CPLD: | |
110 | + for (i = 0; i < SBE_2T3E3_CPLD_REG_MAX; i++) | |
111 | + if (cpld_reg_map[i][sc->h.slot] == reg[1]) { | |
112 | + *val = cpld_read(sc, i); | |
113 | + break; | |
114 | + } | |
115 | + break; | |
116 | + case SBE_2T3E3_CHIP_FRAMER: | |
117 | + for (i = 0; i < SBE_2T3E3_FRAMER_REG_MAX; i++) | |
118 | + if (t3e3_framer_reg_map[i] == reg[1]) { | |
119 | + *val = exar7250_read(sc, i); | |
120 | + break; | |
121 | + } | |
122 | + break; | |
123 | + case SBE_2T3E3_CHIP_LIU: | |
124 | + for (i = 0; i < SBE_2T3E3_LIU_REG_MAX; i++) | |
125 | + if (t3e3_liu_reg_map[i] == reg[1]) { | |
126 | + *val = exar7300_read(sc, i); | |
127 | + break; | |
128 | + } | |
129 | + break; | |
130 | + default: | |
131 | + break; | |
132 | + } | |
133 | +} | |
134 | + | |
135 | +void t3e3_reg_write(struct channel *sc, u32 *reg) | |
136 | +{ | |
137 | + u32 i; | |
138 | + | |
139 | + switch (reg[0]) { | |
140 | + case SBE_2T3E3_CHIP_21143: | |
141 | + dc_write(sc->addr, reg[1], reg[2]); | |
142 | + break; | |
143 | + case SBE_2T3E3_CHIP_CPLD: | |
144 | + for (i = 0; i < SBE_2T3E3_CPLD_REG_MAX; i++) | |
145 | + if (cpld_reg_map[i][sc->h.slot] == reg[1]) { | |
146 | + cpld_write(sc, i, reg[2]); | |
147 | + break; | |
148 | + } | |
149 | + break; | |
150 | + case SBE_2T3E3_CHIP_FRAMER: | |
151 | + for (i = 0; i < SBE_2T3E3_FRAMER_REG_MAX; i++) | |
152 | + if (t3e3_framer_reg_map[i] == reg[1]) { | |
153 | + exar7250_write(sc, i, reg[2]); | |
154 | + break; | |
155 | + } | |
156 | + break; | |
157 | + case SBE_2T3E3_CHIP_LIU: | |
158 | + for (i = 0; i < SBE_2T3E3_LIU_REG_MAX; i++) | |
159 | + if (t3e3_liu_reg_map[i] == reg[1]) { | |
160 | + exar7300_write(sc, i, reg[2]); | |
161 | + break; | |
162 | + } | |
163 | + break; | |
164 | + } | |
165 | +} | |
166 | + | |
167 | +void t3e3_port_get(struct channel *sc, t3e3_param_t *param) | |
168 | +{ | |
169 | + memcpy(param, &(sc->p), sizeof(t3e3_param_t)); | |
170 | +} | |
171 | + | |
172 | +void t3e3_port_set(struct channel *sc, t3e3_param_t *param) | |
173 | +{ | |
174 | + if (param->frame_mode != 0xff) | |
175 | + cpld_set_frame_mode(sc, param->frame_mode); | |
176 | + | |
177 | + if (param->fractional_mode != 0xff) | |
178 | + cpld_set_fractional_mode(sc, param->fractional_mode, | |
179 | + param->bandwidth_start, | |
180 | + param->bandwidth_stop); | |
181 | + | |
182 | + if (param->pad_count != 0xff) | |
183 | + cpld_set_pad_count(sc, param->pad_count); | |
184 | + | |
185 | + if (param->crc != 0xff) | |
186 | + cpld_set_crc(sc, param->crc); | |
187 | + | |
188 | + if (param->receiver_on != 0xff) | |
189 | + dc_receiver_onoff(sc, param->receiver_on); | |
190 | + | |
191 | + if (param->transmitter_on != 0xff) | |
192 | + dc_transmitter_onoff(sc, param->transmitter_on); | |
193 | + | |
194 | + if (param->frame_type != 0xff) | |
195 | + t3e3_set_frame_type(sc, param->frame_type); | |
196 | + | |
197 | + if (param->panel != 0xff) | |
198 | + cpld_select_panel(sc, param->panel); | |
199 | + | |
200 | + if (param->line_build_out != 0xff) | |
201 | + exar7300_line_build_out_onoff(sc, param->line_build_out); | |
202 | + | |
203 | + if (param->receive_equalization != 0xff) | |
204 | + exar7300_receive_equalization_onoff(sc, param->receive_equalization); | |
205 | + | |
206 | + if (param->transmit_all_ones != 0xff) | |
207 | + exar7300_transmit_all_ones_onoff(sc, param->transmit_all_ones); | |
208 | + | |
209 | + if (param->loopback != 0xff) | |
210 | + t3e3_set_loopback(sc, param->loopback); | |
211 | + | |
212 | + if (param->clock_source != 0xff) | |
213 | + cpld_set_clock(sc, param->clock_source); | |
214 | + | |
215 | + if (param->scrambler != 0xff) | |
216 | + cpld_set_scrambler(sc, param->scrambler); | |
217 | +} | |
218 | + | |
219 | +void t3e3_port_get_stats(struct channel *sc, | |
220 | + t3e3_stats_t *stats) | |
221 | +{ | |
222 | + u32 result; | |
223 | + | |
224 | + sc->s.LOC = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL) | |
225 | + & SBE_2T3E3_FRAMER_VAL_LOSS_OF_CLOCK_STATUS ? 1 : 0; | |
226 | + | |
227 | + switch (sc->p.frame_type) { | |
228 | + case SBE_2T3E3_FRAME_TYPE_E3_G751: | |
229 | + case SBE_2T3E3_FRAME_TYPE_E3_G832: | |
230 | + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2); | |
231 | + sc->s.LOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOF ? 1 : 0; | |
232 | + sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0; | |
233 | +#if 0 | |
234 | + sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS ? 1 : 0; | |
235 | +#else | |
236 | + cpld_LOS_update(sc); | |
237 | +#endif | |
238 | + sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_AIS ? 1 : 0; | |
239 | + sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_FERF ? 1 : 0; | |
240 | + break; | |
241 | + | |
242 | + case SBE_2T3E3_FRAME_TYPE_T3_CBIT: | |
243 | + case SBE_2T3E3_FRAME_TYPE_T3_M13: | |
244 | + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS); | |
245 | + sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIS ? 1 : 0; | |
246 | +#if 0 | |
247 | + sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS ? 1 : 0; | |
248 | +#else | |
249 | + cpld_LOS_update(sc); | |
250 | +#endif | |
251 | + sc->s.IDLE = result & SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE ? 1 : 0; | |
252 | + sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0; | |
253 | + | |
254 | + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_STATUS); | |
255 | + sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_FERF ? 1 : 0; | |
256 | + sc->s.AIC = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIC ? 1 : 0; | |
257 | + sc->s.FEBE_code = result & SBE_2T3E3_FRAMER_VAL_T3_RX_FEBE; | |
258 | + | |
259 | + sc->s.FEAC = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC); | |
260 | + break; | |
261 | + | |
262 | + default: | |
263 | + break; | |
264 | + } | |
265 | + | |
266 | + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_MSB) << 8; | |
267 | + result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER); | |
268 | + sc->s.LCV += result; | |
269 | + | |
270 | + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB) << 8; | |
271 | + result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER); | |
272 | + sc->s.FRAMING_BIT += result; | |
273 | + | |
274 | + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_MSB) << 8; | |
275 | + result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER); | |
276 | + sc->s.PARITY_ERROR += result; | |
277 | + | |
278 | + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_MSB) << 8; | |
279 | + result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER); | |
280 | + sc->s.FEBE_count += result; | |
281 | + | |
282 | + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_MSB) << 8; | |
283 | + result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER); | |
284 | + sc->s.CP_BIT += result; | |
285 | + | |
286 | + memcpy(stats, &(sc->s), sizeof(t3e3_stats_t)); | |
287 | +} | |
288 | + | |
289 | +void t3e3_port_del_stats(struct channel *sc) | |
290 | +{ | |
291 | + memset(&(sc->s), 0, sizeof(t3e3_stats_t)); | |
292 | +} | |
293 | + | |
294 | +void t3e3_if_config(struct channel *sc, u32 cmd, char *set, | |
295 | + t3e3_resp_t *ret, int *rlen) | |
296 | +{ | |
297 | + t3e3_param_t *param = (t3e3_param_t *)set; | |
298 | + u32 *data = (u32 *)set; | |
299 | + | |
300 | + /* turn off all interrupt */ | |
301 | + /* cpld_stop_intr(sc); */ | |
302 | + | |
303 | + switch (cmd) { | |
304 | + case SBE_2T3E3_PORT_GET: | |
305 | + t3e3_port_get(sc, &(ret->u.param)); | |
306 | + *rlen = sizeof(ret->u.param); | |
307 | + break; | |
308 | + case SBE_2T3E3_PORT_SET: | |
309 | + t3e3_port_set(sc, param); | |
310 | + *rlen = 0; | |
311 | + break; | |
312 | + case SBE_2T3E3_PORT_GET_STATS: | |
313 | + t3e3_port_get_stats(sc, &(ret->u.stats)); | |
314 | + *rlen = sizeof(ret->u.stats); | |
315 | + break; | |
316 | + case SBE_2T3E3_PORT_DEL_STATS: | |
317 | + t3e3_port_del_stats(sc); | |
318 | + *rlen = 0; | |
319 | + break; | |
320 | + case SBE_2T3E3_PORT_READ_REGS: | |
321 | + t3e3_reg_read(sc, data, &(ret->u.data)); | |
322 | + *rlen = sizeof(ret->u.data); | |
323 | + break; | |
324 | + case SBE_2T3E3_PORT_WRITE_REGS: | |
325 | +#if 0 | |
326 | + printk(KERN_DEBUG "SBE_2T3E3_PORT_WRITE_REGS, 0x%x, 0x%x, 0x%x\n", | |
327 | + ((int*)data)[0], ((int*)data)[1], ((int*)data)[2]); | |
328 | +#endif | |
329 | + t3e3_reg_write(sc, data); | |
330 | + *rlen = 0; | |
331 | + break; | |
332 | + case SBE_2T3E3_LOG_LEVEL: | |
333 | + *rlen = 0; | |
334 | + break; | |
335 | + default: | |
336 | + *rlen = 0; | |
337 | + break; | |
338 | + } | |
339 | + | |
340 | + /* turn on interrupt */ | |
341 | + /* cpld_start_intr(sc); */ | |
342 | +} | |
343 | + | |
344 | +void t3e3_sc_init(struct channel *sc) | |
345 | +{ | |
346 | + memset(sc, 0, sizeof(*sc)); | |
347 | + | |
348 | + sc->p.frame_mode = SBE_2T3E3_FRAME_MODE_HDLC; | |
349 | + sc->p.fractional_mode = SBE_2T3E3_FRACTIONAL_MODE_NONE; | |
350 | + sc->p.crc = SBE_2T3E3_CRC_32; | |
351 | + sc->p.receiver_on = SBE_2T3E3_OFF; | |
352 | + sc->p.transmitter_on = SBE_2T3E3_OFF; | |
353 | + sc->p.frame_type = SBE_2T3E3_FRAME_TYPE_T3_CBIT; | |
354 | + sc->p.panel = SBE_2T3E3_PANEL_FRONT; | |
355 | + sc->p.line_build_out = SBE_2T3E3_OFF; | |
356 | + sc->p.receive_equalization = SBE_2T3E3_OFF; | |
357 | + sc->p.transmit_all_ones = SBE_2T3E3_OFF; | |
358 | + sc->p.loopback = SBE_2T3E3_LOOPBACK_NONE; | |
359 | + sc->p.clock_source = SBE_2T3E3_TIMING_LOCAL; | |
360 | + sc->p.scrambler = SBE_2T3E3_SCRAMBLER_OFF; | |
361 | + sc->p.pad_count = SBE_2T3E3_PAD_COUNT_1; | |
362 | +} |
drivers/staging/sbe-2t3e3/ctrl.h
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#ifndef CTRL_H | |
14 | +#define CTRL_H | |
15 | + | |
16 | +#define SBE_2T3E3_OFF 0 | |
17 | +#define SBE_2T3E3_ON 1 | |
18 | + | |
19 | +#define SBE_2T3E3_LED_NONE 0 | |
20 | +#define SBE_2T3E3_LED_GREEN 1 | |
21 | +#define SBE_2T3E3_LED_YELLOW 2 | |
22 | + | |
23 | +#define SBE_2T3E3_CABLE_LENGTH_LESS_THAN_255_FEET 0 | |
24 | +#define SBE_2T3E3_CABLE_LENGTH_GREATER_THAN_255_FEET 1 | |
25 | + | |
26 | +#define SBE_2T3E3_CRC_16 0 | |
27 | +#define SBE_2T3E3_CRC_32 1 | |
28 | + | |
29 | +#define SBE_2T3E3_PANEL_FRONT 0 | |
30 | +#define SBE_2T3E3_PANEL_REAR 1 | |
31 | + | |
32 | +#define SBE_2T3E3_FRAME_MODE_HDLC 0 | |
33 | +#define SBE_2T3E3_FRAME_MODE_TRANSPARENT 1 | |
34 | +#define SBE_2T3E3_FRAME_MODE_RAW 2 | |
35 | + | |
36 | +#define SBE_2T3E3_FRAME_TYPE_E3_G751 0 | |
37 | +#define SBE_2T3E3_FRAME_TYPE_E3_G832 1 | |
38 | +#define SBE_2T3E3_FRAME_TYPE_T3_CBIT 2 | |
39 | +#define SBE_2T3E3_FRAME_TYPE_T3_M13 3 | |
40 | + | |
41 | +#define SBE_2T3E3_FRACTIONAL_MODE_NONE 0 | |
42 | +#define SBE_2T3E3_FRACTIONAL_MODE_0 1 | |
43 | +#define SBE_2T3E3_FRACTIONAL_MODE_1 2 | |
44 | +#define SBE_2T3E3_FRACTIONAL_MODE_2 3 | |
45 | + | |
46 | +#define SBE_2T3E3_SCRAMBLER_OFF 0 | |
47 | +#define SBE_2T3E3_SCRAMBLER_LARSCOM 1 | |
48 | +#define SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL 2 | |
49 | + | |
50 | +#define SBE_2T3E3_TIMING_LOCAL 0 | |
51 | +#define SBE_2T3E3_TIMING_LOOP 1 | |
52 | + | |
53 | +#define SBE_2T3E3_LOOPBACK_NONE 0 | |
54 | +#define SBE_2T3E3_LOOPBACK_ETHERNET 1 | |
55 | +#define SBE_2T3E3_LOOPBACK_FRAMER 2 | |
56 | +#define SBE_2T3E3_LOOPBACK_LIU_DIGITAL 3 | |
57 | +#define SBE_2T3E3_LOOPBACK_LIU_ANALOG 4 | |
58 | +#define SBE_2T3E3_LOOPBACK_LIU_REMOTE 5 | |
59 | + | |
60 | +#define SBE_2T3E3_PAD_COUNT_1 1 | |
61 | +#define SBE_2T3E3_PAD_COUNT_2 2 | |
62 | +#define SBE_2T3E3_PAD_COUNT_3 3 | |
63 | +#define SBE_2T3E3_PAD_COUNT_4 4 | |
64 | + | |
65 | +#define SBE_2T3E3_CHIP_21143 0 | |
66 | +#define SBE_2T3E3_CHIP_CPLD 1 | |
67 | +#define SBE_2T3E3_CHIP_FRAMER 2 | |
68 | +#define SBE_2T3E3_CHIP_LIU 3 | |
69 | + | |
70 | +#define SBE_2T3E3_LOG_LEVEL_NONE 0 | |
71 | +#define SBE_2T3E3_LOG_LEVEL_ERROR 1 | |
72 | +#define SBE_2T3E3_LOG_LEVEL_WARNING 2 | |
73 | +#define SBE_2T3E3_LOG_LEVEL_INFO 3 | |
74 | + | |
75 | +/* commands */ | |
76 | +#define SBE_2T3E3_PORT_GET 0 | |
77 | +#define SBE_2T3E3_PORT_SET 1 | |
78 | +#define SBE_2T3E3_PORT_GET_STATS 2 | |
79 | +#define SBE_2T3E3_PORT_DEL_STATS 3 | |
80 | +#define SBE_2T3E3_PORT_READ_REGS 4 | |
81 | +#define SBE_2T3E3_LOG_LEVEL 5 | |
82 | +#define SBE_2T3E3_PORT_WRITE_REGS 6 | |
83 | + | |
84 | +#define NG_SBE_2T3E3_NODE_TYPE "sbe2T3E3" | |
85 | +#define NG_SBE_2T3E3_COOKIE 0x03800891 | |
86 | + | |
87 | +typedef struct t3e3_param { | |
88 | + u_int8_t frame_mode; /* FRAME_MODE_* */ | |
89 | + u_int8_t crc; /* CRC_* */ | |
90 | + u_int8_t receiver_on; /* ON/OFF */ | |
91 | + u_int8_t transmitter_on; /* ON/OFF */ | |
92 | + u_int8_t frame_type; /* FRAME_TYPE_* */ | |
93 | + u_int8_t panel; /* PANEL_* */ | |
94 | + u_int8_t line_build_out; /* ON/OFF */ | |
95 | + u_int8_t receive_equalization; /* ON/OFF */ | |
96 | + u_int8_t transmit_all_ones; /* ON/OFF */ | |
97 | + u_int8_t loopback; /* LOOPBACK_* */ | |
98 | + u_int8_t clock_source; /* TIMING_* */ | |
99 | + u_int8_t scrambler; /* SCRAMBLER_* */ | |
100 | + u_int8_t pad_count; /* PAD_COUNT_* */ | |
101 | + u_int8_t log_level; /* LOG_LEVEL_* - unused */ | |
102 | + u_int8_t fractional_mode; /* FRACTIONAL_MODE_* */ | |
103 | + u_int8_t bandwidth_start; /* 0-255 */ | |
104 | + u_int8_t bandwidth_stop; /* 0-255 */ | |
105 | +} t3e3_param_t; | |
106 | + | |
107 | +typedef struct t3e3_stats { | |
108 | + u_int64_t in_bytes; | |
109 | + u32 in_packets, in_dropped; | |
110 | + u32 in_errors, in_error_desc, in_error_coll, in_error_drib, | |
111 | + in_error_crc, in_error_mii; | |
112 | + u_int64_t out_bytes; | |
113 | + u32 out_packets, out_dropped; | |
114 | + u32 out_errors, out_error_jab, out_error_lost_carr, | |
115 | + out_error_no_carr, out_error_link_fail, out_error_underflow, | |
116 | + out_error_dereferred; | |
117 | + u_int8_t LOC, LOF, OOF, LOS, AIS, FERF, IDLE, AIC, FEAC; | |
118 | + u_int16_t FEBE_code; | |
119 | + u32 LCV, FRAMING_BIT, PARITY_ERROR, FEBE_count, CP_BIT; | |
120 | +} t3e3_stats_t; | |
121 | + | |
122 | + | |
123 | +typedef struct t3e3_resp { | |
124 | + union { | |
125 | + t3e3_param_t param; | |
126 | + t3e3_stats_t stats; | |
127 | + u32 data; | |
128 | + } u; | |
129 | +} t3e3_resp_t; | |
130 | + | |
131 | +#endif /* CTRL_H */ |
drivers/staging/sbe-2t3e3/dc.c
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#include <linux/netdevice.h> | |
14 | +#include <linux/types.h> | |
15 | +#include <linux/errno.h> | |
16 | +#include <linux/io.h> | |
17 | +#include "2t3e3.h" | |
18 | +#include "ctrl.h" | |
19 | + | |
20 | +void dc_init(struct channel *sc) | |
21 | +{ | |
22 | + u32 val; | |
23 | + | |
24 | + dc_stop(sc); | |
25 | + /*dc_reset(sc);*/ /* do not want to reset here */ | |
26 | + | |
27 | + /* | |
28 | + * BUS_MODE (CSR0) | |
29 | + */ | |
30 | + val = SBE_2T3E3_21143_VAL_READ_LINE_ENABLE | | |
31 | + SBE_2T3E3_21143_VAL_READ_MULTIPLE_ENABLE | | |
32 | + SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_200us | | |
33 | + SBE_2T3E3_21143_VAL_BUS_ARBITRATION_RR; | |
34 | + | |
35 | + if (sc->h.command & 16) | |
36 | + val |= SBE_2T3E3_21143_VAL_WRITE_AND_INVALIDATE_ENABLE; | |
37 | + | |
38 | + switch (sc->h.cache_size) { | |
39 | + case 32: | |
40 | + val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_32; | |
41 | + break; | |
42 | + case 16: | |
43 | + val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_16; | |
44 | + break; | |
45 | + case 8: | |
46 | + val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_8; | |
47 | + break; | |
48 | + default: | |
49 | + break; | |
50 | + } | |
51 | + | |
52 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, val); | |
53 | + | |
54 | + /* OPERATION_MODE (CSR6) */ | |
55 | + val = SBE_2T3E3_21143_VAL_RECEIVE_ALL | | |
56 | + SBE_2T3E3_21143_VAL_MUST_BE_ONE | | |
57 | + SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1 | | |
58 | + SBE_2T3E3_21143_VAL_LOOPBACK_OFF | | |
59 | + SBE_2T3E3_21143_VAL_PASS_ALL_MULTICAST | | |
60 | + SBE_2T3E3_21143_VAL_PROMISCUOUS_MODE | | |
61 | + SBE_2T3E3_21143_VAL_PASS_BAD_FRAMES; | |
62 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, val); | |
63 | + if (sc->p.loopback == SBE_2T3E3_LOOPBACK_ETHERNET) | |
64 | + sc->p.loopback = SBE_2T3E3_LOOPBACK_NONE; | |
65 | + | |
66 | +#if 0 /* No need to clear this register - and it may be in use */ | |
67 | + /* | |
68 | + * BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT (CSR9) | |
69 | + */ | |
70 | + val = 0; | |
71 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, val); | |
72 | +#endif | |
73 | + | |
74 | + /* | |
75 | + * GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL (CSR11) | |
76 | + */ | |
77 | + val = SBE_2T3E3_21143_VAL_CYCLE_SIZE | | |
78 | + SBE_2T3E3_21143_VAL_TRANSMIT_TIMER | | |
79 | + SBE_2T3E3_21143_VAL_NUMBER_OF_TRANSMIT_PACKETS | | |
80 | + SBE_2T3E3_21143_VAL_RECEIVE_TIMER | | |
81 | + SBE_2T3E3_21143_VAL_NUMBER_OF_RECEIVE_PACKETS; | |
82 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL, val); | |
83 | + | |
84 | + /* prepare descriptors and data for receive and transmit procecsses */ | |
85 | + if (dc_init_descriptor_list(sc) != 0) | |
86 | + return; | |
87 | + | |
88 | + /* clear ethernet interrupts status */ | |
89 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF); | |
90 | + | |
91 | + /* SIA mode registers */ | |
92 | + dc_set_output_port(sc); | |
93 | +} | |
94 | + | |
95 | +void dc_start(struct channel *sc) | |
96 | +{ | |
97 | + u32 val; | |
98 | + | |
99 | + if (!(sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP)) | |
100 | + return; | |
101 | + | |
102 | + dc_init(sc); | |
103 | + | |
104 | + /* get actual LOS and OOF status */ | |
105 | + switch (sc->p.frame_type) { | |
106 | + case SBE_2T3E3_FRAME_TYPE_E3_G751: | |
107 | + case SBE_2T3E3_FRAME_TYPE_E3_G832: | |
108 | + val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2); | |
109 | + dev_dbg(&sc->pdev->dev, "Start Framer Rx Status = %02X\n", val); | |
110 | + sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0; | |
111 | + break; | |
112 | + case SBE_2T3E3_FRAME_TYPE_T3_CBIT: | |
113 | + case SBE_2T3E3_FRAME_TYPE_T3_M13: | |
114 | + val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS); | |
115 | + dev_dbg(&sc->pdev->dev, "Start Framer Rx Status = %02X\n", val); | |
116 | + sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0; | |
117 | + break; | |
118 | + default: | |
119 | + break; | |
120 | + } | |
121 | + cpld_LOS_update(sc); | |
122 | + | |
123 | + /* start receive and transmit processes */ | |
124 | + dc_transmitter_onoff(sc, SBE_2T3E3_ON); | |
125 | + dc_receiver_onoff(sc, SBE_2T3E3_ON); | |
126 | + | |
127 | + /* start interrupts */ | |
128 | + dc_start_intr(sc); | |
129 | +} | |
130 | + | |
131 | +#define MAX_INT_WAIT_CNT 12000 | |
132 | +void dc_stop(struct channel *sc) | |
133 | +{ | |
134 | + int wcnt; | |
135 | + | |
136 | + /* stop receive and transmit processes */ | |
137 | + dc_receiver_onoff(sc, SBE_2T3E3_OFF); | |
138 | + dc_transmitter_onoff(sc, SBE_2T3E3_OFF); | |
139 | + | |
140 | + /* turn off ethernet interrupts */ | |
141 | + dc_stop_intr(sc); | |
142 | + | |
143 | + /* wait to ensure the interrupts have been completed */ | |
144 | + for (wcnt = 0; wcnt < MAX_INT_WAIT_CNT; wcnt++) { | |
145 | + udelay(5); | |
146 | + if (!sc->interrupt_active) | |
147 | + break; | |
148 | + } | |
149 | + if (wcnt >= MAX_INT_WAIT_CNT) | |
150 | + dev_warn(&sc->pdev->dev, "SBE 2T3E3: Interrupt active too long\n"); | |
151 | + | |
152 | + /* clear all receive/transmit data */ | |
153 | + dc_drop_descriptor_list(sc); | |
154 | +} | |
155 | + | |
156 | +void dc_start_intr(struct channel *sc) | |
157 | +{ | |
158 | + if (sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE && sc->s.OOF) | |
159 | + return; | |
160 | + | |
161 | + if (sc->p.receiver_on || sc->p.transmitter_on) { | |
162 | + if (!sc->ether.interrupt_enable_mask) | |
163 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF); | |
164 | + | |
165 | + sc->ether.interrupt_enable_mask = | |
166 | + SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY_ENABLE | | |
167 | + SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY_ENABLE | | |
168 | + SBE_2T3E3_21143_VAL_RECEIVE_STOPPED_ENABLE | | |
169 | + SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE_ENABLE | | |
170 | + SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT_ENABLE | | |
171 | + SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW_INTERRUPT_ENABLE | | |
172 | + SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE_ENABLE | | |
173 | + SBE_2T3E3_21143_VAL_TRANSMIT_STOPPED_ENABLE | | |
174 | + SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT_ENABLE; | |
175 | + | |
176 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, | |
177 | + sc->ether.interrupt_enable_mask); | |
178 | + } | |
179 | +} | |
180 | + | |
181 | +void dc_stop_intr(struct channel *sc) | |
182 | +{ | |
183 | + sc->ether.interrupt_enable_mask = 0; | |
184 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0); | |
185 | +} | |
186 | + | |
187 | +void dc_reset(struct channel *sc) | |
188 | +{ | |
189 | + /* turn off ethernet interrupts */ | |
190 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0); | |
191 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF); | |
192 | + | |
193 | + /* software reset */ | |
194 | + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, | |
195 | + SBE_2T3E3_21143_VAL_SOFTWARE_RESET); | |
196 | + udelay(4); /* 50 PCI cycles < 2us */ | |
197 | + | |
198 | + /* clear hardware configuration */ | |
199 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, 0); | |
200 | + | |
201 | + /* clear software configuration */ | |
202 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, 0); | |
203 | + | |
204 | + /* turn off SIA reset */ | |
205 | + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY, | |
206 | + SBE_2T3E3_21143_VAL_SIA_RESET); | |
207 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE, 0); | |
208 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT, 0); | |
209 | +} | |
210 | + | |
211 | + | |
212 | +void dc_receiver_onoff(struct channel *sc, u32 mode) | |
213 | +{ | |
214 | + u32 i, state = 0; | |
215 | + | |
216 | + if (sc->p.receiver_on == mode) | |
217 | + return; | |
218 | + | |
219 | + switch (mode) { | |
220 | + case SBE_2T3E3_OFF: | |
221 | + if (dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) & | |
222 | + SBE_2T3E3_21143_VAL_RECEIVE_START) { | |
223 | + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
224 | + SBE_2T3E3_21143_VAL_RECEIVE_START); | |
225 | + | |
226 | + for (i = 0; i < 16; i++) { | |
227 | + state = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS) & | |
228 | + SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STATE; | |
229 | + if (state == SBE_2T3E3_21143_VAL_RX_STOPPED) | |
230 | + break; | |
231 | + udelay(5); | |
232 | + } | |
233 | + if (state != SBE_2T3E3_21143_VAL_RX_STOPPED) | |
234 | + dev_warn(&sc->pdev->dev, "SBE 2T3E3: Rx failed to stop\n"); | |
235 | + else | |
236 | + dev_info(&sc->pdev->dev, "SBE 2T3E3: Rx off\n"); | |
237 | + } | |
238 | + break; | |
239 | + case SBE_2T3E3_ON: | |
240 | + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
241 | + SBE_2T3E3_21143_VAL_RECEIVE_START); | |
242 | + udelay(100); | |
243 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND, 0xFFFFFFFF); | |
244 | + break; | |
245 | + default: | |
246 | + return; | |
247 | + } | |
248 | + | |
249 | + sc->p.receiver_on = mode; | |
250 | +} | |
251 | + | |
252 | +void dc_transmitter_onoff(struct channel *sc, u32 mode) | |
253 | +{ | |
254 | + u32 i, state = 0; | |
255 | + | |
256 | + if (sc->p.transmitter_on == mode) | |
257 | + return; | |
258 | + | |
259 | + switch (mode) { | |
260 | + case SBE_2T3E3_OFF: | |
261 | + if (dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) & | |
262 | + SBE_2T3E3_21143_VAL_TRANSMISSION_START) { | |
263 | + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
264 | + SBE_2T3E3_21143_VAL_TRANSMISSION_START); | |
265 | + | |
266 | + for (i = 0; i < 16; i++) { | |
267 | + state = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS) & | |
268 | + SBE_2T3E3_21143_VAL_TRANSMISSION_PROCESS_STATE; | |
269 | + if (state == SBE_2T3E3_21143_VAL_TX_STOPPED) | |
270 | + break; | |
271 | + udelay(5); | |
272 | + } | |
273 | + if (state != SBE_2T3E3_21143_VAL_TX_STOPPED) | |
274 | + dev_warn(&sc->pdev->dev, "SBE 2T3E3: Tx failed to stop\n"); | |
275 | + } | |
276 | + break; | |
277 | + case SBE_2T3E3_ON: | |
278 | + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
279 | + SBE_2T3E3_21143_VAL_TRANSMISSION_START); | |
280 | + udelay(100); | |
281 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND, 0xFFFFFFFF); | |
282 | + break; | |
283 | + default: | |
284 | + return; | |
285 | + } | |
286 | + | |
287 | + sc->p.transmitter_on = mode; | |
288 | +} | |
289 | + | |
290 | + | |
291 | + | |
292 | +void dc_set_loopback(struct channel *sc, u32 mode) | |
293 | +{ | |
294 | + u32 val; | |
295 | + | |
296 | + switch (mode) { | |
297 | + case SBE_2T3E3_21143_VAL_LOOPBACK_OFF: | |
298 | + case SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL: | |
299 | + break; | |
300 | + default: | |
301 | + return; | |
302 | + } | |
303 | + | |
304 | +#if 0 | |
305 | + /* restart SIA */ | |
306 | + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY, | |
307 | + SBE_2T3E3_21143_VAL_SIA_RESET); | |
308 | + udelay(1000); | |
309 | + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY, | |
310 | + SBE_2T3E3_21143_VAL_SIA_RESET); | |
311 | +#endif | |
312 | + | |
313 | + /* select loopback mode */ | |
314 | + val = dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) & | |
315 | + ~SBE_2T3E3_21143_VAL_OPERATING_MODE; | |
316 | + val |= mode; | |
317 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, val); | |
318 | + | |
319 | + if (mode == SBE_2T3E3_21143_VAL_LOOPBACK_OFF) | |
320 | + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
321 | + SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE); | |
322 | + else | |
323 | + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
324 | + SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE); | |
325 | +} | |
326 | + | |
327 | +u32 dc_init_descriptor_list(struct channel *sc) | |
328 | +{ | |
329 | + u32 i, j; | |
330 | + struct sk_buff *m; | |
331 | + | |
332 | + if (sc->ether.rx_ring == NULL) | |
333 | + sc->ether.rx_ring = kzalloc(SBE_2T3E3_RX_DESC_RING_SIZE * | |
334 | + sizeof(t3e3_rx_desc_t), GFP_KERNEL); | |
335 | + if (sc->ether.rx_ring == NULL) { | |
336 | + dev_err(&sc->pdev->dev, "SBE 2T3E3: no buffer space for RX ring\n"); | |
337 | + return ENOMEM; | |
338 | + } | |
339 | + | |
340 | + if (sc->ether.tx_ring == NULL) | |
341 | + sc->ether.tx_ring = kzalloc(SBE_2T3E3_TX_DESC_RING_SIZE * | |
342 | + sizeof(t3e3_tx_desc_t), GFP_KERNEL); | |
343 | + if (sc->ether.tx_ring == NULL) { | |
344 | +#ifdef T3E3_USE_CONTIGMALLOC | |
345 | + t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE * | |
346 | + sizeof(t3e3_rx_desc_t); | |
347 | +#endif | |
348 | + kfree(sc->ether.rx_ring); | |
349 | + sc->ether.rx_ring = NULL; | |
350 | + dev_err(&sc->pdev->dev, "SBE 2T3E3: no buffer space for RX ring\n"); | |
351 | + return ENOMEM; | |
352 | + } | |
353 | + | |
354 | + | |
355 | + /* | |
356 | + * Receive ring | |
357 | + */ | |
358 | + for (i = 0; i < SBE_2T3E3_RX_DESC_RING_SIZE; i++) { | |
359 | + sc->ether.rx_ring[i].rdes0 = SBE_2T3E3_RX_DESC_21143_OWN; | |
360 | + sc->ether.rx_ring[i].rdes1 = | |
361 | + SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED | SBE_2T3E3_MTU; | |
362 | + | |
363 | + if (sc->ether.rx_data[i] == NULL) { | |
364 | + if (!(m = dev_alloc_skb(MCLBYTES))) { | |
365 | + for (j = 0; j < i; j++) { | |
366 | + dev_kfree_skb_any(sc->ether.rx_data[j]); | |
367 | + sc->ether.rx_data[j] = NULL; | |
368 | + } | |
369 | +#ifdef T3E3_USE_CONTIGMALLOC | |
370 | + t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE * | |
371 | + sizeof(t3e3_rx_desc_t); | |
372 | +#endif | |
373 | + kfree(sc->ether.rx_ring); | |
374 | + sc->ether.rx_ring = NULL; | |
375 | +#ifdef T3E3_USE_CONTIGMALLOC | |
376 | + t3e3_contigmemory_size = SBE_2T3E3_TX_DESC_RING_SIZE * | |
377 | + sizeof(t3e3_tx_desc_t); | |
378 | +#endif | |
379 | + kfree(sc->ether.tx_ring); | |
380 | + sc->ether.tx_ring = NULL; | |
381 | + dev_err(&sc->pdev->dev, "SBE 2T3E3: token_alloc err:" | |
382 | + " no buffer space for RX ring\n"); | |
383 | + return ENOBUFS; | |
384 | + } | |
385 | + sc->ether.rx_data[i] = m; | |
386 | + } | |
387 | + sc->ether.rx_ring[i].rdes2 = virt_to_phys(sc->ether.rx_data[i]->data); | |
388 | + | |
389 | + sc->ether.rx_ring[i].rdes3 = virt_to_phys( | |
390 | + &sc->ether.rx_ring[(i + 1) % SBE_2T3E3_RX_DESC_RING_SIZE]); | |
391 | + } | |
392 | + sc->ether.rx_ring[SBE_2T3E3_RX_DESC_RING_SIZE - 1].rdes1 |= | |
393 | + SBE_2T3E3_RX_DESC_END_OF_RING; | |
394 | + sc->ether.rx_ring_current_read = 0; | |
395 | + | |
396 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS, | |
397 | + virt_to_phys(&sc->ether.rx_ring[0])); | |
398 | + | |
399 | + /* | |
400 | + * Transmit ring | |
401 | + */ | |
402 | + for (i = 0; i < SBE_2T3E3_TX_DESC_RING_SIZE; i++) { | |
403 | + sc->ether.tx_ring[i].tdes0 = 0; | |
404 | + sc->ether.tx_ring[i].tdes1 = SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED | | |
405 | + SBE_2T3E3_TX_DESC_DISABLE_PADDING; | |
406 | + | |
407 | + sc->ether.tx_ring[i].tdes2 = 0; | |
408 | + sc->ether.tx_data[i] = NULL; | |
409 | + | |
410 | + sc->ether.tx_ring[i].tdes3 = virt_to_phys( | |
411 | + &sc->ether.tx_ring[(i + 1) % SBE_2T3E3_TX_DESC_RING_SIZE]); | |
412 | + } | |
413 | + sc->ether.tx_ring[SBE_2T3E3_TX_DESC_RING_SIZE - 1].tdes1 |= | |
414 | + SBE_2T3E3_TX_DESC_END_OF_RING; | |
415 | + | |
416 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS, | |
417 | + virt_to_phys(&sc->ether.tx_ring[0])); | |
418 | + sc->ether.tx_ring_current_read = 0; | |
419 | + sc->ether.tx_ring_current_write = 0; | |
420 | + sc->ether.tx_free_cnt = SBE_2T3E3_TX_DESC_RING_SIZE; | |
421 | + spin_lock_init(&sc->ether.tx_lock); | |
422 | + | |
423 | + return 0; | |
424 | +} | |
425 | + | |
426 | +void dc_clear_descriptor_list(struct channel *sc) | |
427 | +{ | |
428 | + u32 i; | |
429 | + | |
430 | + /* clear CSR3 and CSR4 */ | |
431 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS, 0); | |
432 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS, 0); | |
433 | + | |
434 | + /* free all data buffers on TX ring */ | |
435 | + for (i = 0; i < SBE_2T3E3_TX_DESC_RING_SIZE; i++) { | |
436 | + if (sc->ether.tx_data[i] != NULL) { | |
437 | + dev_kfree_skb_any(sc->ether.tx_data[i]); | |
438 | + sc->ether.tx_data[i] = NULL; | |
439 | + } | |
440 | + } | |
441 | +} | |
442 | + | |
443 | +void dc_drop_descriptor_list(struct channel *sc) | |
444 | +{ | |
445 | + u32 i; | |
446 | + | |
447 | + dc_clear_descriptor_list(sc); | |
448 | + | |
449 | + /* free all data buffers on RX ring */ | |
450 | + for (i = 0; i < SBE_2T3E3_RX_DESC_RING_SIZE; i++) { | |
451 | + if (sc->ether.rx_data[i] != NULL) { | |
452 | + dev_kfree_skb_any(sc->ether.rx_data[i]); | |
453 | + sc->ether.rx_data[i] = NULL; | |
454 | + } | |
455 | + } | |
456 | + | |
457 | + if (sc->ether.rx_ring != NULL) { | |
458 | +#ifdef T3E3_USE_CONTIGMALLOC | |
459 | + t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE * | |
460 | + sizeof(t3e3_rx_desc_t); | |
461 | +#endif | |
462 | + kfree(sc->ether.rx_ring); | |
463 | + sc->ether.rx_ring = NULL; | |
464 | + } | |
465 | + | |
466 | + if (sc->ether.tx_ring != NULL) { | |
467 | +#ifdef T3E3_USE_CONTIGMALLOC | |
468 | + t3e3_contigmemory_size = SBE_2T3E3_TX_DESC_RING_SIZE * | |
469 | + sizeof(t3e3_tx_desc_t); | |
470 | +#endif | |
471 | + kfree(sc->ether.tx_ring); | |
472 | + sc->ether.tx_ring = NULL; | |
473 | + } | |
474 | +} | |
475 | + | |
476 | + | |
477 | +void dc_set_output_port(struct channel *sc) | |
478 | +{ | |
479 | + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
480 | + SBE_2T3E3_21143_VAL_PORT_SELECT); | |
481 | + | |
482 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_STATUS, 0x00000301); | |
483 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY, 0); | |
484 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE, 0); | |
485 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT, 0x08000011); | |
486 | + | |
487 | + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
488 | + SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_100Mbs | | |
489 | + SBE_2T3E3_21143_VAL_HEARTBEAT_DISABLE | | |
490 | + SBE_2T3E3_21143_VAL_PORT_SELECT | | |
491 | + SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE); | |
492 | +} | |
493 | + | |
494 | +void dc_restart(struct channel *sc) | |
495 | +{ | |
496 | + dev_warn(&sc->pdev->dev, "SBE 2T3E3: 21143 restart\n"); | |
497 | + | |
498 | + dc_stop(sc); | |
499 | + dc_reset(sc); | |
500 | + dc_init(sc); /* stop + reset + init */ | |
501 | + dc_start(sc); | |
502 | +} |
drivers/staging/sbe-2t3e3/exar7250.c
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#include "2t3e3.h" | |
14 | +#include "ctrl.h" | |
15 | + | |
16 | +void exar7250_init(struct channel *sc) | |
17 | +{ | |
18 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE, | |
19 | + SBE_2T3E3_FRAMER_VAL_T3_CBIT | | |
20 | + SBE_2T3E3_FRAMER_VAL_INTERRUPT_ENABLE_RESET | | |
21 | + SBE_2T3E3_FRAMER_VAL_TIMING_ASYNCH_TXINCLK); | |
22 | + | |
23 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL, | |
24 | + SBE_2T3E3_FRAMER_VAL_DISABLE_TX_LOSS_OF_CLOCK | | |
25 | + SBE_2T3E3_FRAMER_VAL_DISABLE_RX_LOSS_OF_CLOCK | | |
26 | + SBE_2T3E3_FRAMER_VAL_AMI_LINE_CODE | | |
27 | + SBE_2T3E3_FRAMER_VAL_RX_LINE_CLOCK_INVERT); | |
28 | + | |
29 | + exar7250_set_frame_type(sc, SBE_2T3E3_FRAME_TYPE_T3_CBIT); | |
30 | +} | |
31 | + | |
32 | +void exar7250_set_frame_type(struct channel *sc, u32 type) | |
33 | +{ | |
34 | + u32 val; | |
35 | + | |
36 | + switch (type) { | |
37 | + case SBE_2T3E3_FRAME_TYPE_E3_G751: | |
38 | + case SBE_2T3E3_FRAME_TYPE_E3_G832: | |
39 | + case SBE_2T3E3_FRAME_TYPE_T3_CBIT: | |
40 | + case SBE_2T3E3_FRAME_TYPE_T3_M13: | |
41 | + break; | |
42 | + default: | |
43 | + return; | |
44 | + } | |
45 | + | |
46 | + exar7250_stop_intr(sc, type); | |
47 | + | |
48 | + val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE); | |
49 | + val &= ~(SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE | | |
50 | + SBE_2T3E3_FRAMER_VAL_T3_E3_SELECT | | |
51 | + SBE_2T3E3_FRAMER_VAL_FRAME_FORMAT_SELECT); | |
52 | + switch (type) { | |
53 | + case SBE_2T3E3_FRAME_TYPE_E3_G751: | |
54 | + val |= SBE_2T3E3_FRAMER_VAL_E3_G751; | |
55 | + break; | |
56 | + case SBE_2T3E3_FRAME_TYPE_E3_G832: | |
57 | + val |= SBE_2T3E3_FRAMER_VAL_E3_G832; | |
58 | + break; | |
59 | + case SBE_2T3E3_FRAME_TYPE_T3_CBIT: | |
60 | + val |= SBE_2T3E3_FRAMER_VAL_T3_CBIT; | |
61 | + break; | |
62 | + case SBE_2T3E3_FRAME_TYPE_T3_M13: | |
63 | + val |= SBE_2T3E3_FRAMER_VAL_T3_M13; | |
64 | + break; | |
65 | + default: | |
66 | + return; | |
67 | + } | |
68 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE, val); | |
69 | + exar7250_start_intr(sc, type); | |
70 | +} | |
71 | + | |
72 | + | |
73 | +void exar7250_start_intr(struct channel *sc, u32 type) | |
74 | +{ | |
75 | + u32 val; | |
76 | + | |
77 | + switch (type) { | |
78 | + case SBE_2T3E3_FRAME_TYPE_E3_G751: | |
79 | + case SBE_2T3E3_FRAME_TYPE_E3_G832: | |
80 | + val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2); | |
81 | +#if 0 | |
82 | + sc->s.LOS = val & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS ? 1 : 0; | |
83 | +#else | |
84 | + cpld_LOS_update(sc); | |
85 | +#endif | |
86 | + sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0; | |
87 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1); | |
88 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1, | |
89 | + SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE | | |
90 | + SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE); | |
91 | +#if 0 | |
92 | + /*SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_ENABLE | | |
93 | + SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE | | |
94 | + SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_ENABLE | | |
95 | + SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE | | |
96 | + SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_ENABLE);*/ | |
97 | +#endif | |
98 | + | |
99 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2); | |
100 | +#if 0 | |
101 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2, | |
102 | + SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_ENABLE | | |
103 | + SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_ENABLE | | |
104 | + SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_ENABLE); | |
105 | +#endif | |
106 | + break; | |
107 | + | |
108 | + case SBE_2T3E3_FRAME_TYPE_T3_CBIT: | |
109 | + case SBE_2T3E3_FRAME_TYPE_T3_M13: | |
110 | + val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS); | |
111 | +#if 0 | |
112 | + sc->s.LOS = val & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS ? 1 : 0; | |
113 | +#else | |
114 | + cpld_LOS_update(sc); | |
115 | +#endif | |
116 | + sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0; | |
117 | + | |
118 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS); | |
119 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE, | |
120 | + SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE | | |
121 | + SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE); | |
122 | +#if 0 | |
123 | + /* SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_ENABLE | | |
124 | + SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE | | |
125 | + SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_ENABLE | | |
126 | + SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_ENABLE | | |
127 | + SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_ENABLE | | |
128 | + SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_ENABLE | | |
129 | + SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE | | |
130 | + SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_ENABLE);*/ | |
131 | +#endif | |
132 | + | |
133 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS); | |
134 | +#if 0 | |
135 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS, | |
136 | + SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_ENABLE | | |
137 | + SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_ENABLE); | |
138 | +#endif | |
139 | + | |
140 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0); | |
141 | + break; | |
142 | + | |
143 | + default: | |
144 | + return; | |
145 | + } | |
146 | + | |
147 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS); | |
148 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, | |
149 | + SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE | | |
150 | + SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE); | |
151 | +} | |
152 | + | |
153 | + | |
154 | +void exar7250_stop_intr(struct channel *sc, u32 type) | |
155 | +{ | |
156 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, 0); | |
157 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS); | |
158 | + | |
159 | + switch (type) { | |
160 | + case SBE_2T3E3_FRAME_TYPE_E3_G751: | |
161 | + case SBE_2T3E3_FRAME_TYPE_E3_G832: | |
162 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1, 0); | |
163 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1); | |
164 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2, 0); | |
165 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2); | |
166 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL, 0); | |
167 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL); | |
168 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS, 0); | |
169 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS); | |
170 | + break; | |
171 | + | |
172 | + case SBE_2T3E3_FRAME_TYPE_T3_CBIT: | |
173 | + case SBE_2T3E3_FRAME_TYPE_T3_M13: | |
174 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE, 0); | |
175 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS); | |
176 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS, 0); | |
177 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS); | |
178 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0); | |
179 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL); | |
180 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS, 0); | |
181 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS); | |
182 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS, 0); | |
183 | + exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS); | |
184 | + break; | |
185 | + } | |
186 | +} | |
187 | + | |
188 | + | |
189 | + | |
190 | + | |
191 | +void exar7250_unipolar_onoff(struct channel *sc, u32 mode) | |
192 | +{ | |
193 | + switch (mode) { | |
194 | + case SBE_2T3E3_OFF: | |
195 | + exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL, | |
196 | + SBE_2T3E3_FRAMER_VAL_UNIPOLAR); | |
197 | + break; | |
198 | + case SBE_2T3E3_ON: | |
199 | + exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL, | |
200 | + SBE_2T3E3_FRAMER_VAL_UNIPOLAR); | |
201 | + break; | |
202 | + } | |
203 | +} | |
204 | + | |
205 | +void exar7250_set_loopback(struct channel *sc, u32 mode) | |
206 | +{ | |
207 | + switch (mode) { | |
208 | + case SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF: | |
209 | + exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE, | |
210 | + SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE); | |
211 | + break; | |
212 | + case SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON: | |
213 | + exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE, | |
214 | + SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE); | |
215 | + break; | |
216 | + } | |
217 | +} |
drivers/staging/sbe-2t3e3/exar7300.c
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#include "2t3e3.h" | |
14 | +#include "ctrl.h" | |
15 | + | |
16 | +void exar7300_init(struct channel *sc) | |
17 | +{ | |
18 | + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG1, 0); | |
19 | + | |
20 | + /* enable line decodeer and encoder */ | |
21 | + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG2, 0); | |
22 | + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG3, 0); | |
23 | + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, | |
24 | + SBE_2T3E3_LIU_VAL_T3_MODE_SELECT | | |
25 | + SBE_2T3E3_LIU_VAL_LOOPBACK_OFF); | |
26 | +} | |
27 | + | |
28 | +void exar7300_set_loopback(struct channel *sc, u32 mode) | |
29 | +{ | |
30 | + u32 val; | |
31 | + | |
32 | + switch (mode) { | |
33 | + case SBE_2T3E3_LIU_VAL_LOOPBACK_OFF: | |
34 | + case SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE: | |
35 | + case SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG: | |
36 | + case SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL: | |
37 | + break; | |
38 | + default: | |
39 | + return; | |
40 | + } | |
41 | + | |
42 | + val = exar7300_read(sc, SBE_2T3E3_LIU_REG_REG4); | |
43 | + val &= ~(SBE_2T3E3_LIU_VAL_LOCAL_LOOPBACK | SBE_2T3E3_LIU_VAL_REMOTE_LOOPBACK); | |
44 | + val |= mode; | |
45 | + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, val); | |
46 | + | |
47 | +#if 0 | |
48 | + /* TODO - is it necessary? idea from 2T3E3_HW_Test_code */ | |
49 | + switch (mode) { | |
50 | + case SBE_2T3E3_LIU_VAL_LOOPBACK_OFF: | |
51 | + break; | |
52 | + case SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE: | |
53 | + exar7300_receive_equalization_onoff(sc, SBE_2T3E3_ON); | |
54 | + break; | |
55 | + case SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG: | |
56 | + exar7300_receive_equalization_onoff(sc, SBE_2T3E3_OFF); | |
57 | + break; | |
58 | + case SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL: | |
59 | + exar7300_receive_equalization_onoff(sc, SBE_2T3E3_ON); | |
60 | + break; | |
61 | + } | |
62 | +#endif | |
63 | +} | |
64 | + | |
65 | +void exar7300_set_frame_type(struct channel *sc, u32 type) | |
66 | +{ | |
67 | + u32 val; | |
68 | + | |
69 | + switch (type) { | |
70 | + case SBE_2T3E3_FRAME_TYPE_T3_CBIT: | |
71 | + case SBE_2T3E3_FRAME_TYPE_T3_M13: | |
72 | + case SBE_2T3E3_FRAME_TYPE_E3_G751: | |
73 | + case SBE_2T3E3_FRAME_TYPE_E3_G832: | |
74 | + break; | |
75 | + default: | |
76 | + return; | |
77 | + } | |
78 | + | |
79 | + val = exar7300_read(sc, SBE_2T3E3_LIU_REG_REG4); | |
80 | + val &= ~(SBE_2T3E3_LIU_VAL_T3_MODE_SELECT | | |
81 | + SBE_2T3E3_LIU_VAL_E3_MODE_SELECT); | |
82 | + | |
83 | + switch (type) { | |
84 | + case SBE_2T3E3_FRAME_TYPE_T3_CBIT: | |
85 | + case SBE_2T3E3_FRAME_TYPE_T3_M13: | |
86 | + val |= SBE_2T3E3_LIU_VAL_T3_MODE_SELECT; | |
87 | + break; | |
88 | + case SBE_2T3E3_FRAME_TYPE_E3_G751: | |
89 | + case SBE_2T3E3_FRAME_TYPE_E3_G832: | |
90 | + val |= SBE_2T3E3_LIU_VAL_E3_MODE_SELECT; | |
91 | + break; | |
92 | + default: | |
93 | + return; | |
94 | + } | |
95 | + | |
96 | + exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, val); | |
97 | +} | |
98 | + | |
99 | + | |
100 | +void exar7300_transmit_all_ones_onoff(struct channel *sc, u32 mode) | |
101 | +{ | |
102 | + if (sc->p.transmit_all_ones == mode) | |
103 | + return; | |
104 | + | |
105 | + switch (mode) { | |
106 | + case SBE_2T3E3_ON: | |
107 | + exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1, | |
108 | + SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES); | |
109 | + break; | |
110 | + case SBE_2T3E3_OFF: | |
111 | + exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1, | |
112 | + SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES); | |
113 | + break; | |
114 | + default: | |
115 | + return; | |
116 | + } | |
117 | + | |
118 | + sc->p.transmit_all_ones = mode; | |
119 | +} | |
120 | + | |
121 | +void exar7300_receive_equalization_onoff(struct channel *sc, u32 mode) | |
122 | +{ | |
123 | + if (sc->p.receive_equalization == mode) | |
124 | + return; | |
125 | + | |
126 | + switch (mode) { | |
127 | + case SBE_2T3E3_OFF: | |
128 | + exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG2, | |
129 | + SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE); | |
130 | + break; | |
131 | + case SBE_2T3E3_ON: | |
132 | + exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG2, | |
133 | + SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE); | |
134 | + break; | |
135 | + default: | |
136 | + return; | |
137 | + } | |
138 | + | |
139 | + sc->p.receive_equalization = mode; | |
140 | +} | |
141 | + | |
142 | +void exar7300_line_build_out_onoff(struct channel *sc, u32 mode) | |
143 | +{ | |
144 | + if (sc->p.line_build_out == mode) | |
145 | + return; | |
146 | + | |
147 | + switch (mode) { | |
148 | + case SBE_2T3E3_OFF: | |
149 | + exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1, | |
150 | + SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT); | |
151 | + exar7300_receive_equalization_onoff(sc, SBE_2T3E3_OFF); | |
152 | + break; | |
153 | + case SBE_2T3E3_ON: | |
154 | + exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1, | |
155 | + SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT); | |
156 | + exar7300_receive_equalization_onoff(sc, SBE_2T3E3_ON); | |
157 | + break; | |
158 | + default: | |
159 | + return; | |
160 | + } | |
161 | + | |
162 | + sc->p.line_build_out = mode; | |
163 | +} | |
164 | + | |
165 | +/* TODO - what about encoder in raw mode??? disable it too? */ | |
166 | +void exar7300_unipolar_onoff(struct channel *sc, u32 mode) | |
167 | +{ | |
168 | + switch (mode) { | |
169 | + case SBE_2T3E3_OFF: | |
170 | + exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG3, | |
171 | + SBE_2T3E3_LIU_VAL_DECODER_DISABLE); | |
172 | + exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1, | |
173 | + SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA); | |
174 | + break; | |
175 | + case SBE_2T3E3_ON: | |
176 | + exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG3, | |
177 | + SBE_2T3E3_LIU_VAL_DECODER_DISABLE); | |
178 | + exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1, | |
179 | + SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA); | |
180 | + break; | |
181 | + } | |
182 | +} |
drivers/staging/sbe-2t3e3/intr.c
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#include <linux/hdlc.h> | |
14 | +#include <linux/interrupt.h> | |
15 | +#include <linux/netdevice.h> | |
16 | +#include "2t3e3.h" | |
17 | + | |
18 | +irqreturn_t t3e3_intr(int irq, void *dev_instance) | |
19 | +{ | |
20 | + struct channel *sc = dev_to_priv(dev_instance); | |
21 | + u32 val; | |
22 | + irqreturn_t ret = IRQ_NONE; | |
23 | + | |
24 | + sc->interrupt_active = 1; | |
25 | + | |
26 | + val = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR); | |
27 | + | |
28 | + if (val & SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_CHANGE) { | |
29 | + dev_dbg(&sc->pdev->dev, | |
30 | + "Rx LOS Chng Int r=%02x (LOS|OOF=%02x)\n", | |
31 | + val, (sc->s.LOS << 4) | sc->s.OOF); | |
32 | + cpld_LOS_update(sc); | |
33 | + ret = IRQ_HANDLED; | |
34 | + } | |
35 | + | |
36 | + if (val & SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ASSERTED) { | |
37 | + dc_intr(sc); | |
38 | + ret = IRQ_HANDLED; | |
39 | + } | |
40 | + | |
41 | + if (val & SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ASSERTED) { | |
42 | + exar7250_intr(sc); | |
43 | + ret = IRQ_HANDLED; | |
44 | + } | |
45 | + | |
46 | + /* | |
47 | + we don't care about other interrupt sources (DMO, LOS, LCV) because | |
48 | + they are handled by Framer too | |
49 | + */ | |
50 | + | |
51 | + sc->interrupt_active = 0; | |
52 | + return ret; | |
53 | +} | |
54 | + | |
55 | +void dc_intr(struct channel *sc) | |
56 | +{ | |
57 | + u32 val; | |
58 | + | |
59 | + /* disable ethernet interrupts */ | |
60 | + /* grrr this clears interrupt summary bits !!! */ | |
61 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0); | |
62 | + | |
63 | + while ((val = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS)) & | |
64 | + (SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED | | |
65 | + SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE | | |
66 | + SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT | | |
67 | + SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW | | |
68 | + SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE | | |
69 | + SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED | | |
70 | + SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT)) { | |
71 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, val); | |
72 | + | |
73 | + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Ethernet controller interrupt! (CSR5 = %08X)\n", | |
74 | + val); | |
75 | + | |
76 | + if (val & (SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT | | |
77 | + SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE | | |
78 | + SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED)) { | |
79 | + if (val & SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT) | |
80 | + dev_dbg(&sc->pdev->dev, | |
81 | + "Receive interrupt (LOS=%d, OOF=%d)\n", | |
82 | + sc->s.LOS, sc->s.OOF); | |
83 | + if (val & SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE) | |
84 | + dev_dbg(&sc->pdev->dev, | |
85 | + "Receive buffer unavailable\n"); | |
86 | + if (val & SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED) | |
87 | + dev_dbg(&sc->pdev->dev, | |
88 | + "Receive process stopped\n"); | |
89 | + dc_intr_rx(sc); | |
90 | + } | |
91 | + | |
92 | + if (val & SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW) { | |
93 | + dev_dbg(&sc->pdev->dev, "Transmit underflow\n"); | |
94 | + dc_intr_tx_underflow(sc); | |
95 | + } | |
96 | + | |
97 | + if (val & (SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE | | |
98 | + SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT | | |
99 | + SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED)) { | |
100 | + if (val & SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT) | |
101 | + dev_dbg(&sc->pdev->dev, "Transmit interrupt\n"); | |
102 | + if (val & SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE) | |
103 | + dev_dbg(&sc->pdev->dev, | |
104 | + "Transmit buffer unavailable\n"); | |
105 | + if (val & SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED) | |
106 | + dev_dbg(&sc->pdev->dev, | |
107 | + "Transmit process stopped\n"); | |
108 | + dc_intr_tx(sc); | |
109 | + } | |
110 | + } | |
111 | + | |
112 | + /* enable ethernet interrupts */ | |
113 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, | |
114 | + sc->ether.interrupt_enable_mask); | |
115 | +} | |
116 | + | |
117 | +void dc_intr_rx(struct channel *sc) | |
118 | +{ | |
119 | + u32 current_read; | |
120 | + u32 error_mask, error; | |
121 | + t3e3_rx_desc_t *current_desc; | |
122 | + struct sk_buff *m, *m2; | |
123 | + unsigned rcv_len; | |
124 | + | |
125 | + sc->rcv_count++; /* for the activity LED */ | |
126 | + | |
127 | + current_read = sc->ether.rx_ring_current_read; | |
128 | + dev_dbg(&sc->pdev->dev, "intr_rx current_read = %d\n", current_read); | |
129 | + | |
130 | + /* when ethernet loopback is set, ignore framer signals */ | |
131 | + if ((sc->p.loopback != SBE_2T3E3_LOOPBACK_ETHERNET) && sc->s.OOF) { | |
132 | + while (!(sc->ether.rx_ring[current_read].rdes0 & | |
133 | + SBE_2T3E3_RX_DESC_21143_OWN)) { | |
134 | + current_desc = &sc->ether.rx_ring[current_read]; | |
135 | + current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING | | |
136 | + SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED; | |
137 | + current_desc->rdes1 |= SBE_2T3E3_MTU; | |
138 | + current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN; | |
139 | + current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE; | |
140 | + } | |
141 | + sc->ether.rx_ring_current_read = current_read; | |
142 | + return; | |
143 | + } | |
144 | + | |
145 | + while (!(sc->ether.rx_ring[current_read].rdes0 & | |
146 | + SBE_2T3E3_RX_DESC_21143_OWN)) { | |
147 | + current_desc = &sc->ether.rx_ring[current_read]; | |
148 | + | |
149 | + dev_dbg(&sc->pdev->dev, "rdes0: %08X rdes1: %08X\n", | |
150 | + current_desc->rdes0, current_desc->rdes1); | |
151 | + | |
152 | + m = sc->ether.rx_data[current_read]; | |
153 | + rcv_len = (current_desc->rdes0 & SBE_2T3E3_RX_DESC_FRAME_LENGTH) >> | |
154 | + SBE_2T3E3_RX_DESC_FRAME_LENGTH_SHIFT; | |
155 | + | |
156 | + dev_dbg(&sc->pdev->dev, "mbuf was received (mbuf len = %d)\n", | |
157 | + rcv_len); | |
158 | + | |
159 | + switch (sc->p.crc) { | |
160 | + case SBE_2T3E3_CRC_16: | |
161 | + rcv_len -= SBE_2T3E3_CRC16_LENGTH; | |
162 | + break; | |
163 | + case SBE_2T3E3_CRC_32: | |
164 | + rcv_len -= SBE_2T3E3_CRC32_LENGTH; | |
165 | + break; | |
166 | + default: | |
167 | + break; | |
168 | + } | |
169 | + | |
170 | + if (current_desc->rdes0 & SBE_2T3E3_RX_DESC_LAST_DESC) { | |
171 | + | |
172 | + /* TODO: is collision possible? */ | |
173 | + error_mask = SBE_2T3E3_RX_DESC_DESC_ERROR | | |
174 | + SBE_2T3E3_RX_DESC_COLLISION_SEEN | | |
175 | + SBE_2T3E3_RX_DESC_DRIBBLING_BIT; | |
176 | + | |
177 | + switch (sc->p.frame_mode) { | |
178 | + case SBE_2T3E3_FRAME_MODE_HDLC: | |
179 | + error_mask |= SBE_2T3E3_RX_DESC_MII_ERROR; | |
180 | + if (sc->p.crc == SBE_2T3E3_CRC_32) | |
181 | + error_mask |= SBE_2T3E3_RX_DESC_CRC_ERROR; | |
182 | + break; | |
183 | + case SBE_2T3E3_FRAME_MODE_TRANSPARENT: | |
184 | + case SBE_2T3E3_FRAME_MODE_RAW: | |
185 | + break; | |
186 | + default: | |
187 | + error_mask = 0; | |
188 | + } | |
189 | + | |
190 | + if (sc->s.LOS) { | |
191 | + error_mask &= ~(SBE_2T3E3_RX_DESC_DRIBBLING_BIT || | |
192 | + SBE_2T3E3_RX_DESC_MII_ERROR); | |
193 | + } | |
194 | + | |
195 | + error = current_desc->rdes0 & error_mask; | |
196 | + if (error) { | |
197 | + sc->s.in_errors++; | |
198 | + dev_dbg(&sc->pdev->dev, | |
199 | + "error interrupt: NO_ERROR_MESSAGE = %d\n", | |
200 | + sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES ? 1 : 0); | |
201 | + | |
202 | + current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING | | |
203 | + SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED; | |
204 | + current_desc->rdes1 |= SBE_2T3E3_MTU; | |
205 | + current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN; | |
206 | + | |
207 | + if (error & SBE_2T3E3_RX_DESC_DESC_ERROR) { | |
208 | + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES)) | |
209 | + dev_err(&sc->pdev->dev, | |
210 | + "SBE 2T3E3: descriptor error\n"); | |
211 | + sc->s.in_error_desc++; | |
212 | + } | |
213 | + | |
214 | + if (error & SBE_2T3E3_RX_DESC_COLLISION_SEEN) { | |
215 | + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES)) | |
216 | + dev_err(&sc->pdev->dev, | |
217 | + "SBE 2T3E3: collision seen\n"); | |
218 | + sc->s.in_error_coll++; | |
219 | + } else { | |
220 | + if (error & SBE_2T3E3_RX_DESC_DRIBBLING_BIT) { | |
221 | + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES)) | |
222 | + dev_err(&sc->pdev->dev, | |
223 | + "SBE 2T3E3: dribbling bits error\n"); | |
224 | + sc->s.in_error_drib++; | |
225 | + } | |
226 | + | |
227 | + if (error & SBE_2T3E3_RX_DESC_CRC_ERROR) { | |
228 | + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES)) | |
229 | + dev_err(&sc->pdev->dev, | |
230 | + "SBE 2T3E3: crc error\n"); | |
231 | + sc->s.in_error_crc++; | |
232 | + } | |
233 | + } | |
234 | + | |
235 | + if (error & SBE_2T3E3_RX_DESC_MII_ERROR) { | |
236 | + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES)) | |
237 | + dev_err(&sc->pdev->dev, "SBE 2T3E3: mii error\n"); | |
238 | + sc->s.in_error_mii++; | |
239 | + } | |
240 | + | |
241 | + current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE; | |
242 | + sc->r.flags |= SBE_2T3E3_FLAG_NO_ERROR_MESSAGES; | |
243 | + continue; | |
244 | + } | |
245 | + } | |
246 | + | |
247 | + current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING | | |
248 | + SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED; | |
249 | + current_desc->rdes1 |= SBE_2T3E3_MTU; | |
250 | + | |
251 | + if (rcv_len > 1600) { | |
252 | + sc->s.in_errors++; | |
253 | + sc->s.in_dropped++; | |
254 | + if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES)) | |
255 | + dev_err(&sc->pdev->dev, "SBE 2T3E3: oversized rx: rdes0 = %08X\n", | |
256 | + current_desc->rdes0); | |
257 | + } else { | |
258 | + m2 = dev_alloc_skb(MCLBYTES); | |
259 | + if (m2 != NULL) { | |
260 | + current_desc->rdes2 = virt_to_phys(m2->data); | |
261 | + sc->ether.rx_data[current_read] = m2; | |
262 | + sc->s.in_packets++; | |
263 | + sc->s.in_bytes += rcv_len; | |
264 | + m->dev = sc->dev; | |
265 | + skb_put(m, rcv_len); | |
266 | + skb_reset_mac_header(m); | |
267 | + m->protocol = hdlc_type_trans(m, m->dev); | |
268 | + netif_rx(m); | |
269 | + | |
270 | + /* good packet was received so we will show error messages again... */ | |
271 | + if (sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES) { | |
272 | + dev_dbg(&sc->pdev->dev, | |
273 | + "setting ERROR_MESSAGES->0\n"); | |
274 | + sc->r.flags &= ~SBE_2T3E3_FLAG_NO_ERROR_MESSAGES; | |
275 | + } | |
276 | + | |
277 | + } else { | |
278 | + sc->s.in_errors++; | |
279 | + sc->s.in_dropped++; | |
280 | + } | |
281 | + } | |
282 | + current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN; | |
283 | + current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE; | |
284 | + } | |
285 | + | |
286 | + sc->ether.rx_ring_current_read = current_read; | |
287 | + | |
288 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND, 0xFFFFFFFF); | |
289 | +} | |
290 | + | |
291 | +void dc_intr_tx(struct channel *sc) | |
292 | +{ | |
293 | + u32 current_read, current_write; | |
294 | + u32 last_segment, error; | |
295 | + t3e3_tx_desc_t *current_desc; | |
296 | + | |
297 | + spin_lock(&sc->ether.tx_lock); | |
298 | + | |
299 | + current_read = sc->ether.tx_ring_current_read; | |
300 | + current_write = sc->ether.tx_ring_current_write; | |
301 | + | |
302 | + while (current_read != current_write) { | |
303 | + current_desc = &sc->ether.tx_ring[current_read]; | |
304 | + | |
305 | + if (current_desc->tdes0 & SBE_2T3E3_RX_DESC_21143_OWN) | |
306 | + break; | |
307 | + | |
308 | + dev_dbg(&sc->pdev->dev, | |
309 | + "txeof: tdes0 = %08X tdes1 = %08X\n", | |
310 | + current_desc->tdes0, current_desc->tdes1); | |
311 | + | |
312 | + error = current_desc->tdes0 & (SBE_2T3E3_TX_DESC_ERROR_SUMMARY | | |
313 | + SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT | | |
314 | + SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER | | |
315 | + SBE_2T3E3_TX_DESC_NO_CARRIER | | |
316 | + SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT | | |
317 | + SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR | | |
318 | + SBE_2T3E3_TX_DESC_DEFFERED); | |
319 | + | |
320 | + last_segment = current_desc->tdes1 & SBE_2T3E3_TX_DESC_LAST_SEGMENT; | |
321 | + | |
322 | + current_desc->tdes0 = 0; | |
323 | + current_desc->tdes1 &= SBE_2T3E3_TX_DESC_END_OF_RING | | |
324 | + SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED; | |
325 | + current_desc->tdes2 = 0; | |
326 | + sc->ether.tx_free_cnt++; | |
327 | + | |
328 | + if (last_segment != SBE_2T3E3_TX_DESC_LAST_SEGMENT) { | |
329 | + current_read = (current_read + 1) % SBE_2T3E3_TX_DESC_RING_SIZE; | |
330 | + continue; | |
331 | + } | |
332 | + | |
333 | + | |
334 | + if (sc->ether.tx_data[current_read]) { | |
335 | + sc->s.out_packets++; | |
336 | + sc->s.out_bytes += sc->ether.tx_data[current_read]->len; | |
337 | + dev_kfree_skb_any(sc->ether.tx_data[current_read]); | |
338 | + sc->ether.tx_data[current_read] = NULL; | |
339 | + } | |
340 | + | |
341 | + if (error > 0) { | |
342 | + sc->s.out_errors++; | |
343 | + | |
344 | + if (error & SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT) { | |
345 | + dev_err(&sc->pdev->dev, "SBE 2T3E3: transmit jabber timeout\n"); | |
346 | + sc->s.out_error_jab++; | |
347 | + } | |
348 | + | |
349 | + if (sc->p.loopback != SBE_2T3E3_LOOPBACK_ETHERNET) { | |
350 | + if (error & SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER) { | |
351 | + dev_err(&sc->pdev->dev, "SBE 2T3E3: loss of carrier\n"); | |
352 | + sc->s.out_error_lost_carr++; | |
353 | + } | |
354 | + | |
355 | + if (error & SBE_2T3E3_TX_DESC_NO_CARRIER) { | |
356 | + dev_err(&sc->pdev->dev, "SBE 2T3E3: no carrier\n"); | |
357 | + sc->s.out_error_no_carr++; | |
358 | + } | |
359 | + } | |
360 | + | |
361 | + if (error & SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT) { | |
362 | + dev_err(&sc->pdev->dev, "SBE 2T3E3: link fail report\n"); | |
363 | + sc->s.out_error_link_fail++; | |
364 | + } | |
365 | + | |
366 | + if (error & SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR) { | |
367 | + dev_err(&sc->pdev->dev, "SBE 2T3E3:" | |
368 | + " transmission underflow error\n"); | |
369 | + sc->s.out_error_underflow++; | |
370 | + spin_unlock(&sc->ether.tx_lock); | |
371 | + | |
372 | + dc_restart(sc); | |
373 | + return; | |
374 | + } | |
375 | + | |
376 | + if (error & SBE_2T3E3_TX_DESC_DEFFERED) { | |
377 | + dev_err(&sc->pdev->dev, "SBE 2T3E3: transmission deferred\n"); | |
378 | + sc->s.out_error_dereferred++; | |
379 | + } | |
380 | + } | |
381 | + | |
382 | + current_read = (current_read + 1) % SBE_2T3E3_TX_DESC_RING_SIZE; | |
383 | + } | |
384 | + | |
385 | + sc->ether.tx_ring_current_read = current_read; | |
386 | + | |
387 | + /* Relieve flow control when the TX queue is drained at least half way */ | |
388 | + if (sc->ether.tx_full && | |
389 | + (sc->ether.tx_free_cnt >= (SBE_2T3E3_TX_DESC_RING_SIZE / 2))) { | |
390 | + sc->ether.tx_full = 0; | |
391 | + netif_wake_queue(sc->dev); | |
392 | + } | |
393 | + spin_unlock(&sc->ether.tx_lock); | |
394 | +} | |
395 | + | |
396 | + | |
397 | +void dc_intr_tx_underflow(struct channel *sc) | |
398 | +{ | |
399 | + u32 val; | |
400 | + | |
401 | + dc_transmitter_onoff(sc, SBE_2T3E3_OFF); | |
402 | + | |
403 | + val = dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE); | |
404 | + dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
405 | + SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS); | |
406 | + | |
407 | + switch (val & SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS) { | |
408 | + case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1: | |
409 | + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
410 | + SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2); | |
411 | + break; | |
412 | + case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2: | |
413 | + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
414 | + SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3); | |
415 | + break; | |
416 | + case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3: | |
417 | + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
418 | + SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4); | |
419 | + break; | |
420 | + case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4: | |
421 | + default: | |
422 | + dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
423 | + SBE_2T3E3_21143_VAL_STORE_AND_FORWARD); | |
424 | + break; | |
425 | + } | |
426 | + | |
427 | + dc_transmitter_onoff(sc, SBE_2T3E3_ON); | |
428 | +} | |
429 | + | |
430 | + | |
431 | + | |
432 | + | |
433 | +void exar7250_intr(struct channel *sc) | |
434 | +{ | |
435 | + u32 status, old_OOF; | |
436 | + | |
437 | +#if 0 | |
438 | + /* disable interrupts */ | |
439 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, 0); | |
440 | +#endif | |
441 | + | |
442 | + old_OOF = sc->s.OOF; | |
443 | + | |
444 | + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS); | |
445 | + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt! (REG[0x05] = %02X)\n", status); | |
446 | + | |
447 | + switch (sc->p.frame_type) { | |
448 | + case SBE_2T3E3_FRAME_TYPE_E3_G751: | |
449 | + case SBE_2T3E3_FRAME_TYPE_E3_G832: | |
450 | + exar7250_E3_intr(sc, status); | |
451 | + break; | |
452 | + | |
453 | + case SBE_2T3E3_FRAME_TYPE_T3_CBIT: | |
454 | + case SBE_2T3E3_FRAME_TYPE_T3_M13: | |
455 | + exar7250_T3_intr(sc, status); | |
456 | + break; | |
457 | + | |
458 | + default: | |
459 | + break; | |
460 | + } | |
461 | + | |
462 | + if (sc->s.OOF != old_OOF) { | |
463 | + if (sc->s.OOF) { | |
464 | + if (sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE) { | |
465 | + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Disabling eth interrupts\n"); | |
466 | + /* turn off ethernet interrupts */ | |
467 | + dc_stop_intr(sc); | |
468 | + } | |
469 | + } else if (sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP) { | |
470 | + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Enabling eth interrupts\n"); | |
471 | + /* start interrupts */ | |
472 | + sc->s.OOF = 1; | |
473 | + dc_intr_rx(sc); | |
474 | + sc->s.OOF = 0; | |
475 | + if (sc->p.receiver_on) { | |
476 | + dc_receiver_onoff(sc, SBE_2T3E3_OFF); | |
477 | + dc_receiver_onoff(sc, SBE_2T3E3_ON); | |
478 | + } | |
479 | + dc_start_intr(sc); | |
480 | + } | |
481 | + } | |
482 | +#if 0 | |
483 | + /* reenable interrupts */ | |
484 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, | |
485 | + SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE | | |
486 | + SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE | |
487 | + ); | |
488 | +#endif | |
489 | +} | |
490 | + | |
491 | + | |
492 | +void exar7250_T3_intr(struct channel *sc, u32 block_status) | |
493 | +{ | |
494 | + u32 status, result; | |
495 | + | |
496 | + if (block_status & SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS) { | |
497 | + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS); | |
498 | + | |
499 | + if (status) { | |
500 | + dev_dbg(&sc->pdev->dev, | |
501 | + "Framer interrupt T3 RX (REG[0x13] = %02X)\n", | |
502 | + status); | |
503 | + | |
504 | + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS); | |
505 | + | |
506 | +#if 0 | |
507 | + if (status & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_STATUS) { | |
508 | + dev_dbg(&sc->pdev->dev, | |
509 | + "Framer interrupt T3: LOS\n"); | |
510 | + sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS ? 1 : 0; | |
511 | + | |
512 | + } | |
513 | +#else | |
514 | + cpld_LOS_update(sc); | |
515 | +#endif | |
516 | + if (status & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_STATUS) { | |
517 | + sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0; | |
518 | + dev_dbg(&sc->pdev->dev, | |
519 | + "Framer interrupt T3: OOF (%d)\n", | |
520 | + sc->s.OOF); | |
521 | + } | |
522 | + | |
523 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE, | |
524 | + SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE | | |
525 | + SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE); | |
526 | +#if 0 | |
527 | + SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_ENABLE | | |
528 | + SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE | | |
529 | + SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_ENABLE | | |
530 | + SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_ENABLE | | |
531 | + SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_ENABLE | | |
532 | + SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_ENABLE | | |
533 | + SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE | | |
534 | + SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_ENABLE | |
535 | +#endif | |
536 | + } | |
537 | + | |
538 | + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS); | |
539 | + if (status) { | |
540 | + dev_dbg(&sc->pdev->dev, | |
541 | + "Framer interrupt T3 RX (REG[0x17] = %02X)\n", | |
542 | + status); | |
543 | +#if 0 | |
544 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS, | |
545 | + SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_ENABLE | | |
546 | + SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_ENABLE | |
547 | + ); | |
548 | +#endif | |
549 | + } | |
550 | + | |
551 | + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL); | |
552 | + if (status) | |
553 | + dev_dbg(&sc->pdev->dev, | |
554 | + "Framer interrupt T3 RX (REG[0x18] = %02X)\n", | |
555 | + status); | |
556 | + } | |
557 | + | |
558 | + | |
559 | + if (block_status & SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS) { | |
560 | + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS); | |
561 | + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt T3 TX (REG[0x31] = %02X)\n", | |
562 | + status); | |
563 | + | |
564 | + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS); | |
565 | + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt T3 TX (REG[0x34] = %02X)\n", | |
566 | + status); | |
567 | + } | |
568 | +} | |
569 | + | |
570 | + | |
571 | +void exar7250_E3_intr(struct channel *sc, u32 block_status) | |
572 | +{ | |
573 | + u32 status, result; | |
574 | + | |
575 | + if (block_status & SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS) { | |
576 | + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1); | |
577 | + | |
578 | + if (status) { | |
579 | + dev_dbg(&sc->pdev->dev, | |
580 | + "Framer interrupt E3 RX (REG[0x14] = %02X)\n", | |
581 | + status); | |
582 | + | |
583 | + result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2); | |
584 | + | |
585 | +#if 0 | |
586 | + if (status & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_STATUS) { | |
587 | + dev_dbg(&sc->pdev->dev, | |
588 | + "Framer interrupt E3: LOS\n"); | |
589 | + sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS ? 1 : 0; | |
590 | + } | |
591 | +#else | |
592 | + cpld_LOS_update(sc); | |
593 | +#endif | |
594 | + if (status & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_STATUS) { | |
595 | + sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0; | |
596 | + dev_dbg(&sc->pdev->dev, | |
597 | + "Framer interrupt E3: OOF (%d)\n", | |
598 | + sc->s.OOF); | |
599 | + } | |
600 | + | |
601 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1, | |
602 | + SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE | | |
603 | + SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE | |
604 | + ); | |
605 | +#if 0 | |
606 | + SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_ENABLE | | |
607 | + SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE | | |
608 | + SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_ENABLE | | |
609 | + SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE | | |
610 | + SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_ENABLE | |
611 | +#endif | |
612 | + } | |
613 | + | |
614 | + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2); | |
615 | + if (status) { | |
616 | + dev_dbg(&sc->pdev->dev, | |
617 | + "Framer interrupt E3 RX (REG[0x15] = %02X)\n", | |
618 | + status); | |
619 | + | |
620 | +#if 0 | |
621 | + exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2, | |
622 | + SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_ENABLE | | |
623 | + SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_ENABLE | | |
624 | + SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_ENABLE); | |
625 | +#endif | |
626 | + } | |
627 | + | |
628 | + } | |
629 | + | |
630 | + if (block_status & SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS) { | |
631 | + status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS); | |
632 | + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt E3 TX (REG[0x34] = %02X)\n", | |
633 | + status); | |
634 | + } | |
635 | +} |
drivers/staging/sbe-2t3e3/io.c
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#include <linux/ip.h> | |
14 | +#include <asm/system.h> | |
15 | +#include "2t3e3.h" | |
16 | +#include "ctrl.h" | |
17 | + | |
18 | +/* All access to registers done via the 21143 on port 0 must be | |
19 | + * protected via the card->bootrom_lock. */ | |
20 | + | |
21 | +/* priviate define to be used here only - must be protected by card->bootrom_lock */ | |
22 | +#define cpld_write_nolock(channel, reg, val) \ | |
23 | + bootrom_write((channel), CPLD_MAP_REG(reg, channel), val) | |
24 | + | |
25 | +u32 cpld_read(struct channel *channel, u32 reg) | |
26 | +{ | |
27 | + unsigned long flags; | |
28 | + u32 val; | |
29 | + | |
30 | + spin_lock_irqsave(&channel->card->bootrom_lock, flags); | |
31 | + val = bootrom_read((channel), CPLD_MAP_REG(reg, channel)); | |
32 | + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags); | |
33 | + return val; | |
34 | +} | |
35 | + | |
36 | +/**************************************** | |
37 | + * Access via BootROM port | |
38 | + ****************************************/ | |
39 | + | |
40 | +u32 bootrom_read(struct channel *channel, u32 reg) | |
41 | +{ | |
42 | + unsigned long addr = channel->card->bootrom_addr; | |
43 | + u32 result; | |
44 | + | |
45 | + /* select BootROM address */ | |
46 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS, reg & 0x3FFFF); | |
47 | + | |
48 | + /* select reading from BootROM */ | |
49 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
50 | + SBE_2T3E3_21143_VAL_READ_OPERATION | | |
51 | + SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT); | |
52 | + | |
53 | + udelay(2); /* 20 PCI cycles */ | |
54 | + | |
55 | + /* read from BootROM */ | |
56 | + result = dc_read(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT) & 0xff; | |
57 | + | |
58 | + /* reset CSR9 */ | |
59 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0); | |
60 | + | |
61 | + return result; | |
62 | +} | |
63 | + | |
64 | +void bootrom_write(struct channel *channel, u32 reg, u32 val) | |
65 | +{ | |
66 | + unsigned long addr = channel->card->bootrom_addr; | |
67 | + | |
68 | + /* select BootROM address */ | |
69 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS, reg & 0x3FFFF); | |
70 | + | |
71 | + /* select writting to BootROM */ | |
72 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
73 | + SBE_2T3E3_21143_VAL_WRITE_OPERATION | | |
74 | + SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT | | |
75 | + (val & 0xff)); | |
76 | + | |
77 | + udelay(2); /* 20 PCI cycles */ | |
78 | + | |
79 | + /* reset CSR9 */ | |
80 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0); | |
81 | +} | |
82 | + | |
83 | + | |
84 | +/**************************************** | |
85 | + * Access via Serial I/O port | |
86 | + ****************************************/ | |
87 | + | |
88 | +static u32 serialrom_read_bit(struct channel *channel) | |
89 | +{ | |
90 | + unsigned long addr = channel->card->bootrom_addr; | |
91 | + u32 bit; | |
92 | + | |
93 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
94 | + SBE_2T3E3_21143_VAL_READ_OPERATION | | |
95 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT | | |
96 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK | | |
97 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock high */ | |
98 | + | |
99 | + bit = (dc_read(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT) & | |
100 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_OUT) > 0 ? 1 : 0; | |
101 | + | |
102 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
103 | + SBE_2T3E3_21143_VAL_READ_OPERATION | | |
104 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT | | |
105 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */ | |
106 | + | |
107 | + return bit; | |
108 | +} | |
109 | + | |
110 | +static void serialrom_write_bit(struct channel *channel, u32 bit) | |
111 | +{ | |
112 | + unsigned long addr = channel->card->bootrom_addr; | |
113 | + u32 lastbit = -1; | |
114 | + | |
115 | + bit &= 1; | |
116 | + | |
117 | + if (bit != lastbit) { | |
118 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
119 | + SBE_2T3E3_21143_VAL_WRITE_OPERATION | | |
120 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT | | |
121 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT | | |
122 | + (bit << 2)); /* clock low */ | |
123 | + | |
124 | + lastbit = bit; | |
125 | + } | |
126 | + | |
127 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
128 | + SBE_2T3E3_21143_VAL_WRITE_OPERATION | | |
129 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT | | |
130 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK | | |
131 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT | | |
132 | + (bit << 2)); /* clock high */ | |
133 | + | |
134 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
135 | + SBE_2T3E3_21143_VAL_WRITE_OPERATION | | |
136 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT | | |
137 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT | | |
138 | + (bit << 2)); /* clock low */ | |
139 | +} | |
140 | + | |
141 | +/**************************************** | |
142 | + * Access to SerialROM (eeprom) | |
143 | + ****************************************/ | |
144 | + | |
145 | +u32 t3e3_eeprom_read_word(struct channel *channel, u32 address) | |
146 | +{ | |
147 | + unsigned long addr = channel->card->bootrom_addr; | |
148 | + u32 i, val; | |
149 | + unsigned long flags; | |
150 | + | |
151 | + address &= 0x3f; | |
152 | + | |
153 | + spin_lock_irqsave(&channel->card->bootrom_lock, flags); | |
154 | + | |
155 | + /* select correct Serial Chip */ | |
156 | + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, | |
157 | + SBE_2T3E3_CPLD_VAL_EEPROM_SELECT); | |
158 | + | |
159 | + /* select reading from Serial I/O Bus */ | |
160 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
161 | + SBE_2T3E3_21143_VAL_READ_OPERATION | | |
162 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT | | |
163 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */ | |
164 | + | |
165 | + /* select read operation */ | |
166 | + serialrom_write_bit(channel, 0); | |
167 | + serialrom_write_bit(channel, 1); | |
168 | + serialrom_write_bit(channel, 1); | |
169 | + serialrom_write_bit(channel, 0); | |
170 | + | |
171 | + for (i = 0x20; i; i >>= 1) | |
172 | + serialrom_write_bit(channel, address & i ? 1 : 0); | |
173 | + | |
174 | + val = 0; | |
175 | + for (i = 0x8000; i; i >>= 1) | |
176 | + val |= (serialrom_read_bit(channel) ? i : 0); | |
177 | + | |
178 | + /* Reset 21143's CSR9 */ | |
179 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
180 | + SBE_2T3E3_21143_VAL_READ_OPERATION | | |
181 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT | | |
182 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */ | |
183 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0); | |
184 | + | |
185 | + /* Unselect Serial Chip */ | |
186 | + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0); | |
187 | + | |
188 | + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags); | |
189 | + | |
190 | + return ntohs(val); | |
191 | +} | |
192 | + | |
193 | + | |
194 | +/**************************************** | |
195 | + * Access to Framer | |
196 | + ****************************************/ | |
197 | + | |
198 | +u32 exar7250_read(struct channel *channel, u32 reg) | |
199 | +{ | |
200 | + u32 result; | |
201 | + unsigned long flags; | |
202 | + | |
203 | +#if 0 | |
204 | + switch (reg) { | |
205 | + case SBE_2T3E3_FRAMER_REG_OPERATING_MODE: | |
206 | + return channel->framer_regs[reg]; | |
207 | + break; | |
208 | + default: | |
209 | + } | |
210 | +#endif | |
211 | + | |
212 | + spin_lock_irqsave(&channel->card->bootrom_lock, flags); | |
213 | + | |
214 | + result = bootrom_read(channel, cpld_reg_map[SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS] | |
215 | + [channel->h.slot] + (t3e3_framer_reg_map[reg] << 2)); | |
216 | + | |
217 | + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags); | |
218 | + | |
219 | + return result; | |
220 | +} | |
221 | + | |
222 | +void exar7250_write(struct channel *channel, u32 reg, u32 val) | |
223 | +{ | |
224 | + unsigned long flags; | |
225 | + | |
226 | + val &= 0xff; | |
227 | + channel->framer_regs[reg] = val; | |
228 | + | |
229 | + spin_lock_irqsave(&channel->card->bootrom_lock, flags); | |
230 | + | |
231 | + bootrom_write(channel, cpld_reg_map[SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS] | |
232 | + [channel->h.slot] + (t3e3_framer_reg_map[reg] << 2), val); | |
233 | + | |
234 | + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags); | |
235 | +} | |
236 | + | |
237 | + | |
238 | +/**************************************** | |
239 | + * Access to LIU | |
240 | + ****************************************/ | |
241 | + | |
242 | +u32 exar7300_read(struct channel *channel, u32 reg) | |
243 | +{ | |
244 | + unsigned long addr = channel->card->bootrom_addr, flags; | |
245 | + u32 i, val; | |
246 | + | |
247 | +#if 0 | |
248 | + switch (reg) { | |
249 | + case SBE_2T3E3_LIU_REG_REG1: | |
250 | + case SBE_2T3E3_LIU_REG_REG2: | |
251 | + case SBE_2T3E3_LIU_REG_REG3: | |
252 | + case SBE_2T3E3_LIU_REG_REG4: | |
253 | + return channel->liu_regs[reg]; | |
254 | + break; | |
255 | + default: | |
256 | + } | |
257 | +#endif | |
258 | + | |
259 | + /* select correct Serial Chip */ | |
260 | + | |
261 | + spin_lock_irqsave(&channel->card->bootrom_lock, flags); | |
262 | + | |
263 | + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, | |
264 | + cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_SELECT][channel->h.slot]); | |
265 | + | |
266 | + /* select reading from Serial I/O Bus */ | |
267 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
268 | + SBE_2T3E3_21143_VAL_READ_OPERATION | | |
269 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT | | |
270 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */ | |
271 | + | |
272 | + /* select read operation */ | |
273 | + serialrom_write_bit(channel, 1); | |
274 | + | |
275 | + /* Exar7300 register address is 4 bit long */ | |
276 | + reg = t3e3_liu_reg_map[reg]; | |
277 | + for (i = 0; i < 4; i++, reg >>= 1) /* 4 bits of SerialROM address */ | |
278 | + serialrom_write_bit(channel, reg & 1); | |
279 | + for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM address */ | |
280 | + serialrom_write_bit(channel, 0); | |
281 | + | |
282 | + val = 0; /* Exar7300 register value is 5 bit long */ | |
283 | + for (i = 0; i < 8; i++) /* 8 bits of SerialROM value */ | |
284 | + val += (serialrom_read_bit(channel) << i); | |
285 | + | |
286 | + /* Reset 21143's CSR9 */ | |
287 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
288 | + SBE_2T3E3_21143_VAL_READ_OPERATION | | |
289 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT | | |
290 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */ | |
291 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0); | |
292 | + | |
293 | + /* Unselect Serial Chip */ | |
294 | + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0); | |
295 | + | |
296 | + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags); | |
297 | + | |
298 | + return val; | |
299 | +} | |
300 | + | |
301 | +void exar7300_write(struct channel *channel, u32 reg, u32 val) | |
302 | +{ | |
303 | + unsigned long addr = channel->card->bootrom_addr, flags; | |
304 | + u32 i; | |
305 | + | |
306 | + channel->liu_regs[reg] = val; | |
307 | + | |
308 | + /* select correct Serial Chip */ | |
309 | + | |
310 | + spin_lock_irqsave(&channel->card->bootrom_lock, flags); | |
311 | + | |
312 | + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, | |
313 | + cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_SELECT][channel->h.slot]); | |
314 | + | |
315 | + /* select writting to Serial I/O Bus */ | |
316 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
317 | + SBE_2T3E3_21143_VAL_WRITE_OPERATION | | |
318 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT | | |
319 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */ | |
320 | + | |
321 | + /* select write operation */ | |
322 | + serialrom_write_bit(channel, 0); | |
323 | + | |
324 | + /* Exar7300 register address is 4 bit long */ | |
325 | + reg = t3e3_liu_reg_map[reg]; | |
326 | + for (i = 0; i < 4; i++) { /* 4 bits */ | |
327 | + serialrom_write_bit(channel, reg & 1); | |
328 | + reg >>= 1; | |
329 | + } | |
330 | + for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM address */ | |
331 | + serialrom_write_bit(channel, 0); | |
332 | + | |
333 | + /* Exar7300 register value is 5 bit long */ | |
334 | + for (i = 0; i < 5; i++) { | |
335 | + serialrom_write_bit(channel, val & 1); | |
336 | + val >>= 1; | |
337 | + } | |
338 | + for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM value */ | |
339 | + serialrom_write_bit(channel, 0); | |
340 | + | |
341 | + /* Reset 21143_CSR9 */ | |
342 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, | |
343 | + SBE_2T3E3_21143_VAL_WRITE_OPERATION | | |
344 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT | | |
345 | + SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */ | |
346 | + dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0); | |
347 | + | |
348 | + /* Unselect Serial Chip */ | |
349 | + cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0); | |
350 | + | |
351 | + spin_unlock_irqrestore(&channel->card->bootrom_lock, flags); | |
352 | +} |
drivers/staging/sbe-2t3e3/main.c
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#include <linux/interrupt.h> | |
14 | +#include <linux/netdevice.h> | |
15 | +#include "2t3e3.h" | |
16 | + | |
17 | +void t3e3_init(struct channel *sc) | |
18 | +{ | |
19 | + cpld_init(sc); | |
20 | + dc_reset(sc); | |
21 | + dc_init(sc); | |
22 | + exar7250_init(sc); | |
23 | + exar7300_init(sc); | |
24 | +} | |
25 | + | |
26 | +int t3e3_if_start_xmit(struct sk_buff *skb, struct net_device *dev) | |
27 | +{ | |
28 | + struct channel *sc = dev_to_priv(dev); | |
29 | + u32 current_write, last_write; | |
30 | + unsigned long flags; | |
31 | + struct sk_buff *skb2; | |
32 | + | |
33 | + if (skb == NULL) { | |
34 | + sc->s.out_errors++; | |
35 | + return 0; | |
36 | + } | |
37 | + | |
38 | + if (sc->p.transmitter_on != SBE_2T3E3_ON) { | |
39 | + sc->s.out_errors++; | |
40 | + sc->s.out_dropped++; | |
41 | + dev_kfree_skb_any(skb); | |
42 | + return 0; | |
43 | + } | |
44 | + | |
45 | + if (sc->s.OOF && sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE) { | |
46 | + sc->s.out_dropped++; | |
47 | + dev_kfree_skb_any(skb); | |
48 | + return 0; | |
49 | + } | |
50 | + | |
51 | + spin_lock_irqsave(&sc->ether.tx_lock, flags); | |
52 | + | |
53 | + current_write = sc->ether.tx_ring_current_write; | |
54 | + for (skb2 = skb; skb2 != NULL; skb2 = NULL) { | |
55 | + if (skb2->len) { | |
56 | + if ((sc->ether.tx_ring[current_write].tdes1 & | |
57 | + SBE_2T3E3_TX_DESC_BUFFER_1_SIZE) > 0) | |
58 | + break; | |
59 | + current_write = (current_write + 1) % SBE_2T3E3_TX_DESC_RING_SIZE; | |
60 | + /* | |
61 | + * Leave at least 1 tx desc free so that dc_intr_tx() can | |
62 | + * identify empty list | |
63 | + */ | |
64 | + if (current_write == sc->ether.tx_ring_current_read) | |
65 | + break; | |
66 | + } | |
67 | + } | |
68 | + if (skb2 != NULL) { | |
69 | + netif_stop_queue(sc->dev); | |
70 | + sc->ether.tx_full = 1; | |
71 | + dev_dbg(&sc->pdev->dev, "SBE 2T3E3: out of descriptors\n"); | |
72 | + spin_unlock_irqrestore(&sc->ether.tx_lock, flags); | |
73 | + return NETDEV_TX_BUSY; | |
74 | + } | |
75 | + | |
76 | + current_write = last_write = sc->ether.tx_ring_current_write; | |
77 | + dev_dbg(&sc->pdev->dev, "sending mbuf (current_write = %d)\n", | |
78 | + current_write); | |
79 | + | |
80 | + for (skb2 = skb; skb2 != NULL; skb2 = NULL) { | |
81 | + if (skb2->len) { | |
82 | + dev_dbg(&sc->pdev->dev, | |
83 | + "sending mbuf (len = %d, next = %p)\n", | |
84 | + skb2->len, NULL); | |
85 | + | |
86 | + sc->ether.tx_free_cnt--; | |
87 | + sc->ether.tx_ring[current_write].tdes0 = 0; | |
88 | + sc->ether.tx_ring[current_write].tdes1 &= | |
89 | + SBE_2T3E3_TX_DESC_END_OF_RING | | |
90 | + SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED; | |
91 | +/* DISABLE_PADDING sometimes gets lost somehow, hands off... */ | |
92 | + sc->ether.tx_ring[current_write].tdes1 |= | |
93 | + SBE_2T3E3_TX_DESC_DISABLE_PADDING | skb2->len; | |
94 | + | |
95 | + if (current_write == sc->ether.tx_ring_current_write) { | |
96 | + sc->ether.tx_ring[current_write].tdes1 |= | |
97 | + SBE_2T3E3_TX_DESC_FIRST_SEGMENT; | |
98 | + } else { | |
99 | + sc->ether.tx_ring[current_write].tdes0 = | |
100 | + SBE_2T3E3_TX_DESC_21143_OWN; | |
101 | + } | |
102 | + | |
103 | + sc->ether.tx_ring[current_write].tdes2 = virt_to_phys(skb2->data); | |
104 | + sc->ether.tx_data[current_write] = NULL; | |
105 | + | |
106 | + last_write = current_write; | |
107 | + current_write = (current_write + 1) % SBE_2T3E3_TX_DESC_RING_SIZE; | |
108 | + } | |
109 | + } | |
110 | + | |
111 | + sc->ether.tx_data[last_write] = skb; | |
112 | + sc->ether.tx_ring[last_write].tdes1 |= | |
113 | + SBE_2T3E3_TX_DESC_LAST_SEGMENT | | |
114 | + SBE_2T3E3_TX_DESC_INTERRUPT_ON_COMPLETION; | |
115 | + sc->ether.tx_ring[sc->ether.tx_ring_current_write].tdes0 |= | |
116 | + SBE_2T3E3_TX_DESC_21143_OWN; | |
117 | + sc->ether.tx_ring_current_write = current_write; | |
118 | + | |
119 | + dev_dbg(&sc->pdev->dev, "txput: tdes0 = %08X tdes1 = %08X\n", | |
120 | + sc->ether.tx_ring[last_write].tdes0, | |
121 | + sc->ether.tx_ring[last_write].tdes1); | |
122 | + | |
123 | + dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND, | |
124 | + 0xffffffff); | |
125 | + | |
126 | + spin_unlock_irqrestore(&sc->ether.tx_lock, flags); | |
127 | + return 0; | |
128 | +} | |
129 | + | |
130 | + | |
131 | +void t3e3_read_card_serial_number(struct channel *sc) | |
132 | +{ | |
133 | + u32 i; | |
134 | + | |
135 | + for (i = 0; i < 3; i++) | |
136 | + sc->ether.card_serial_number[i] = t3e3_eeprom_read_word(sc, 10 + i); | |
137 | + | |
138 | + printk(KERN_INFO "SBE wanPMC-2T3E3 serial number: %04X%04X%04X\n", | |
139 | + sc->ether.card_serial_number[0], sc->ether.card_serial_number[1], | |
140 | + sc->ether.card_serial_number[2]); | |
141 | +} | |
142 | + | |
143 | +/* | |
144 | + bit 0 led1 (green) | |
145 | + bit 1 led1 (yellow) | |
146 | + | |
147 | + bit 2 led2 (green) | |
148 | + bit 3 led2 (yellow) | |
149 | + | |
150 | + bit 4 led3 (green) | |
151 | + bit 5 led3 (yellow) | |
152 | + | |
153 | + bit 6 led4 (green) | |
154 | + bit 7 led4 (yellow) | |
155 | +*/ | |
156 | + | |
157 | +void update_led(struct channel *sc, int blinker) | |
158 | +{ | |
159 | + int leds; | |
160 | + if (sc->s.LOS) | |
161 | + leds = 0; /* led1 = off */ | |
162 | + else if (sc->s.OOF) | |
163 | + leds = 2; /* led1 = yellow */ | |
164 | + else if ((blinker & 1) && sc->rcv_count) { | |
165 | + leds = 0; /* led1 = off */ | |
166 | + sc->rcv_count = 0; | |
167 | + } else | |
168 | + leds = 1; /* led1 = green */ | |
169 | + cpld_write(sc, SBE_2T3E3_CPLD_REG_LEDR, leds); | |
170 | + sc->leds = leds; | |
171 | +} |
drivers/staging/sbe-2t3e3/maps.c
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#include <linux/kernel.h> | |
14 | +#include "2t3e3.h" | |
15 | + | |
16 | +const u32 cpld_reg_map[][2] = | |
17 | +{ | |
18 | + { 0x0000, 0x0080 }, /* 0 - Port Control Register A (PCRA) */ | |
19 | + { 0x0004, 0x0084 }, /* 1 - Port Control Register B (PCRB) */ | |
20 | + { 0x0008, 0x0088 }, /* 2 - LCV Count Register (PLCR) */ | |
21 | + { 0x000c, 0x008c }, /* 3 - LCV Threshold register (PLTR) */ | |
22 | + { 0x0010, 0x0090 }, /* 4 - Payload Fill Register (PPFR) */ | |
23 | + { 0x0200, 0x0200 }, /* 5 - Board ID / FPGA Programming Status Register */ | |
24 | + { 0x0204, 0x0204 }, /* 6 - FPGA Version Register */ | |
25 | + { 0x0800, 0x1000 }, /* 7 - Framer Registers Base Address */ | |
26 | + { 0x2000, 0x2000 }, /* 8 - Serial Chip Select Register */ | |
27 | + { 0x2004, 0x2004 }, /* 9 - Static Reset Register */ | |
28 | + { 0x2008, 0x2008 }, /* 10 - Pulse Reset Register */ | |
29 | + { 0x200c, 0x200c }, /* 11 - FPGA Reconfiguration Register */ | |
30 | + { 0x2010, 0x2014 }, /* 12 - LED Register (LEDR) */ | |
31 | + { 0x2018, 0x201c }, /* 13 - LIU Control and Status Register (PISCR) */ | |
32 | + { 0x2020, 0x2024 }, /* 14 - Interrupt Enable Register (PIER) */ | |
33 | + { 0x0068, 0x00e8 }, /* 15 - Port Control Register C (PCRC) */ | |
34 | + { 0x006c, 0x00ec }, /* 16 - Port Bandwidth Start (PBWF) */ | |
35 | + { 0x0070, 0x00f0 }, /* 17 - Port Bandwidth Stop (PBWL) */ | |
36 | +}; | |
37 | + | |
38 | +const u32 cpld_val_map[][2] = | |
39 | +{ | |
40 | + { 0x01, 0x02 }, /* LIU1 / LIU2 select for Serial Chip Select */ | |
41 | + { 0x04, 0x08 }, /* DAC1 / DAC2 select for Serial Chip Select */ | |
42 | + { 0x00, 0x04 }, /* LOOP1 / LOOP2 - select of loop timing source */ | |
43 | + { 0x01, 0x02 } /* PORT1 / PORT2 - select LIU and Framer for reset */ | |
44 | +}; | |
45 | + | |
46 | +const u32 t3e3_framer_reg_map[] = { | |
47 | + 0x00, /* 0 - OPERATING_MODE */ | |
48 | + 0x01, /* 1 - IO_CONTROL */ | |
49 | + 0x04, /* 2 - BLOCK_INTERRUPT_ENABLE */ | |
50 | + 0x05, /* 3 - BLOCK_INTERRUPT_STATUS */ | |
51 | + 0x10, /* 4 - T3_RX_CONFIGURATION_STATUS, E3_RX_CONFIGURATION_STATUS_1 */ | |
52 | + 0x11, /* 5 - T3_RX_STATUS, E3_RX_CONFIGURATION_STATUS_2 */ | |
53 | + 0x12, /* 6 - T3_RX_INTERRUPT_ENABLE, E3_RX_INTERRUPT_ENABLE_1 */ | |
54 | + 0x13, /* 7 - T3_RX_INTERRUPT_STATUS, E3_RX_INTERRUPT_ENABLE_2 */ | |
55 | + 0x14, /* 8 - T3_RX_SYNC_DETECT_ENABLE, E3_RX_INTERRUPT_STATUS_1 */ | |
56 | + 0x15, /* 9 - E3_RX_INTERRUPT_STATUS_2 */ | |
57 | + 0x16, /* 10 - T3_RX_FEAC */ | |
58 | + 0x17, /* 11 - T3_RX_FEAC_INTERRUPT_ENABLE_STATUS */ | |
59 | + 0x18, /* 12 - T3_RX_LAPD_CONTROL, E3_RX_LAPD_CONTROL */ | |
60 | + 0x19, /* 13 - T3_RX_LAPD_STATUS, E3_RX_LAPD_STATUS */ | |
61 | + 0x1a, /* 14 - E3_RX_NR_BYTE, E3_RX_SERVICE_BITS */ | |
62 | + 0x1b, /* 15 - E3_RX_GC_BYTE */ | |
63 | + 0x30, /* 16 - T3_TX_CONFIGURATION, E3_TX_CONFIGURATION */ | |
64 | + 0x31, /* 17 - T3_TX_FEAC_CONFIGURATION_STATUS */ | |
65 | + 0x32, /* 18 - T3_TX_FEAC */ | |
66 | + 0x33, /* 19 - T3_TX_LAPD_CONFIGURATION, E3_TX_LAPD_CONFIGURATION */ | |
67 | + 0x34, /* 20 - T3_TX_LAPD_STATUS, E3_TX_LAPD_STATUS_INTERRUPT */ | |
68 | + 0x35, /* 21 - T3_TX_MBIT_MASK, E3_TX_GC_BYTE, E3_TX_SERVICE_BITS */ | |
69 | + 0x36, /* 22 - T3_TX_FBIT_MASK, E3_TX_MA_BYTE */ | |
70 | + 0x37, /* 23 - T3_TX_FBIT_MASK_2, E3_TX_NR_BYTE */ | |
71 | + 0x38, /* 24 - T3_TX_FBIT_MASK_3 */ | |
72 | + 0x48, /* 25 - E3_TX_FA1_ERROR_MASK, E3_TX_FAS_ERROR_MASK_UPPER */ | |
73 | + 0x49, /* 26 - E3_TX_FA2_ERROR_MASK, E3_TX_FAS_ERROR_MASK_LOWER */ | |
74 | + 0x4a, /* 27 - E3_TX_BIP8_MASK, E3_TX_BIP4_MASK */ | |
75 | + 0x50, /* 28 - PMON_LCV_EVENT_COUNT_MSB */ | |
76 | + 0x51, /* 29 - PMON_LCV_EVENT_COUNT_LSB */ | |
77 | + 0x52, /* 30 - PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB */ | |
78 | + 0x53, /* 31 - PMON_FRAMING_BIT_ERROR_EVENT_COUNT_LSB */ | |
79 | + 0x54, /* 32 - PMON_PARITY_ERROR_EVENT_COUNT_MSB */ | |
80 | + 0x55, /* 33 - PMON_PARITY_ERROR_EVENT_COUNT_LSB */ | |
81 | + 0x56, /* 34 - PMON_FEBE_EVENT_COUNT_MSB */ | |
82 | + 0x57, /* 35 - PMON_FEBE_EVENT_COUNT_LSB */ | |
83 | + 0x58, /* 36 - PMON_CP_BIT_ERROR_EVENT_COUNT_MSB */ | |
84 | + 0x59, /* 37 - PMON_CP_BIT_ERROR_EVENT_COUNT_LSB */ | |
85 | + 0x6c, /* 38 - PMON_HOLDING_REGISTER */ | |
86 | + 0x6d, /* 39 - ONE_SECOND_ERROR_STATUS */ | |
87 | + 0x6e, /* 40 - LCV_ONE_SECOND_ACCUMULATOR_MSB */ | |
88 | + 0x6f, /* 41 - LCV_ONE_SECOND_ACCUMULATOR_LSB */ | |
89 | + 0x70, /* 42 - FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_MSB */ | |
90 | + 0x71, /* 43 - FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_LSB */ | |
91 | + 0x72, /* 44 - FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_MSB */ | |
92 | + 0x73, /* 45 - FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_LSB */ | |
93 | + 0x80, /* 46 - LINE_INTERFACE_DRIVE */ | |
94 | + 0x81 /* 47 - LINE_INTERFACE_SCAN */ | |
95 | +}; | |
96 | + | |
97 | +const u32 t3e3_liu_reg_map[] = | |
98 | +{ | |
99 | + 0x00, /* REG0 */ | |
100 | + 0x01, /* REG1 */ | |
101 | + 0x02, /* REG2 */ | |
102 | + 0x03, /* REG3 */ | |
103 | + 0x04 /* REG4 */ | |
104 | +}; |
drivers/staging/sbe-2t3e3/module.c
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#include <linux/module.h> | |
14 | +#include <linux/slab.h> | |
15 | +#include <linux/delay.h> | |
16 | +#include <linux/netdevice.h> | |
17 | +#include <linux/pci.h> | |
18 | +#include <linux/hdlc.h> | |
19 | +#include <linux/if_arp.h> | |
20 | +#include <linux/interrupt.h> | |
21 | +#include "2t3e3.h" | |
22 | + | |
23 | +static void check_leds(unsigned long arg) | |
24 | +{ | |
25 | + struct card *card = (struct card *)arg; | |
26 | + struct channel *channel0 = &card->channels[0]; | |
27 | + static int blinker; | |
28 | + | |
29 | + update_led(channel0, ++blinker); | |
30 | + if (has_two_ports(channel0->pdev)) | |
31 | + update_led(&card->channels[1], blinker); | |
32 | + | |
33 | + card->timer.expires = jiffies + HZ / 10; | |
34 | + add_timer(&card->timer); | |
35 | +} | |
36 | + | |
37 | +static void t3e3_remove_channel(struct channel *channel) | |
38 | +{ | |
39 | + struct pci_dev *pdev = channel->pdev; | |
40 | + struct net_device *dev = channel->dev; | |
41 | + | |
42 | + /* system hangs if board asserts irq while module is unloaded */ | |
43 | + cpld_stop_intr(channel); | |
44 | + free_irq(dev->irq, dev); | |
45 | + dc_drop_descriptor_list(channel); | |
46 | + unregister_hdlc_device(dev); | |
47 | + free_netdev(dev); | |
48 | + pci_release_regions(pdev); | |
49 | + pci_disable_device(pdev); | |
50 | + pci_set_drvdata(pdev, NULL); | |
51 | +} | |
52 | + | |
53 | +static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev *pdev, struct card *card) | |
54 | +{ | |
55 | + struct net_device *dev; | |
56 | + unsigned int val; | |
57 | + int err; | |
58 | + | |
59 | + err = pci_enable_device(pdev); | |
60 | + if (err) | |
61 | + return err; | |
62 | + | |
63 | + err = pci_request_regions(pdev, "SBE 2T3E3"); | |
64 | + if (err) | |
65 | + goto disable; | |
66 | + | |
67 | + dev = alloc_hdlcdev(channel); | |
68 | + if (!dev) { | |
69 | + printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n"); | |
70 | + goto free_regions; | |
71 | + } | |
72 | + | |
73 | + t3e3_sc_init(channel); | |
74 | + dev_to_priv(dev) = channel; | |
75 | + | |
76 | + channel->pdev = pdev; | |
77 | + channel->dev = dev; | |
78 | + channel->card = card; | |
79 | + channel->addr = pci_resource_start(pdev, 0); | |
80 | + if (pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P1) | |
81 | + channel->h.slot = 1; | |
82 | + else | |
83 | + channel->h.slot = 0; | |
84 | + | |
85 | + if (setup_device(dev, channel)) | |
86 | + goto free_regions; | |
87 | + | |
88 | + pci_read_config_dword(channel->pdev, 0x40, &val); /* mask sleep mode */ | |
89 | + pci_write_config_dword(channel->pdev, 0x40, val & 0x3FFFFFFF); | |
90 | + | |
91 | + pci_read_config_byte(channel->pdev, PCI_CACHE_LINE_SIZE, &channel->h.cache_size); | |
92 | + pci_read_config_dword(channel->pdev, PCI_COMMAND, &channel->h.command); | |
93 | + t3e3_init(channel); | |
94 | + | |
95 | + if (request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev)) { | |
96 | + printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq); | |
97 | + goto free_regions; | |
98 | + } | |
99 | + | |
100 | + pci_set_drvdata(pdev, channel); | |
101 | + return 0; | |
102 | + | |
103 | +free_regions: | |
104 | + pci_release_regions(pdev); | |
105 | +disable: | |
106 | + pci_disable_device(pdev); | |
107 | + return err; | |
108 | +} | |
109 | + | |
110 | +static void __devexit t3e3_remove_card(struct pci_dev *pdev) | |
111 | +{ | |
112 | + struct channel *channel0 = pci_get_drvdata(pdev); | |
113 | + struct card *card = channel0->card; | |
114 | + | |
115 | + del_timer(&card->timer); | |
116 | + if (has_two_ports(channel0->pdev)) { | |
117 | + t3e3_remove_channel(&card->channels[1]); | |
118 | + pci_dev_put(card->channels[1].pdev); | |
119 | + } | |
120 | + t3e3_remove_channel(channel0); | |
121 | + kfree(card); | |
122 | +} | |
123 | + | |
124 | +static int __devinit t3e3_init_card(struct pci_dev *pdev, const struct pci_device_id *ent) | |
125 | +{ | |
126 | + /* pdev points to channel #0 */ | |
127 | + struct pci_dev *pdev1 = NULL; | |
128 | + struct card *card; | |
129 | + int channels = 1, err; | |
130 | + | |
131 | + if (has_two_ports(pdev)) { | |
132 | + while ((pdev1 = pci_get_subsys(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, | |
133 | + PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P1, | |
134 | + pdev1))) | |
135 | + if (pdev1->bus == pdev->bus && | |
136 | + pdev1->devfn == pdev->devfn + 8 /* next device on the same bus */) | |
137 | + break; /* found the second channel */ | |
138 | + | |
139 | + if (!pdev1) { | |
140 | + printk(KERN_ERR "SBE 2T3E3" ": Can't find the second channel\n"); | |
141 | + return -EFAULT; | |
142 | + } | |
143 | + channels = 2; | |
144 | + /* holds the reference for pdev1 */ | |
145 | + } | |
146 | + | |
147 | + card = kzalloc(sizeof(struct card) + channels * sizeof(struct channel), GFP_KERNEL); | |
148 | + if (!card) { | |
149 | + printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n"); | |
150 | + return -ENOBUFS; | |
151 | + } | |
152 | + | |
153 | + spin_lock_init(&card->bootrom_lock); | |
154 | + card->bootrom_addr = pci_resource_start(pdev, 0); | |
155 | + | |
156 | + err = t3e3_init_channel(&card->channels[0], pdev, card); | |
157 | + if (err) | |
158 | + goto free_card; | |
159 | + | |
160 | + if (channels == 2) { | |
161 | + err = t3e3_init_channel(&card->channels[1], pdev1, card); | |
162 | + if (err) { | |
163 | + t3e3_remove_channel(&card->channels[0]); | |
164 | + goto free_card; | |
165 | + } | |
166 | + } | |
167 | + | |
168 | + /* start LED timer */ | |
169 | + init_timer(&card->timer); | |
170 | + card->timer.function = check_leds; | |
171 | + card->timer.expires = jiffies + HZ / 10; | |
172 | + card->timer.data = (unsigned long)card; | |
173 | + add_timer(&card->timer); | |
174 | + return 0; | |
175 | + | |
176 | +free_card: | |
177 | + kfree(card); | |
178 | + return err; | |
179 | +} | |
180 | + | |
181 | +static struct pci_device_id t3e3_pci_tbl[] __devinitdata = { | |
182 | + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, | |
183 | + PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_T3E3, 0, 0, 0 }, | |
184 | + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, | |
185 | + PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P0, 0, 0, 0 }, | |
186 | + /* channel 1 will be initialized after channel 0 */ | |
187 | + { 0, } | |
188 | +}; | |
189 | + | |
190 | +static struct pci_driver t3e3_pci_driver = { | |
191 | + .name = "SBE T3E3", | |
192 | + .id_table = t3e3_pci_tbl, | |
193 | + .probe = t3e3_init_card, | |
194 | + .remove = t3e3_remove_card, | |
195 | +}; | |
196 | + | |
197 | +static int __init t3e3_init_module(void) | |
198 | +{ | |
199 | + return pci_register_driver(&t3e3_pci_driver); | |
200 | +} | |
201 | + | |
202 | +static void __exit t3e3_cleanup_module(void) | |
203 | +{ | |
204 | + pci_unregister_driver(&t3e3_pci_driver); | |
205 | +} | |
206 | + | |
207 | +module_init(t3e3_init_module); | |
208 | +module_exit(t3e3_cleanup_module); | |
209 | +MODULE_LICENSE("GPL"); | |
210 | +MODULE_DEVICE_TABLE(pci, t3e3_pci_tbl); |
drivers/staging/sbe-2t3e3/netdev.c
1 | +/* | |
2 | + * SBE 2T3E3 synchronous serial card driver for Linux | |
3 | + * | |
4 | + * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify it | |
7 | + * under the terms of version 2 of the GNU General Public License | |
8 | + * as published by the Free Software Foundation. | |
9 | + * | |
10 | + * This code is based on a driver written by SBE Inc. | |
11 | + */ | |
12 | + | |
13 | +#include <linux/capability.h> | |
14 | +#include <linux/module.h> | |
15 | +#include <linux/slab.h> | |
16 | +#include <linux/delay.h> | |
17 | +#include <linux/netdevice.h> | |
18 | +#include <linux/pci.h> | |
19 | +#include <linux/hdlc.h> | |
20 | +#include <linux/if_arp.h> | |
21 | +#include <linux/interrupt.h> | |
22 | +#include "2t3e3.h" | |
23 | + | |
24 | +int t3e3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |
25 | +{ | |
26 | + struct channel *sc = dev_to_priv(dev); | |
27 | + int cmd_2t3e3, len, rlen; | |
28 | + t3e3_param_t param; | |
29 | + t3e3_resp_t resp; | |
30 | + void *data = ifr->ifr_data + sizeof(cmd_2t3e3) + sizeof(len); | |
31 | + | |
32 | + if (cmd == SIOCWANDEV) | |
33 | + return hdlc_ioctl(dev, ifr, cmd); | |
34 | + if (!capable(CAP_SYS_ADMIN)) | |
35 | + return -EPERM; | |
36 | + if (cmd != SIOCDEVPRIVATE + 15) | |
37 | + return -EINVAL; | |
38 | + | |
39 | + if (copy_from_user(&cmd_2t3e3, ifr->ifr_data, sizeof(cmd_2t3e3))) | |
40 | + return -EFAULT; | |
41 | + if (copy_from_user(&len, ifr->ifr_data + sizeof(cmd_2t3e3), sizeof(len))) | |
42 | + return -EFAULT; | |
43 | + | |
44 | + if (len > sizeof(param)) | |
45 | + return -EFAULT; | |
46 | + | |
47 | + if (len) | |
48 | + if (copy_from_user(¶m, data, len)) | |
49 | + return -EFAULT; | |
50 | + | |
51 | + t3e3_if_config(sc, cmd_2t3e3, (char *)¶m, &resp, &rlen); | |
52 | + | |
53 | + if (rlen) | |
54 | + if (copy_to_user(data, &resp, rlen)) | |
55 | + return -EFAULT; | |
56 | + | |
57 | + return 0; | |
58 | +} | |
59 | + | |
60 | +static struct net_device_stats* t3e3_get_stats(struct net_device *dev) | |
61 | +{ | |
62 | + struct net_device_stats *nstats = &dev->stats; | |
63 | + struct channel *sc = dev_to_priv(dev); | |
64 | + t3e3_stats_t *stats = &sc->s; | |
65 | + | |
66 | + memset(nstats, 0, sizeof(struct net_device_stats)); | |
67 | + nstats->rx_packets = stats->in_packets; | |
68 | + nstats->tx_packets = stats->out_packets; | |
69 | + nstats->rx_bytes = stats->in_bytes; | |
70 | + nstats->tx_bytes = stats->out_bytes; | |
71 | + | |
72 | + nstats->rx_errors = stats->in_errors; | |
73 | + nstats->tx_errors = stats->out_errors; | |
74 | + nstats->rx_crc_errors = stats->in_error_crc; | |
75 | + | |
76 | + | |
77 | + nstats->rx_dropped = stats->in_dropped; | |
78 | + nstats->tx_dropped = stats->out_dropped; | |
79 | + nstats->tx_carrier_errors = stats->out_error_lost_carr + | |
80 | + stats->out_error_no_carr; | |
81 | + | |
82 | + return nstats; | |
83 | +} | |
84 | + | |
85 | +int t3e3_open(struct net_device *dev) | |
86 | +{ | |
87 | + struct channel *sc = dev_to_priv(dev); | |
88 | + int ret = hdlc_open(dev); | |
89 | + | |
90 | + if (ret) | |
91 | + return ret; | |
92 | + | |
93 | + sc->r.flags |= SBE_2T3E3_FLAG_NETWORK_UP; | |
94 | + dc_start(dev_to_priv(dev)); | |
95 | + netif_start_queue(dev); | |
96 | + try_module_get(THIS_MODULE); | |
97 | + return 0; | |
98 | +} | |
99 | + | |
100 | +int t3e3_close(struct net_device *dev) | |
101 | +{ | |
102 | + struct channel *sc = dev_to_priv(dev); | |
103 | + hdlc_close(dev); | |
104 | + netif_stop_queue(dev); | |
105 | + dc_stop(sc); | |
106 | + sc->r.flags &= ~SBE_2T3E3_FLAG_NETWORK_UP; | |
107 | + module_put(THIS_MODULE); | |
108 | + return 0; | |
109 | +} | |
110 | + | |
111 | +static int t3e3_attach(struct net_device *dev, unsigned short foo1, | |
112 | + unsigned short foo2) | |
113 | +{ | |
114 | + return 0; | |
115 | +} | |
116 | + | |
117 | +static const struct net_device_ops t3e3_ops = { | |
118 | + .ndo_open = t3e3_open, | |
119 | + .ndo_stop = t3e3_close, | |
120 | + .ndo_change_mtu = hdlc_change_mtu, | |
121 | + .ndo_start_xmit = hdlc_start_xmit, | |
122 | + .ndo_do_ioctl = t3e3_ioctl, | |
123 | + .ndo_get_stats = t3e3_get_stats, | |
124 | +}; | |
125 | + | |
126 | +int setup_device(struct net_device *dev, struct channel *sc) | |
127 | +{ | |
128 | + hdlc_device *hdlc = dev_to_hdlc(dev); | |
129 | + int retval; | |
130 | + | |
131 | + dev->base_addr = pci_resource_start(sc->pdev, 0); | |
132 | + dev->irq = sc->pdev->irq; | |
133 | + dev->netdev_ops = &t3e3_ops; | |
134 | + dev->tx_queue_len = 100; | |
135 | + hdlc->xmit = t3e3_if_start_xmit; | |
136 | + hdlc->attach = t3e3_attach; | |
137 | + if ((retval = register_hdlc_device(dev))) { | |
138 | + dev_err(&sc->pdev->dev, "error registering HDLC device\n"); | |
139 | + return retval; | |
140 | + } | |
141 | + return 0; | |
142 | +} |