aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/sbe-2t3e3/dc.c
diff options
context:
space:
mode:
authorKrzysztof Halasa <khc@pm.waw.pl>2010-08-12 17:14:07 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-30 20:36:50 -0400
commit921a86e0e306e42452e16894f2cc792659ede16b (patch)
tree3c3709b0ad5c9a324db7a56530675b9d9f2198c1 /drivers/staging/sbe-2t3e3/dc.c
parentb0b57633089ee4726aefe20760132c41bbd83fff (diff)
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>
Diffstat (limited to 'drivers/staging/sbe-2t3e3/dc.c')
-rw-r--r--drivers/staging/sbe-2t3e3/dc.c502
1 files changed, 502 insertions, 0 deletions
diff --git a/drivers/staging/sbe-2t3e3/dc.c b/drivers/staging/sbe-2t3e3/dc.c
new file mode 100644
index 00000000000..126a9720c6b
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/dc.c
@@ -0,0 +1,502 @@
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
20void 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
95void 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
132void 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
156void 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
181void 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
187void 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
212void 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
252void 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
292void 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
327u32 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
426void 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
443void 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
477void 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
494void 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}