1 /* $Id: elsa_ser.c,v 2.14.2.3 2004/02/11 13:21:33 keil Exp $
3 * stuff for the serial modem on ELSA cards
5 * This software may be used and distributed according to the terms
6 * of the GNU General Public License, incorporated herein by reference.
10 #include <linux/serial.h>
11 #include <linux/serial_reg.h>
13 #define MAX_MODEM_BUF 256
14 #define WAKEUP_CHARS (MAX_MODEM_BUF/2)
15 #define RS_ISR_PASS_LIMIT 256
16 #define BASE_BAUD ( 1843200 / 16 )
18 //#define SERIAL_DEBUG_OPEN 1
19 //#define SERIAL_DEBUG_INTR 1
20 //#define SERIAL_DEBUG_FLOW 1
21 #undef SERIAL_DEBUG_OPEN
22 #undef SERIAL_DEBUG_INTR
23 #undef SERIAL_DEBUG_FLOW
24 #undef SERIAL_DEBUG_REG
25 //#define SERIAL_DEBUG_REG 1
27 #ifdef SERIAL_DEBUG_REG
28 static u_char deb
[32];
29 const char *ModemIn
[] = {"RBR","IER","IIR","LCR","MCR","LSR","MSR","SCR"};
30 const char *ModemOut
[] = {"THR","IER","FCR","LCR","MCR","LSR","MSR","SCR"};
33 static char *MInit_1
= "AT&F&C1E0&D2\r\0";
34 static char *MInit_2
= "ATL2M1S64=13\r\0";
35 static char *MInit_3
= "AT+FCLASS=0\r\0";
36 static char *MInit_4
= "ATV1S2=128X1\r\0";
37 static char *MInit_5
= "AT\\V8\\N3\r\0";
38 static char *MInit_6
= "ATL0M0&G0%E1\r\0";
39 static char *MInit_7
= "AT%L1%M0%C3\r\0";
41 static char *MInit_speed28800
= "AT%G0%B28800\r\0";
43 static char *MInit_dialout
= "ATs7=60 x1 d\r\0";
44 static char *MInit_dialin
= "ATs7=60 x1 a\r\0";
47 static inline unsigned int serial_in(struct IsdnCardState
*cs
, int offset
)
49 #ifdef SERIAL_DEBUG_REG
50 u_int val
= inb(cs
->hw
.elsa
.base
+ 8 + offset
);
51 debugl1(cs
,"in %s %02x",ModemIn
[offset
], val
);
54 return inb(cs
->hw
.elsa
.base
+ 8 + offset
);
58 static inline unsigned int serial_inp(struct IsdnCardState
*cs
, int offset
)
60 #ifdef SERIAL_DEBUG_REG
61 #ifdef ELSA_SERIAL_NOPAUSE_IO
62 u_int val
= inb(cs
->hw
.elsa
.base
+ 8 + offset
);
63 debugl1(cs
,"inp %s %02x",ModemIn
[offset
], val
);
65 u_int val
= inb_p(cs
->hw
.elsa
.base
+ 8 + offset
);
66 debugl1(cs
,"inP %s %02x",ModemIn
[offset
], val
);
70 #ifdef ELSA_SERIAL_NOPAUSE_IO
71 return inb(cs
->hw
.elsa
.base
+ 8 + offset
);
73 return inb_p(cs
->hw
.elsa
.base
+ 8 + offset
);
78 static inline void serial_out(struct IsdnCardState
*cs
, int offset
, int value
)
80 #ifdef SERIAL_DEBUG_REG
81 debugl1(cs
,"out %s %02x",ModemOut
[offset
], value
);
83 outb(value
, cs
->hw
.elsa
.base
+ 8 + offset
);
86 static inline void serial_outp(struct IsdnCardState
*cs
, int offset
,
89 #ifdef SERIAL_DEBUG_REG
90 #ifdef ELSA_SERIAL_NOPAUSE_IO
91 debugl1(cs
,"outp %s %02x",ModemOut
[offset
], value
);
93 debugl1(cs
,"outP %s %02x",ModemOut
[offset
], value
);
96 #ifdef ELSA_SERIAL_NOPAUSE_IO
97 outb(value
, cs
->hw
.elsa
.base
+ 8 + offset
);
99 outb_p(value
, cs
->hw
.elsa
.base
+ 8 + offset
);
104 * This routine is called to set the UART divisor registers to match
105 * the specified baud rate for a serial port.
107 static void change_speed(struct IsdnCardState
*cs
, int baud
)
109 int quot
= 0, baud_base
;
110 unsigned cval
, fcr
= 0;
114 /* byte size and parity */
115 cval
= 0x03; bits
= 10;
116 /* Determine divisor based on baud rate */
117 baud_base
= BASE_BAUD
;
118 quot
= baud_base
/ baud
;
119 /* If the quotient is ever zero, default to 9600 bps */
121 quot
= baud_base
/ 9600;
124 if ((baud_base
/ quot
) < 2400)
125 fcr
= UART_FCR_ENABLE_FIFO
| UART_FCR_TRIGGER_1
;
127 fcr
= UART_FCR_ENABLE_FIFO
| UART_FCR_TRIGGER_8
;
128 serial_outp(cs
, UART_FCR
, fcr
);
129 /* CTS flow control flag and modem status interrupts */
130 cs
->hw
.elsa
.IER
&= ~UART_IER_MSI
;
131 cs
->hw
.elsa
.IER
|= UART_IER_MSI
;
132 serial_outp(cs
, UART_IER
, cs
->hw
.elsa
.IER
);
134 debugl1(cs
,"modem quot=0x%x", quot
);
135 serial_outp(cs
, UART_LCR
, cval
| UART_LCR_DLAB
);/* set DLAB */
136 serial_outp(cs
, UART_DLL
, quot
& 0xff); /* LS of divisor */
137 serial_outp(cs
, UART_DLM
, quot
>> 8); /* MS of divisor */
138 serial_outp(cs
, UART_LCR
, cval
); /* reset DLAB */
139 serial_inp(cs
, UART_RX
);
142 static int mstartup(struct IsdnCardState
*cs
)
147 * Clear the FIFO buffers and disable them
148 * (they will be reenabled in change_speed())
150 serial_outp(cs
, UART_FCR
, (UART_FCR_CLEAR_RCVR
| UART_FCR_CLEAR_XMIT
));
153 * At this point there's no way the LSR could still be 0xFF;
154 * if it is, then bail out, because there's likely no UART
157 if (serial_inp(cs
, UART_LSR
) == 0xff) {
163 * Clear the interrupt registers.
165 (void) serial_inp(cs
, UART_RX
);
166 (void) serial_inp(cs
, UART_IIR
);
167 (void) serial_inp(cs
, UART_MSR
);
170 * Now, initialize the UART
172 serial_outp(cs
, UART_LCR
, UART_LCR_WLEN8
); /* reset DLAB */
175 cs
->hw
.elsa
.MCR
= UART_MCR_DTR
| UART_MCR_RTS
| UART_MCR_OUT2
;
176 serial_outp(cs
, UART_MCR
, cs
->hw
.elsa
.MCR
);
179 * Finally, enable interrupts
181 cs
->hw
.elsa
.IER
= UART_IER_MSI
| UART_IER_RLSI
| UART_IER_RDI
;
182 serial_outp(cs
, UART_IER
, cs
->hw
.elsa
.IER
); /* enable interrupts */
185 * And clear the interrupt registers again for luck.
187 (void)serial_inp(cs
, UART_LSR
);
188 (void)serial_inp(cs
, UART_RX
);
189 (void)serial_inp(cs
, UART_IIR
);
190 (void)serial_inp(cs
, UART_MSR
);
192 cs
->hw
.elsa
.transcnt
= cs
->hw
.elsa
.transp
= 0;
193 cs
->hw
.elsa
.rcvcnt
= cs
->hw
.elsa
.rcvp
=0;
196 * and set the speed of the serial port
198 change_speed(cs
, BASE_BAUD
);
199 cs
->hw
.elsa
.MFlag
= 1;
205 * This routine will shutdown a serial port; interrupts are disabled, and
206 * DTR is dropped if the hangup on close termio flag is on.
208 static void mshutdown(struct IsdnCardState
*cs
)
211 #ifdef SERIAL_DEBUG_OPEN
212 printk(KERN_DEBUG
"Shutting down serial ....");
216 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
217 * here so the queue might never be waken up
221 serial_outp(cs
, UART_IER
, 0x00); /* disable all intrs */
222 cs
->hw
.elsa
.MCR
&= ~UART_MCR_OUT2
;
224 /* disable break condition */
225 serial_outp(cs
, UART_LCR
, serial_inp(cs
, UART_LCR
) & ~UART_LCR_SBC
);
227 cs
->hw
.elsa
.MCR
&= ~(UART_MCR_DTR
|UART_MCR_RTS
);
228 serial_outp(cs
, UART_MCR
, cs
->hw
.elsa
.MCR
);
231 serial_outp(cs
, UART_FCR
, (UART_FCR_CLEAR_RCVR
| UART_FCR_CLEAR_XMIT
));
232 serial_inp(cs
, UART_RX
); /* read data port to reset things */
234 #ifdef SERIAL_DEBUG_OPEN
240 write_modem(struct BCState
*bcs
) {
242 struct IsdnCardState
*cs
= bcs
->cs
;
247 if (bcs
->tx_skb
->len
<= 0)
249 len
= bcs
->tx_skb
->len
;
250 if (len
> MAX_MODEM_BUF
- cs
->hw
.elsa
.transcnt
)
251 len
= MAX_MODEM_BUF
- cs
->hw
.elsa
.transcnt
;
252 fp
= cs
->hw
.elsa
.transcnt
+ cs
->hw
.elsa
.transp
;
253 fp
&= (MAX_MODEM_BUF
-1);
255 if (count
> MAX_MODEM_BUF
- fp
) {
256 count
= MAX_MODEM_BUF
- fp
;
257 memcpy(cs
->hw
.elsa
.transbuf
+ fp
, bcs
->tx_skb
->data
, count
);
258 skb_pull(bcs
->tx_skb
, count
);
259 cs
->hw
.elsa
.transcnt
+= count
;
264 memcpy((cs
->hw
.elsa
.transbuf
+ fp
), bcs
->tx_skb
->data
, count
);
265 skb_pull(bcs
->tx_skb
, count
);
266 cs
->hw
.elsa
.transcnt
+= count
;
269 if (cs
->hw
.elsa
.transcnt
&&
270 !(cs
->hw
.elsa
.IER
& UART_IER_THRI
)) {
271 cs
->hw
.elsa
.IER
|= UART_IER_THRI
;
272 serial_outp(cs
, UART_IER
, cs
->hw
.elsa
.IER
);
278 modem_fill(struct BCState
*bcs
) {
281 if (bcs
->tx_skb
->len
) {
285 if (test_bit(FLG_LLI_L1WAKEUP
,&bcs
->st
->lli
.flag
) &&
286 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
)) {
288 spin_lock_irqsave(&bcs
->aclock
, flags
);
289 bcs
->ackcnt
+= bcs
->hw
.hscx
.count
;
290 spin_unlock_irqrestore(&bcs
->aclock
, flags
);
291 schedule_event(bcs
, B_ACKPENDING
);
293 dev_kfree_skb_any(bcs
->tx_skb
);
297 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
298 bcs
->hw
.hscx
.count
= 0;
299 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
302 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
303 schedule_event(bcs
, B_XMTBUFREADY
);
307 static inline void receive_chars(struct IsdnCardState
*cs
,
314 ch
= serial_in(cs
, UART_RX
);
315 if (cs
->hw
.elsa
.rcvcnt
>= MAX_MODEM_BUF
)
317 cs
->hw
.elsa
.rcvbuf
[cs
->hw
.elsa
.rcvcnt
++] = ch
;
318 #ifdef SERIAL_DEBUG_INTR
319 printk("DR%02x:%02x...", ch
, *status
);
321 if (*status
& (UART_LSR_BI
| UART_LSR_PE
|
322 UART_LSR_FE
| UART_LSR_OE
)) {
324 #ifdef SERIAL_DEBUG_INTR
325 printk("handling exept....");
328 *status
= serial_inp(cs
, UART_LSR
);
329 } while (*status
& UART_LSR_DR
);
330 if (cs
->hw
.elsa
.MFlag
== 2) {
331 if (!(skb
= dev_alloc_skb(cs
->hw
.elsa
.rcvcnt
)))
332 printk(KERN_WARNING
"ElsaSER: receive out of memory\n");
334 memcpy(skb_put(skb
, cs
->hw
.elsa
.rcvcnt
), cs
->hw
.elsa
.rcvbuf
,
336 skb_queue_tail(& cs
->hw
.elsa
.bcs
->rqueue
, skb
);
338 schedule_event(cs
->hw
.elsa
.bcs
, B_RCVBUFREADY
);
343 t
+= sprintf(t
, "modem read cnt %d", cs
->hw
.elsa
.rcvcnt
);
344 QuickHex(t
, cs
->hw
.elsa
.rcvbuf
, cs
->hw
.elsa
.rcvcnt
);
347 cs
->hw
.elsa
.rcvcnt
= 0;
350 static inline void transmit_chars(struct IsdnCardState
*cs
, int *intr_done
)
354 debugl1(cs
, "transmit_chars: p(%x) cnt(%x)", cs
->hw
.elsa
.transp
,
355 cs
->hw
.elsa
.transcnt
);
357 if (cs
->hw
.elsa
.transcnt
<= 0) {
358 cs
->hw
.elsa
.IER
&= ~UART_IER_THRI
;
359 serial_out(cs
, UART_IER
, cs
->hw
.elsa
.IER
);
364 serial_outp(cs
, UART_TX
, cs
->hw
.elsa
.transbuf
[cs
->hw
.elsa
.transp
++]);
365 if (cs
->hw
.elsa
.transp
>= MAX_MODEM_BUF
)
366 cs
->hw
.elsa
.transp
=0;
367 if (--cs
->hw
.elsa
.transcnt
<= 0)
369 } while (--count
> 0);
370 if ((cs
->hw
.elsa
.transcnt
< WAKEUP_CHARS
) && (cs
->hw
.elsa
.MFlag
==2))
371 modem_fill(cs
->hw
.elsa
.bcs
);
373 #ifdef SERIAL_DEBUG_INTR
378 if (cs
->hw
.elsa
.transcnt
<= 0) {
379 cs
->hw
.elsa
.IER
&= ~UART_IER_THRI
;
380 serial_outp(cs
, UART_IER
, cs
->hw
.elsa
.IER
);
385 static void rs_interrupt_elsa(int irq
, struct IsdnCardState
*cs
)
387 int status
, iir
, msr
;
388 int pass_counter
= 0;
390 #ifdef SERIAL_DEBUG_INTR
391 printk("rs_interrupt_single(%d)...", irq
);
395 status
= serial_inp(cs
, UART_LSR
);
396 debugl1(cs
,"rs LSR %02x", status
);
397 #ifdef SERIAL_DEBUG_INTR
398 printk("status = %x...", status
);
400 if (status
& UART_LSR_DR
)
401 receive_chars(cs
, &status
);
402 if (status
& UART_LSR_THRE
)
403 transmit_chars(cs
, NULL
);
404 if (pass_counter
++ > RS_ISR_PASS_LIMIT
) {
405 printk("rs_single loop break.\n");
408 iir
= serial_inp(cs
, UART_IIR
);
409 debugl1(cs
,"rs IIR %02x", iir
);
410 if ((iir
& 0xf) == 0) {
411 msr
= serial_inp(cs
, UART_MSR
);
412 debugl1(cs
,"rs MSR %02x", msr
);
414 } while (!(iir
& UART_IIR_NO_INT
));
415 #ifdef SERIAL_DEBUG_INTR
420 extern int open_hscxstate(struct IsdnCardState
*cs
, struct BCState
*bcs
);
421 extern void modehscx(struct BCState
*bcs
, int mode
, int bc
);
422 extern void hscx_l2l1(struct PStack
*st
, int pr
, void *arg
);
425 close_elsastate(struct BCState
*bcs
)
427 modehscx(bcs
, 0, bcs
->channel
);
428 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
429 if (bcs
->hw
.hscx
.rcvbuf
) {
430 if (bcs
->mode
!= L1_MODE_MODEM
)
431 kfree(bcs
->hw
.hscx
.rcvbuf
);
432 bcs
->hw
.hscx
.rcvbuf
= NULL
;
434 skb_queue_purge(&bcs
->rqueue
);
435 skb_queue_purge(&bcs
->squeue
);
437 dev_kfree_skb_any(bcs
->tx_skb
);
439 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
445 modem_write_cmd(struct IsdnCardState
*cs
, u_char
*buf
, int len
) {
451 if (len
> (MAX_MODEM_BUF
- cs
->hw
.elsa
.transcnt
)) {
454 fp
= cs
->hw
.elsa
.transcnt
+ cs
->hw
.elsa
.transp
;
455 fp
&= (MAX_MODEM_BUF
-1);
457 if (count
> MAX_MODEM_BUF
- fp
) {
458 count
= MAX_MODEM_BUF
- fp
;
459 memcpy(cs
->hw
.elsa
.transbuf
+ fp
, msg
, count
);
460 cs
->hw
.elsa
.transcnt
+= count
;
465 memcpy(cs
->hw
.elsa
.transbuf
+ fp
, msg
, count
);
466 cs
->hw
.elsa
.transcnt
+= count
;
467 if (cs
->hw
.elsa
.transcnt
&&
468 !(cs
->hw
.elsa
.IER
& UART_IER_THRI
)) {
469 cs
->hw
.elsa
.IER
|= UART_IER_THRI
;
470 serial_outp(cs
, UART_IER
, cs
->hw
.elsa
.IER
);
475 modem_set_init(struct IsdnCardState
*cs
) {
478 #define RCV_DELAY 20000
479 modem_write_cmd(cs
, MInit_1
, strlen(MInit_1
));
481 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
483 debugl1(cs
, "msi tout=%d", timeout
);
485 modem_write_cmd(cs
, MInit_2
, strlen(MInit_2
));
487 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
489 debugl1(cs
, "msi tout=%d", timeout
);
491 modem_write_cmd(cs
, MInit_3
, strlen(MInit_3
));
493 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
495 debugl1(cs
, "msi tout=%d", timeout
);
497 modem_write_cmd(cs
, MInit_4
, strlen(MInit_4
));
499 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
501 debugl1(cs
, "msi tout=%d", timeout
);
503 modem_write_cmd(cs
, MInit_5
, strlen(MInit_5
));
505 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
507 debugl1(cs
, "msi tout=%d", timeout
);
509 modem_write_cmd(cs
, MInit_6
, strlen(MInit_6
));
511 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
513 debugl1(cs
, "msi tout=%d", timeout
);
515 modem_write_cmd(cs
, MInit_7
, strlen(MInit_7
));
517 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
519 debugl1(cs
, "msi tout=%d", timeout
);
524 modem_set_dial(struct IsdnCardState
*cs
, int outgoing
) {
526 #define RCV_DELAY 20000
528 modem_write_cmd(cs
, MInit_speed28800
, strlen(MInit_speed28800
));
530 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
532 debugl1(cs
, "msi tout=%d", timeout
);
535 modem_write_cmd(cs
, MInit_dialout
, strlen(MInit_dialout
));
537 modem_write_cmd(cs
, MInit_dialin
, strlen(MInit_dialin
));
539 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
541 debugl1(cs
, "msi tout=%d", timeout
);
546 modem_l2l1(struct PStack
*st
, int pr
, void *arg
)
548 struct BCState
*bcs
= st
->l1
.bcs
;
549 struct sk_buff
*skb
= arg
;
552 if (pr
== (PH_DATA
| REQUEST
)) {
553 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
555 skb_queue_tail(&bcs
->squeue
, skb
);
558 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
559 bcs
->hw
.hscx
.count
= 0;
562 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
563 } else if (pr
== (PH_ACTIVATE
| REQUEST
)) {
564 test_and_set_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
565 st
->l1
.l1l2(st
, PH_ACTIVATE
| CONFIRM
, NULL
);
566 set_arcofi(bcs
->cs
, st
->l1
.bc
);
568 modem_set_dial(bcs
->cs
, test_bit(FLG_ORIG
, &st
->l2
.flag
));
569 bcs
->cs
->hw
.elsa
.MFlag
=2;
570 } else if (pr
== (PH_DEACTIVATE
| REQUEST
)) {
571 test_and_clear_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
572 bcs
->cs
->dc
.isac
.arcofi_bc
= st
->l1
.bc
;
573 arcofi_fsm(bcs
->cs
, ARCOFI_START
, &ARCOFI_XOP_0
);
574 interruptible_sleep_on(&bcs
->cs
->dc
.isac
.arcofi_wait
);
575 bcs
->cs
->hw
.elsa
.MFlag
=1;
577 printk(KERN_WARNING
"ElsaSer: unknown pr %x\n", pr
);
582 setstack_elsa(struct PStack
*st
, struct BCState
*bcs
)
585 bcs
->channel
= st
->l1
.bc
;
586 switch (st
->l1
.mode
) {
589 if (open_hscxstate(st
->l1
.hardware
, bcs
))
591 st
->l2
.l2l1
= hscx_l2l1
;
594 bcs
->mode
= L1_MODE_MODEM
;
595 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
596 bcs
->hw
.hscx
.rcvbuf
= bcs
->cs
->hw
.elsa
.rcvbuf
;
597 skb_queue_head_init(&bcs
->rqueue
);
598 skb_queue_head_init(&bcs
->squeue
);
601 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
603 bcs
->hw
.hscx
.rcvidx
= 0;
605 bcs
->cs
->hw
.elsa
.bcs
= bcs
;
606 st
->l2
.l2l1
= modem_l2l1
;
610 setstack_manager(st
);
617 init_modem(struct IsdnCardState
*cs
) {
619 cs
->bcs
[0].BC_SetStack
= setstack_elsa
;
620 cs
->bcs
[1].BC_SetStack
= setstack_elsa
;
621 cs
->bcs
[0].BC_Close
= close_elsastate
;
622 cs
->bcs
[1].BC_Close
= close_elsastate
;
623 if (!(cs
->hw
.elsa
.rcvbuf
= kmalloc(MAX_MODEM_BUF
,
626 "Elsa: No modem mem hw.elsa.rcvbuf\n");
629 if (!(cs
->hw
.elsa
.transbuf
= kmalloc(MAX_MODEM_BUF
,
632 "Elsa: No modem mem hw.elsa.transbuf\n");
633 kfree(cs
->hw
.elsa
.rcvbuf
);
634 cs
->hw
.elsa
.rcvbuf
= NULL
;
638 printk(KERN_WARNING
"Elsa: problem startup modem\n");
644 release_modem(struct IsdnCardState
*cs
) {
646 cs
->hw
.elsa
.MFlag
= 0;
647 if (cs
->hw
.elsa
.transbuf
) {
648 if (cs
->hw
.elsa
.rcvbuf
) {
650 kfree(cs
->hw
.elsa
.rcvbuf
);
651 cs
->hw
.elsa
.rcvbuf
= NULL
;
653 kfree(cs
->hw
.elsa
.transbuf
);
654 cs
->hw
.elsa
.transbuf
= NULL
;