Commit | Line | Data |
---|---|---|
921a86e0 KH |
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 | ||
a00979cc DN |
20 | static int dc_init_descriptor_list(struct channel *sc); |
21 | ||
921a86e0 KH |
22 | void dc_init(struct channel *sc) |
23 | { | |
24 | u32 val; | |
25 | ||
26 | dc_stop(sc); | |
27 | /*dc_reset(sc);*/ /* do not want to reset here */ | |
28 | ||
29 | /* | |
30 | * BUS_MODE (CSR0) | |
31 | */ | |
32 | val = SBE_2T3E3_21143_VAL_READ_LINE_ENABLE | | |
33 | SBE_2T3E3_21143_VAL_READ_MULTIPLE_ENABLE | | |
34 | SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_200us | | |
35 | SBE_2T3E3_21143_VAL_BUS_ARBITRATION_RR; | |
36 | ||
37 | if (sc->h.command & 16) | |
38 | val |= SBE_2T3E3_21143_VAL_WRITE_AND_INVALIDATE_ENABLE; | |
39 | ||
40 | switch (sc->h.cache_size) { | |
41 | case 32: | |
42 | val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_32; | |
43 | break; | |
44 | case 16: | |
45 | val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_16; | |
46 | break; | |
47 | case 8: | |
48 | val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_8; | |
49 | break; | |
50 | default: | |
51 | break; | |
52 | } | |
53 | ||
54 | dc_write(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, val); | |
55 | ||
56 | /* OPERATION_MODE (CSR6) */ | |
57 | val = SBE_2T3E3_21143_VAL_RECEIVE_ALL | | |
58 | SBE_2T3E3_21143_VAL_MUST_BE_ONE | | |
59 | SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1 | | |
60 | SBE_2T3E3_21143_VAL_LOOPBACK_OFF | | |
61 | SBE_2T3E3_21143_VAL_PASS_ALL_MULTICAST | | |
62 | SBE_2T3E3_21143_VAL_PROMISCUOUS_MODE | | |
63 | SBE_2T3E3_21143_VAL_PASS_BAD_FRAMES; | |
64 | dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, val); | |
65 | if (sc->p.loopback == SBE_2T3E3_LOOPBACK_ETHERNET) | |
66 | sc->p.loopback = SBE_2T3E3_LOOPBACK_NONE; | |
67 | ||
921a86e0 KH |
68 | /* |
69 | * GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL (CSR11) | |
70 | */ | |
71 | val = SBE_2T3E3_21143_VAL_CYCLE_SIZE | | |
72 | SBE_2T3E3_21143_VAL_TRANSMIT_TIMER | | |
73 | SBE_2T3E3_21143_VAL_NUMBER_OF_TRANSMIT_PACKETS | | |
74 | SBE_2T3E3_21143_VAL_RECEIVE_TIMER | | |
75 | SBE_2T3E3_21143_VAL_NUMBER_OF_RECEIVE_PACKETS; | |
76 | dc_write(sc->addr, SBE_2T3E3_21143_REG_GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL, val); | |
77 | ||
ef73b7a4 | 78 | /* prepare descriptors and data for receive and transmit processes */ |
921a86e0 KH |
79 | if (dc_init_descriptor_list(sc) != 0) |
80 | return; | |
81 | ||
82 | /* clear ethernet interrupts status */ | |
83 | dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF); | |
84 | ||
85 | /* SIA mode registers */ | |
86 | dc_set_output_port(sc); | |
87 | } | |
88 | ||
89 | void dc_start(struct channel *sc) | |
90 | { | |
91 | u32 val; | |
92 | ||
93 | if (!(sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP)) | |
94 | return; | |
95 | ||
96 | dc_init(sc); | |
97 | ||
98 | /* get actual LOS and OOF status */ | |
99 | switch (sc->p.frame_type) { | |
100 | case SBE_2T3E3_FRAME_TYPE_E3_G751: | |
101 | case SBE_2T3E3_FRAME_TYPE_E3_G832: | |
102 | val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2); | |
103 | dev_dbg(&sc->pdev->dev, "Start Framer Rx Status = %02X\n", val); | |
104 | sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0; | |
105 | break; | |
106 | case SBE_2T3E3_FRAME_TYPE_T3_CBIT: | |
107 | case SBE_2T3E3_FRAME_TYPE_T3_M13: | |
108 | val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS); | |
109 | dev_dbg(&sc->pdev->dev, "Start Framer Rx Status = %02X\n", val); | |
110 | sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0; | |
111 | break; | |
112 | default: | |
113 | break; | |
114 | } | |
115 | cpld_LOS_update(sc); | |
116 | ||
117 | /* start receive and transmit processes */ | |
118 | dc_transmitter_onoff(sc, SBE_2T3E3_ON); | |
119 | dc_receiver_onoff(sc, SBE_2T3E3_ON); | |
120 | ||
121 | /* start interrupts */ | |
122 | dc_start_intr(sc); | |
123 | } | |
124 | ||
125 | #define MAX_INT_WAIT_CNT 12000 | |
126 | void dc_stop(struct channel *sc) | |
127 | { | |
128 | int wcnt; | |
129 | ||
130 | /* stop receive and transmit processes */ | |
131 | dc_receiver_onoff(sc, SBE_2T3E3_OFF); | |
132 | dc_transmitter_onoff(sc, SBE_2T3E3_OFF); | |
133 | ||
134 | /* turn off ethernet interrupts */ | |
135 | dc_stop_intr(sc); | |
136 | ||
137 | /* wait to ensure the interrupts have been completed */ | |
138 | for (wcnt = 0; wcnt < MAX_INT_WAIT_CNT; wcnt++) { | |
139 | udelay(5); | |
140 | if (!sc->interrupt_active) | |
141 | break; | |
142 | } | |
143 | if (wcnt >= MAX_INT_WAIT_CNT) | |
144 | dev_warn(&sc->pdev->dev, "SBE 2T3E3: Interrupt active too long\n"); | |
145 | ||
146 | /* clear all receive/transmit data */ | |
147 | dc_drop_descriptor_list(sc); | |
148 | } | |
149 | ||
150 | void dc_start_intr(struct channel *sc) | |
151 | { | |
152 | if (sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE && sc->s.OOF) | |
153 | return; | |
154 | ||
155 | if (sc->p.receiver_on || sc->p.transmitter_on) { | |
156 | if (!sc->ether.interrupt_enable_mask) | |
157 | dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF); | |
158 | ||
159 | sc->ether.interrupt_enable_mask = | |
160 | SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY_ENABLE | | |
161 | SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY_ENABLE | | |
162 | SBE_2T3E3_21143_VAL_RECEIVE_STOPPED_ENABLE | | |
163 | SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE_ENABLE | | |
164 | SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT_ENABLE | | |
165 | SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW_INTERRUPT_ENABLE | | |
166 | SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE_ENABLE | | |
167 | SBE_2T3E3_21143_VAL_TRANSMIT_STOPPED_ENABLE | | |
168 | SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT_ENABLE; | |
169 | ||
170 | dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, | |
171 | sc->ether.interrupt_enable_mask); | |
172 | } | |
173 | } | |
174 | ||
175 | void dc_stop_intr(struct channel *sc) | |
176 | { | |
177 | sc->ether.interrupt_enable_mask = 0; | |
178 | dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0); | |
179 | } | |
180 | ||
181 | void dc_reset(struct channel *sc) | |
182 | { | |
183 | /* turn off ethernet interrupts */ | |
184 | dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0); | |
185 | dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF); | |
186 | ||
187 | /* software reset */ | |
188 | dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, | |
189 | SBE_2T3E3_21143_VAL_SOFTWARE_RESET); | |
190 | udelay(4); /* 50 PCI cycles < 2us */ | |
191 | ||
192 | /* clear hardware configuration */ | |
193 | dc_write(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, 0); | |
194 | ||
195 | /* clear software configuration */ | |
196 | dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, 0); | |
197 | ||
198 | /* turn off SIA reset */ | |
199 | dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY, | |
200 | SBE_2T3E3_21143_VAL_SIA_RESET); | |
201 | dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE, 0); | |
202 | dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT, 0); | |
203 | } | |
204 | ||
205 | ||
206 | void dc_receiver_onoff(struct channel *sc, u32 mode) | |
207 | { | |
208 | u32 i, state = 0; | |
209 | ||
210 | if (sc->p.receiver_on == mode) | |
211 | return; | |
212 | ||
213 | switch (mode) { | |
214 | case SBE_2T3E3_OFF: | |
215 | if (dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) & | |
216 | SBE_2T3E3_21143_VAL_RECEIVE_START) { | |
217 | dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
218 | SBE_2T3E3_21143_VAL_RECEIVE_START); | |
219 | ||
220 | for (i = 0; i < 16; i++) { | |
221 | state = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS) & | |
222 | SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STATE; | |
223 | if (state == SBE_2T3E3_21143_VAL_RX_STOPPED) | |
224 | break; | |
225 | udelay(5); | |
226 | } | |
227 | if (state != SBE_2T3E3_21143_VAL_RX_STOPPED) | |
228 | dev_warn(&sc->pdev->dev, "SBE 2T3E3: Rx failed to stop\n"); | |
229 | else | |
230 | dev_info(&sc->pdev->dev, "SBE 2T3E3: Rx off\n"); | |
231 | } | |
232 | break; | |
233 | case SBE_2T3E3_ON: | |
234 | dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
235 | SBE_2T3E3_21143_VAL_RECEIVE_START); | |
236 | udelay(100); | |
237 | dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND, 0xFFFFFFFF); | |
238 | break; | |
239 | default: | |
240 | return; | |
241 | } | |
242 | ||
243 | sc->p.receiver_on = mode; | |
244 | } | |
245 | ||
246 | void dc_transmitter_onoff(struct channel *sc, u32 mode) | |
247 | { | |
248 | u32 i, state = 0; | |
249 | ||
250 | if (sc->p.transmitter_on == mode) | |
251 | return; | |
252 | ||
253 | switch (mode) { | |
254 | case SBE_2T3E3_OFF: | |
255 | if (dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) & | |
256 | SBE_2T3E3_21143_VAL_TRANSMISSION_START) { | |
257 | dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
258 | SBE_2T3E3_21143_VAL_TRANSMISSION_START); | |
259 | ||
260 | for (i = 0; i < 16; i++) { | |
261 | state = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS) & | |
262 | SBE_2T3E3_21143_VAL_TRANSMISSION_PROCESS_STATE; | |
263 | if (state == SBE_2T3E3_21143_VAL_TX_STOPPED) | |
264 | break; | |
265 | udelay(5); | |
266 | } | |
267 | if (state != SBE_2T3E3_21143_VAL_TX_STOPPED) | |
268 | dev_warn(&sc->pdev->dev, "SBE 2T3E3: Tx failed to stop\n"); | |
269 | } | |
270 | break; | |
271 | case SBE_2T3E3_ON: | |
272 | dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
273 | SBE_2T3E3_21143_VAL_TRANSMISSION_START); | |
274 | udelay(100); | |
275 | dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND, 0xFFFFFFFF); | |
276 | break; | |
277 | default: | |
278 | return; | |
279 | } | |
280 | ||
281 | sc->p.transmitter_on = mode; | |
282 | } | |
283 | ||
284 | ||
285 | ||
286 | void dc_set_loopback(struct channel *sc, u32 mode) | |
287 | { | |
288 | u32 val; | |
289 | ||
290 | switch (mode) { | |
291 | case SBE_2T3E3_21143_VAL_LOOPBACK_OFF: | |
292 | case SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL: | |
293 | break; | |
294 | default: | |
295 | return; | |
296 | } | |
297 | ||
921a86e0 KH |
298 | /* select loopback mode */ |
299 | val = dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) & | |
300 | ~SBE_2T3E3_21143_VAL_OPERATING_MODE; | |
301 | val |= mode; | |
302 | dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, val); | |
303 | ||
304 | if (mode == SBE_2T3E3_21143_VAL_LOOPBACK_OFF) | |
305 | dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
306 | SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE); | |
307 | else | |
308 | dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
309 | SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE); | |
310 | } | |
311 | ||
a00979cc | 312 | static int dc_init_descriptor_list(struct channel *sc) |
921a86e0 KH |
313 | { |
314 | u32 i, j; | |
315 | struct sk_buff *m; | |
316 | ||
317 | if (sc->ether.rx_ring == NULL) | |
78110bb8 | 318 | sc->ether.rx_ring = kcalloc(SBE_2T3E3_RX_DESC_RING_SIZE, |
921a86e0 | 319 | sizeof(t3e3_rx_desc_t), GFP_KERNEL); |
78110bb8 | 320 | if (sc->ether.rx_ring == NULL) |
a00979cc | 321 | return -ENOMEM; |
921a86e0 KH |
322 | |
323 | if (sc->ether.tx_ring == NULL) | |
78110bb8 | 324 | sc->ether.tx_ring = kcalloc(SBE_2T3E3_TX_DESC_RING_SIZE, |
921a86e0 KH |
325 | sizeof(t3e3_tx_desc_t), GFP_KERNEL); |
326 | if (sc->ether.tx_ring == NULL) { | |
921a86e0 KH |
327 | kfree(sc->ether.rx_ring); |
328 | sc->ether.rx_ring = NULL; | |
a00979cc | 329 | return -ENOMEM; |
921a86e0 KH |
330 | } |
331 | ||
332 | ||
333 | /* | |
334 | * Receive ring | |
335 | */ | |
336 | for (i = 0; i < SBE_2T3E3_RX_DESC_RING_SIZE; i++) { | |
337 | sc->ether.rx_ring[i].rdes0 = SBE_2T3E3_RX_DESC_21143_OWN; | |
338 | sc->ether.rx_ring[i].rdes1 = | |
339 | SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED | SBE_2T3E3_MTU; | |
340 | ||
341 | if (sc->ether.rx_data[i] == NULL) { | |
342 | if (!(m = dev_alloc_skb(MCLBYTES))) { | |
343 | for (j = 0; j < i; j++) { | |
344 | dev_kfree_skb_any(sc->ether.rx_data[j]); | |
345 | sc->ether.rx_data[j] = NULL; | |
346 | } | |
921a86e0 KH |
347 | kfree(sc->ether.rx_ring); |
348 | sc->ether.rx_ring = NULL; | |
921a86e0 KH |
349 | kfree(sc->ether.tx_ring); |
350 | sc->ether.tx_ring = NULL; | |
351 | dev_err(&sc->pdev->dev, "SBE 2T3E3: token_alloc err:" | |
352 | " no buffer space for RX ring\n"); | |
a00979cc | 353 | return -ENOBUFS; |
921a86e0 KH |
354 | } |
355 | sc->ether.rx_data[i] = m; | |
356 | } | |
357 | sc->ether.rx_ring[i].rdes2 = virt_to_phys(sc->ether.rx_data[i]->data); | |
358 | ||
359 | sc->ether.rx_ring[i].rdes3 = virt_to_phys( | |
360 | &sc->ether.rx_ring[(i + 1) % SBE_2T3E3_RX_DESC_RING_SIZE]); | |
361 | } | |
362 | sc->ether.rx_ring[SBE_2T3E3_RX_DESC_RING_SIZE - 1].rdes1 |= | |
363 | SBE_2T3E3_RX_DESC_END_OF_RING; | |
364 | sc->ether.rx_ring_current_read = 0; | |
365 | ||
366 | dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS, | |
367 | virt_to_phys(&sc->ether.rx_ring[0])); | |
368 | ||
369 | /* | |
370 | * Transmit ring | |
371 | */ | |
372 | for (i = 0; i < SBE_2T3E3_TX_DESC_RING_SIZE; i++) { | |
373 | sc->ether.tx_ring[i].tdes0 = 0; | |
374 | sc->ether.tx_ring[i].tdes1 = SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED | | |
375 | SBE_2T3E3_TX_DESC_DISABLE_PADDING; | |
376 | ||
377 | sc->ether.tx_ring[i].tdes2 = 0; | |
378 | sc->ether.tx_data[i] = NULL; | |
379 | ||
380 | sc->ether.tx_ring[i].tdes3 = virt_to_phys( | |
381 | &sc->ether.tx_ring[(i + 1) % SBE_2T3E3_TX_DESC_RING_SIZE]); | |
382 | } | |
383 | sc->ether.tx_ring[SBE_2T3E3_TX_DESC_RING_SIZE - 1].tdes1 |= | |
384 | SBE_2T3E3_TX_DESC_END_OF_RING; | |
385 | ||
386 | dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS, | |
387 | virt_to_phys(&sc->ether.tx_ring[0])); | |
388 | sc->ether.tx_ring_current_read = 0; | |
389 | sc->ether.tx_ring_current_write = 0; | |
390 | sc->ether.tx_free_cnt = SBE_2T3E3_TX_DESC_RING_SIZE; | |
391 | spin_lock_init(&sc->ether.tx_lock); | |
392 | ||
393 | return 0; | |
394 | } | |
395 | ||
396 | void dc_clear_descriptor_list(struct channel *sc) | |
397 | { | |
398 | u32 i; | |
399 | ||
400 | /* clear CSR3 and CSR4 */ | |
401 | dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS, 0); | |
402 | dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS, 0); | |
403 | ||
404 | /* free all data buffers on TX ring */ | |
405 | for (i = 0; i < SBE_2T3E3_TX_DESC_RING_SIZE; i++) { | |
406 | if (sc->ether.tx_data[i] != NULL) { | |
407 | dev_kfree_skb_any(sc->ether.tx_data[i]); | |
408 | sc->ether.tx_data[i] = NULL; | |
409 | } | |
410 | } | |
411 | } | |
412 | ||
413 | void dc_drop_descriptor_list(struct channel *sc) | |
414 | { | |
415 | u32 i; | |
416 | ||
417 | dc_clear_descriptor_list(sc); | |
418 | ||
419 | /* free all data buffers on RX ring */ | |
420 | for (i = 0; i < SBE_2T3E3_RX_DESC_RING_SIZE; i++) { | |
421 | if (sc->ether.rx_data[i] != NULL) { | |
422 | dev_kfree_skb_any(sc->ether.rx_data[i]); | |
423 | sc->ether.rx_data[i] = NULL; | |
424 | } | |
425 | } | |
426 | ||
24c92eac AB |
427 | kfree(sc->ether.rx_ring); |
428 | sc->ether.rx_ring = NULL; | |
429 | kfree(sc->ether.tx_ring); | |
430 | sc->ether.tx_ring = NULL; | |
921a86e0 KH |
431 | } |
432 | ||
433 | ||
434 | void dc_set_output_port(struct channel *sc) | |
435 | { | |
436 | dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
437 | SBE_2T3E3_21143_VAL_PORT_SELECT); | |
438 | ||
439 | dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_STATUS, 0x00000301); | |
440 | dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY, 0); | |
441 | dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE, 0); | |
442 | dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT, 0x08000011); | |
443 | ||
444 | dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, | |
445 | SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_100Mbs | | |
446 | SBE_2T3E3_21143_VAL_HEARTBEAT_DISABLE | | |
447 | SBE_2T3E3_21143_VAL_PORT_SELECT | | |
448 | SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE); | |
449 | } | |
450 | ||
451 | void dc_restart(struct channel *sc) | |
452 | { | |
453 | dev_warn(&sc->pdev->dev, "SBE 2T3E3: 21143 restart\n"); | |
454 | ||
455 | dc_stop(sc); | |
456 | dc_reset(sc); | |
457 | dc_init(sc); /* stop + reset + init */ | |
458 | dc_start(sc); | |
459 | } |