2.0.30 serial.c, ppp.c and pppd-2.2 questions

Rob Riggs (rob@DevilsThumb.COM)
Fri, 18 Jul 1997 18:07:22 -0600


After some time exploring and hacking around in the above
mentioned code, I have a few observations and questions.

In serial.c's receive_char() interrupt handler we read a
char from the UART then just drop it if the flip buffer
is full. If we are going to do this we should indicate
an overflow error. An alternative solution is to test if
the flip buffer is full before we read the UART and just
break out of the read loop. Then, if the UART buffer
overflows, the UART reports the error. This method is
optimal for UARTs that implement automatic flow control.
(The UART drops RTS when the read FIFO reaches a certain
level and stops sending from the transmit FIFO when CTS
is dropped.)

If we don't read the UART data when the flip buffer is full
it would be nice to mask the "data ready" interrupt until
we have an empty flip buffer. This would require a callback
from the tty layer's flush_to_ldisc() to notify us that the
flip buffer has been flipped. This would also allow flow
control based on how full the flip buffer is.

In pppd, the code sets up the tty to IGNPAR & IGNBRK. In
serial.c, if both of those are set, then it ignores parity
errors and breaks, but also overflow errors. If we receive
any of these errors in serial.c during a ppp connection,
they are ignored.

However, in ppp.c we test for errors in the tty flip buffer
and drop the frame if there are any. This saves time, because
we skip both FCS computation and moving of data into the
receive buffer when a tty error is indicated. In an overflow
situation (we did not keep up with the serial input),
especially if we are dropping characters from the flip buffer,
this is win. Bottom half processing goes much faster which
means can swap the flip buffer faster. Because the overflow
condition is not passed along, we must wait until the frame
is done. ppp.c processes all the data as valid, until "end
of frame" is caught and it discovers that the FCS is bad.

The questions are:

1. Should pppd really be setting the tty to IGNPAR & IGNBRK?

2. Should serial.c ignore overflows if IGNPAR & IGNBRK are set?
(I'm not sure what POSIX has to say about it. I didn't see
anything mentioned in the books that I have.)

3. Should we drop data when the flip buffer is full and not
report it as an overflow? (Again, POSIX may indicate
what is and isn't allowed.)

4. Should we drop data at all, or should we let the UART
overflow on its own and report the error to us? (We
would need to mask the "data ready" interrupt until
there is an empty flip buffer available.)

5. Are there any problems with doing flow control based on
how full the flip buffer is?

Lots to ponder...

Also... the irqtune homepage (http://www.best.com/~cae/irqtune)
has this little tidbit:

The flip-buffer is a double buffer mechanism in
the serial/tty drivers through which all data must
pass. It has a fixed size of only 512 bytes. MRU/MTU
greater than the flip-buffer size may create an internal
race condition that may cause dropouts on slower CPU's
or heavily loaded configurations.

I was unable to see where any race condition due to MRU/MTU size
can occur. I am hoping someone can shed some light on this for me.

(Of course I got into all of this because I am overflowing
the flip buffer occasionally even at 64Kbps. Things get
real ugly at 128Kbps. The UART is running at 230400bps while
connected to an ISDN TA on a 486-66.)

-Rob

P.S. Please cc: all replies directly to me. -Thanks