Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ctrl.c
Go to the documentation of this file.
1 /*
2  * SBE 2T3E3 synchronous serial card driver for Linux
3  *
4  * Copyright (C) 2009-2010 Krzysztof Halasa <[email protected]>
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 
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 
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)
45  if (rx == SBE_2T3E3_ON)
47 
48  /* stop current loopback if any exists */
49  switch (sc->p.loopback) {
51  break;
54  break;
57  break;
62  break;
63  default:
64  return;
65  }
66 
67  switch (mode) {
69  break;
72  break;
75  break;
78  break;
81  break;
84  break;
85  default:
86  return;
87  }
88 
89  sc->p.loopback = mode;
90 
91  if (tx == SBE_2T3E3_ON)
93  if (rx == 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]) {
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;
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]) {
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;
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 
168 {
169  memcpy(param, &(sc->p), sizeof(t3e3_param_t));
170 }
171 
173 {
174  if (param->frame_mode != 0xff)
175  cpld_set_frame_mode(sc, param->frame_mode);
176 
177  if (param->fractional_mode != 0xff)
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)
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)
202 
203  if (param->receive_equalization != 0xff)
205 
206  if (param->transmit_all_ones != 0xff)
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 
221 {
222  u32 result;
223 
226 
227  switch (sc->p.frame_type) {
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 
234  cpld_LOS_update(sc);
235 
236  sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_AIS ? 1 : 0;
237  sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_FERF ? 1 : 0;
238  break;
239 
243  sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIS ? 1 : 0;
244 
245  cpld_LOS_update(sc);
246 
247  sc->s.IDLE = result & SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE ? 1 : 0;
248  sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
249 
251  sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_FERF ? 1 : 0;
252  sc->s.AIC = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIC ? 1 : 0;
254 
256  break;
257 
258  default:
259  break;
260  }
261 
264  sc->s.LCV += result;
265 
268  sc->s.FRAMING_BIT += result;
269 
272  sc->s.PARITY_ERROR += result;
273 
276  sc->s.FEBE_count += result;
277 
280  sc->s.CP_BIT += result;
281 
282  memcpy(stats, &(sc->s), sizeof(t3e3_stats_t));
283 }
284 
286 {
287  memset(&(sc->s), 0, sizeof(t3e3_stats_t));
288 }
289 
290 void t3e3_if_config(struct channel *sc, u32 cmd, char *set,
291  t3e3_resp_t *ret, int *rlen)
292 {
293  t3e3_param_t *param = (t3e3_param_t *)set;
294  u32 *data = (u32 *)set;
295 
296  /* turn off all interrupt */
297  /* cpld_stop_intr(sc); */
298 
299  switch (cmd) {
300  case SBE_2T3E3_PORT_GET:
301  t3e3_port_get(sc, &(ret->u.param));
302  *rlen = sizeof(ret->u.param);
303  break;
304  case SBE_2T3E3_PORT_SET:
305  t3e3_port_set(sc, param);
306  *rlen = 0;
307  break;
309  t3e3_port_get_stats(sc, &(ret->u.stats));
310  *rlen = sizeof(ret->u.stats);
311  break;
314  *rlen = 0;
315  break;
317  t3e3_reg_read(sc, data, &(ret->u.data));
318  *rlen = sizeof(ret->u.data);
319  break;
321  t3e3_reg_write(sc, data);
322  *rlen = 0;
323  break;
324  case SBE_2T3E3_LOG_LEVEL:
325  *rlen = 0;
326  break;
327  default:
328  *rlen = 0;
329  break;
330  }
331 }
332 
333 void t3e3_sc_init(struct channel *sc)
334 {
335  memset(sc, 0, sizeof(*sc));
336 
339  sc->p.crc = SBE_2T3E3_CRC_32;
351 }