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 skb_copy_from_linear_data(bcs
->tx_skb
,
258 cs
->hw
.elsa
.transbuf
+ fp
, count
);
259 skb_pull(bcs
->tx_skb
, count
);
260 cs
->hw
.elsa
.transcnt
+= count
;
265 skb_copy_from_linear_data(bcs
->tx_skb
,
266 cs
->hw
.elsa
.transbuf
+ fp
, count
);
267 skb_pull(bcs
->tx_skb
, count
);
268 cs
->hw
.elsa
.transcnt
+= count
;
271 if (cs
->hw
.elsa
.transcnt
&&
272 !(cs
->hw
.elsa
.IER
& UART_IER_THRI
)) {
273 cs
->hw
.elsa
.IER
|= UART_IER_THRI
;
274 serial_outp(cs
, UART_IER
, cs
->hw
.elsa
.IER
);
280 modem_fill(struct BCState
*bcs
) {
283 if (bcs
->tx_skb
->len
) {
287 if (test_bit(FLG_LLI_L1WAKEUP
,&bcs
->st
->lli
.flag
) &&
288 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
)) {
290 spin_lock_irqsave(&bcs
->aclock
, flags
);
291 bcs
->ackcnt
+= bcs
->hw
.hscx
.count
;
292 spin_unlock_irqrestore(&bcs
->aclock
, flags
);
293 schedule_event(bcs
, B_ACKPENDING
);
295 dev_kfree_skb_any(bcs
->tx_skb
);
299 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
300 bcs
->hw
.hscx
.count
= 0;
301 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
304 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
305 schedule_event(bcs
, B_XMTBUFREADY
);
309 static inline void receive_chars(struct IsdnCardState
*cs
,
316 ch
= serial_in(cs
, UART_RX
);
317 if (cs
->hw
.elsa
.rcvcnt
>= MAX_MODEM_BUF
)
319 cs
->hw
.elsa
.rcvbuf
[cs
->hw
.elsa
.rcvcnt
++] = ch
;
320 #ifdef SERIAL_DEBUG_INTR
321 printk("DR%02x:%02x...", ch
, *status
);
323 if (*status
& (UART_LSR_BI
| UART_LSR_PE
|
324 UART_LSR_FE
| UART_LSR_OE
)) {
326 #ifdef SERIAL_DEBUG_INTR
327 printk("handling exept....");
330 *status
= serial_inp(cs
, UART_LSR
);
331 } while (*status
& UART_LSR_DR
);
332 if (cs
->hw
.elsa
.MFlag
== 2) {
333 if (!(skb
= dev_alloc_skb(cs
->hw
.elsa
.rcvcnt
)))
334 printk(KERN_WARNING
"ElsaSER: receive out of memory\n");
336 memcpy(skb_put(skb
, cs
->hw
.elsa
.rcvcnt
), cs
->hw
.elsa
.rcvbuf
,
338 skb_queue_tail(& cs
->hw
.elsa
.bcs
->rqueue
, skb
);
340 schedule_event(cs
->hw
.elsa
.bcs
, B_RCVBUFREADY
);
345 t
+= sprintf(t
, "modem read cnt %d", cs
->hw
.elsa
.rcvcnt
);
346 QuickHex(t
, cs
->hw
.elsa
.rcvbuf
, cs
->hw
.elsa
.rcvcnt
);
349 cs
->hw
.elsa
.rcvcnt
= 0;
352 static inline void transmit_chars(struct IsdnCardState
*cs
, int *intr_done
)
356 debugl1(cs
, "transmit_chars: p(%x) cnt(%x)", cs
->hw
.elsa
.transp
,
357 cs
->hw
.elsa
.transcnt
);
359 if (cs
->hw
.elsa
.transcnt
<= 0) {
360 cs
->hw
.elsa
.IER
&= ~UART_IER_THRI
;
361 serial_out(cs
, UART_IER
, cs
->hw
.elsa
.IER
);
366 serial_outp(cs
, UART_TX
, cs
->hw
.elsa
.transbuf
[cs
->hw
.elsa
.transp
++]);
367 if (cs
->hw
.elsa
.transp
>= MAX_MODEM_BUF
)
368 cs
->hw
.elsa
.transp
=0;
369 if (--cs
->hw
.elsa
.transcnt
<= 0)
371 } while (--count
> 0);
372 if ((cs
->hw
.elsa
.transcnt
< WAKEUP_CHARS
) && (cs
->hw
.elsa
.MFlag
==2))
373 modem_fill(cs
->hw
.elsa
.bcs
);
375 #ifdef SERIAL_DEBUG_INTR
380 if (cs
->hw
.elsa
.transcnt
<= 0) {
381 cs
->hw
.elsa
.IER
&= ~UART_IER_THRI
;
382 serial_outp(cs
, UART_IER
, cs
->hw
.elsa
.IER
);
387 static void rs_interrupt_elsa(struct IsdnCardState
*cs
)
389 int status
, iir
, msr
;
390 int pass_counter
= 0;
392 #ifdef SERIAL_DEBUG_INTR
393 printk(KERN_DEBUG
"rs_interrupt_single(%d)...", cs
->irq
);
397 status
= serial_inp(cs
, UART_LSR
);
398 debugl1(cs
,"rs LSR %02x", status
);
399 #ifdef SERIAL_DEBUG_INTR
400 printk("status = %x...", status
);
402 if (status
& UART_LSR_DR
)
403 receive_chars(cs
, &status
);
404 if (status
& UART_LSR_THRE
)
405 transmit_chars(cs
, NULL
);
406 if (pass_counter
++ > RS_ISR_PASS_LIMIT
) {
407 printk("rs_single loop break.\n");
410 iir
= serial_inp(cs
, UART_IIR
);
411 debugl1(cs
,"rs IIR %02x", iir
);
412 if ((iir
& 0xf) == 0) {
413 msr
= serial_inp(cs
, UART_MSR
);
414 debugl1(cs
,"rs MSR %02x", msr
);
416 } while (!(iir
& UART_IIR_NO_INT
));
417 #ifdef SERIAL_DEBUG_INTR
422 extern int open_hscxstate(struct IsdnCardState
*cs
, struct BCState
*bcs
);
423 extern void modehscx(struct BCState
*bcs
, int mode
, int bc
);
424 extern void hscx_l2l1(struct PStack
*st
, int pr
, void *arg
);
427 close_elsastate(struct BCState
*bcs
)
429 modehscx(bcs
, 0, bcs
->channel
);
430 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
431 if (bcs
->hw
.hscx
.rcvbuf
) {
432 if (bcs
->mode
!= L1_MODE_MODEM
)
433 kfree(bcs
->hw
.hscx
.rcvbuf
);
434 bcs
->hw
.hscx
.rcvbuf
= NULL
;
436 skb_queue_purge(&bcs
->rqueue
);
437 skb_queue_purge(&bcs
->squeue
);
439 dev_kfree_skb_any(bcs
->tx_skb
);
441 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
447 modem_write_cmd(struct IsdnCardState
*cs
, u_char
*buf
, int len
) {
453 if (len
> (MAX_MODEM_BUF
- cs
->hw
.elsa
.transcnt
)) {
456 fp
= cs
->hw
.elsa
.transcnt
+ cs
->hw
.elsa
.transp
;
457 fp
&= (MAX_MODEM_BUF
-1);
459 if (count
> MAX_MODEM_BUF
- fp
) {
460 count
= MAX_MODEM_BUF
- fp
;
461 memcpy(cs
->hw
.elsa
.transbuf
+ fp
, msg
, count
);
462 cs
->hw
.elsa
.transcnt
+= count
;
467 memcpy(cs
->hw
.elsa
.transbuf
+ fp
, msg
, count
);
468 cs
->hw
.elsa
.transcnt
+= count
;
469 if (cs
->hw
.elsa
.transcnt
&&
470 !(cs
->hw
.elsa
.IER
& UART_IER_THRI
)) {
471 cs
->hw
.elsa
.IER
|= UART_IER_THRI
;
472 serial_outp(cs
, UART_IER
, cs
->hw
.elsa
.IER
);
477 modem_set_init(struct IsdnCardState
*cs
) {
481 modem_write_cmd(cs
, MInit_1
, strlen(MInit_1
));
483 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
485 debugl1(cs
, "msi tout=%d", timeout
);
487 modem_write_cmd(cs
, MInit_2
, strlen(MInit_2
));
489 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
491 debugl1(cs
, "msi tout=%d", timeout
);
493 modem_write_cmd(cs
, MInit_3
, strlen(MInit_3
));
495 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
497 debugl1(cs
, "msi tout=%d", timeout
);
499 modem_write_cmd(cs
, MInit_4
, strlen(MInit_4
));
501 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
503 debugl1(cs
, "msi tout=%d", timeout
);
505 modem_write_cmd(cs
, MInit_5
, strlen(MInit_5
));
507 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
509 debugl1(cs
, "msi tout=%d", timeout
);
511 modem_write_cmd(cs
, MInit_6
, strlen(MInit_6
));
513 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
515 debugl1(cs
, "msi tout=%d", timeout
);
517 modem_write_cmd(cs
, MInit_7
, strlen(MInit_7
));
519 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
521 debugl1(cs
, "msi tout=%d", timeout
);
526 modem_set_dial(struct IsdnCardState
*cs
, int outgoing
) {
530 modem_write_cmd(cs
, MInit_speed28800
, strlen(MInit_speed28800
));
532 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
534 debugl1(cs
, "msi tout=%d", timeout
);
537 modem_write_cmd(cs
, MInit_dialout
, strlen(MInit_dialout
));
539 modem_write_cmd(cs
, MInit_dialin
, strlen(MInit_dialin
));
541 while(timeout
-- && cs
->hw
.elsa
.transcnt
)
543 debugl1(cs
, "msi tout=%d", timeout
);
548 modem_l2l1(struct PStack
*st
, int pr
, void *arg
)
550 struct BCState
*bcs
= st
->l1
.bcs
;
551 struct sk_buff
*skb
= arg
;
554 if (pr
== (PH_DATA
| REQUEST
)) {
555 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
557 skb_queue_tail(&bcs
->squeue
, skb
);
560 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
561 bcs
->hw
.hscx
.count
= 0;
564 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
565 } else if (pr
== (PH_ACTIVATE
| REQUEST
)) {
566 test_and_set_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
567 st
->l1
.l1l2(st
, PH_ACTIVATE
| CONFIRM
, NULL
);
568 set_arcofi(bcs
->cs
, st
->l1
.bc
);
570 modem_set_dial(bcs
->cs
, test_bit(FLG_ORIG
, &st
->l2
.flag
));
571 bcs
->cs
->hw
.elsa
.MFlag
=2;
572 } else if (pr
== (PH_DEACTIVATE
| REQUEST
)) {
573 test_and_clear_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
574 bcs
->cs
->dc
.isac
.arcofi_bc
= st
->l1
.bc
;
575 arcofi_fsm(bcs
->cs
, ARCOFI_START
, &ARCOFI_XOP_0
);
576 interruptible_sleep_on(&bcs
->cs
->dc
.isac
.arcofi_wait
);
577 bcs
->cs
->hw
.elsa
.MFlag
=1;
579 printk(KERN_WARNING
"ElsaSer: unknown pr %x\n", pr
);
584 setstack_elsa(struct PStack
*st
, struct BCState
*bcs
)
587 bcs
->channel
= st
->l1
.bc
;
588 switch (st
->l1
.mode
) {
591 if (open_hscxstate(st
->l1
.hardware
, bcs
))
593 st
->l2
.l2l1
= hscx_l2l1
;
596 bcs
->mode
= L1_MODE_MODEM
;
597 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
598 bcs
->hw
.hscx
.rcvbuf
= bcs
->cs
->hw
.elsa
.rcvbuf
;
599 skb_queue_head_init(&bcs
->rqueue
);
600 skb_queue_head_init(&bcs
->squeue
);
603 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
605 bcs
->hw
.hscx
.rcvidx
= 0;
607 bcs
->cs
->hw
.elsa
.bcs
= bcs
;
608 st
->l2
.l2l1
= modem_l2l1
;
612 setstack_manager(st
);
619 init_modem(struct IsdnCardState
*cs
) {
621 cs
->bcs
[0].BC_SetStack
= setstack_elsa
;
622 cs
->bcs
[1].BC_SetStack
= setstack_elsa
;
623 cs
->bcs
[0].BC_Close
= close_elsastate
;
624 cs
->bcs
[1].BC_Close
= close_elsastate
;
625 if (!(cs
->hw
.elsa
.rcvbuf
= kmalloc(MAX_MODEM_BUF
,
628 "Elsa: No modem mem hw.elsa.rcvbuf\n");
631 if (!(cs
->hw
.elsa
.transbuf
= kmalloc(MAX_MODEM_BUF
,
634 "Elsa: No modem mem hw.elsa.transbuf\n");
635 kfree(cs
->hw
.elsa
.rcvbuf
);
636 cs
->hw
.elsa
.rcvbuf
= NULL
;
640 printk(KERN_WARNING
"Elsa: problem startup modem\n");
646 release_modem(struct IsdnCardState
*cs
) {
648 cs
->hw
.elsa
.MFlag
= 0;
649 if (cs
->hw
.elsa
.transbuf
) {
650 if (cs
->hw
.elsa
.rcvbuf
) {
652 kfree(cs
->hw
.elsa
.rcvbuf
);
653 cs
->hw
.elsa
.rcvbuf
= NULL
;
655 kfree(cs
->hw
.elsa
.transbuf
);
656 cs
->hw
.elsa
.transbuf
= NULL
;