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