[rtems-libbsd commit] ppp: Fix transmitting data

Christian Mauderer christianm at rtems.org
Fri Feb 11 07:42:48 UTC 2022


Module:    rtems-libbsd
Branch:    6-freebsd-12
Commit:    17ac5a8cfe0bb0f6c2425dc4288363ba0d114e71
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=17ac5a8cfe0bb0f6c2425dc4288363ba0d114e71

Author:    Christian Mauderer <christian.mauderer at embedded-brains.de>
Date:      Thu Aug 12 08:54:20 2021 +0200

ppp: Fix transmitting data

The pppstart expected that a driver write would somehow magically
process all data passed to the write function. Because ppp disables all
buffering that originally has been in termios, that assumption is not
true for all but polled drivers.

With this patch, the pppstart now gets and processes the feedback that
is returned from the driver via rtems_termios_dequeue_characters.

Fixes #4493

---

 rtemsbsd/sys/net/if_ppp.c    | 11 ++++++-----
 rtemsbsd/sys/net/if_pppvar.h |  1 +
 rtemsbsd/sys/net/ppp_tty.c   | 32 ++++++++++++++++++++++++++++----
 3 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/rtemsbsd/sys/net/if_ppp.c b/rtemsbsd/sys/net/if_ppp.c
index 709f13e..e134dc7 100644
--- a/rtemsbsd/sys/net/if_ppp.c
+++ b/rtemsbsd/sys/net/if_ppp.c
@@ -313,11 +313,12 @@ static rtems_task ppp_txdaemon(rtems_task_argument arg)
       frag=0;
 
       /* initialize output values */
-      sc->sc_outfcs    = PPP_INITFCS;
-      sc->sc_outbuf    = (u_char *)0;
-      sc->sc_outlen    = (short   )0;
-      sc->sc_outoff    = (short   )0;
-      sc->sc_outfcslen = (short   )0;
+      sc->sc_outfcs        = PPP_INITFCS;
+      sc->sc_outbuf        = (u_char *)0;
+      sc->sc_outlen        = (short   )0;
+      sc->sc_outoff        = (short   )0;
+      sc->sc_outoff_update = false;
+      sc->sc_outfcslen     = (short   )0;
 
 /*	  printf("Start Transmit Packet..\n"); */
 
diff --git a/rtemsbsd/sys/net/if_pppvar.h b/rtemsbsd/sys/net/if_pppvar.h
index fdfb56d..bd11bcb 100644
--- a/rtemsbsd/sys/net/if_pppvar.h
+++ b/rtemsbsd/sys/net/if_pppvar.h
@@ -117,6 +117,7 @@ struct ppp_softc {
 
 	struct	ifqueue sc_freeq;       /* free packets */
 	short	sc_outoff;		/* output packet byte offset */
+	bool	sc_outoff_update;	/* outoff needs update in pppstart */
 	short	sc_outflag;		/* output status flag */
 	short	sc_outlen;		/* length of output packet */
 	short	sc_outfcslen;		/* length of output fcs data */
diff --git a/rtemsbsd/sys/net/ppp_tty.c b/rtemsbsd/sys/net/ppp_tty.c
index 80d4fee..2e850dc 100644
--- a/rtemsbsd/sys/net/ppp_tty.c
+++ b/rtemsbsd/sys/net/ppp_tty.c
@@ -124,7 +124,7 @@ int     pppread(struct rtems_termios_tty *tty, rtems_libio_rw_args_t *rw_args);
 int     pppwrite(struct rtems_termios_tty *tty, rtems_libio_rw_args_t *rw_args);
 int     ppptioctl(struct rtems_termios_tty *tty, rtems_libio_ioctl_args_t *args);
 int     pppinput(int c, struct rtems_termios_tty *tty);
-int     pppstart(struct rtems_termios_tty *tp);
+int     pppstart(struct rtems_termios_tty *tp, int len);
 u_short pppfcs(u_short fcs, u_char *cp, int len);
 void    pppallocmbuf(struct ppp_softc *sc, struct mbuf **mp);
 
@@ -557,7 +557,7 @@ pppasyncctlp(
  * Called at spltty or higher.
  */
 int
-pppstart(struct rtems_termios_tty *tp)
+pppstart(struct rtems_termios_tty *tp, int len)
 {
   u_char             *sendBegin;
   u_long              ioffset = (u_long       )0;
@@ -567,6 +567,13 @@ pppstart(struct rtems_termios_tty *tp)
 
   /* ensure input is valid and we are busy */
   if (( sc != NULL ) && ( sc->sc_outflag & SC_TX_BUSY )) {
+    /* Adapt offsets if necessary */
+    if ( sc->sc_outoff_update ) {
+      sc->sc_stats.ppp_obytes += len;
+      sc->sc_outoff += len;
+      sc->sc_outoff_update = false;
+    }
+
     /* check to see if we need to get the next buffer */
 
     /* Ready with PPP_FLAG Character ? */
@@ -644,8 +651,25 @@ pppstart(struct rtems_termios_tty *tp)
 
       /* write out the character(s) and update the stats */
       (*tp->handler.write)(ctx, (char *)sendBegin, (ioffset > 0) ? ioffset : 1);
-      sc->sc_stats.ppp_obytes += (ioffset > 0) ? ioffset : 1;
-      sc->sc_outoff += ioffset;
+      /*
+       * In case of polled drivers, everything is sent here. So adapt the
+       * offsets. In case of interrupt or task driven drivers, we don't know
+       * whether all characters have been sent. We only get feedback via
+       * rtems_termios_dequeue_characters() function which is the one that is
+       * calling us.
+       */
+      if (tp->handler.mode == TERMIOS_POLLED) {
+        sc->sc_stats.ppp_obytes += (ioffset > 0) ? ioffset : 1;
+        sc->sc_outoff += ioffset;
+        sc->sc_outoff_update = false;
+      } else {
+        if (ioffset > 0) {
+          sc->sc_outoff_update = true;
+        } else {
+          sc->sc_outoff_update = false;
+          sc->sc_stats.ppp_obytes += 1;
+        }
+      }
 
       return (0);
     }



More information about the vc mailing list