\documentclass[aspectratio=169,obeyspaces,spaces,hyphens,dvipsnames]{beamer}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}% http://ctan.org/pkg/lm
\usepackage{minted}
\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{pgfplots}
\usepackage{tikz}
\usepackage[normalem]{ulem}

\mode<presentation>
\usetheme{Bootlin}

\def\signed #1{{\leavevmode\unskip\nobreak\hfil\penalty50\hskip2em
  \hbox{}\nobreak\hfil(#1)
  \parfillskip=0pt \finalhyphendemerits=0 \endgraf}}

\newsavebox\mybox
\newenvironment{aquote}[1]
  {\savebox\mybox{#1}\begin{quotation}}
  {\signed{\usebox\mybox}\end{quotation}}

\title{Improving IEEE 802.15.4 MAC management support}
\authors{Miquel Raynal}
\email{miquel.raynal@bootlin.com}
\slidesurl{https://bootlin.com/pub/conferences/}
\institute{Bootlin}
\conference{Linux Plumbers Conference, Fall 2022}

\begin{document}

\addtocontents{toc}{\protect\setcounter{tocdepth}{-1}}
\section{Improving \\IEEE 802.15.4 MAC management support in the Linux kernel}
\addtocontents{toc}{\protect\setcounter{tocdepth}{2}}

\begin{frame}{Miquel Raynal}
  \begin{itemize}
  \item Embedded Linux engineer at Bootlin
    \begin{itemize}
    \item Embedded Linux {\bf expertise}
    \item {\bf Development}, consulting and training
    \item Strong open-source focus
    \end{itemize}
  \item Open-source contributor
    \begin{itemize}
    \item Maintainer of the NAND subsystem
    \item Co-maintainer of the MTD subsystem
    \item Kernel support for various ARM SoCs
    \item {\bf Active contributor to the WPAN subsystem} with Qorvo support
    \end{itemize}
  \item Living in {\bf Toulouse}, France
  \end{itemize}
\end{frame}

\subsection{The IEEE 802.15.4 specification in a nutshell}

\begin{frame}{Functional description}
  \begin{columns}
    \column{0.5\textwidth}
    \begin{itemize}
    \item Defines the PHY layer and the MAC sublayer
      \begin{itemize}
      \item Introduced to build Wireless Personal Area Networks (WPAN)
      \item Low power, low range (10m), low rate (up to 250kib/s)
      \item Easy connection between sensors and actuators
      \item A base for Zigbee and 6LowPan
      \end{itemize}
    \item Focus on the MAC sublayer:
      \begin{itemize}
      \item MAC data services
      \item MAC management services through the MAC subLayer Management Entity (MLME)
      \end{itemize}
    \end{itemize}
    \column{0.5\textwidth}
    \begin{center}
      \includegraphics[width=0.9\textwidth]{osi.pdf}
                      {\tiny\break IEEE 802.15.4 stack integration in the OSI model}
    \end{center}
  \end{columns}
\end{frame}

\begin{frame}{Personal Area Networks (PAN)}
  Devices connect together to form PANs
  \begin{itemize}
  \item One PAN coordinator which takes a PAN ID
    \begin{itemize}
    \item Advertises the PAN
    \item Allows devices associations
    \item May serve as a bridge with the Internet
    \end{itemize}
  \item Coordinators
    \begin{itemize}
    \item Advertise the PAN
    \item Allow devices associations
    \item Follow the PAN coordinator realignments
    \end{itemize}
  \item Leaf nodes
    \begin{itemize}
    \item Follow their coordinator realignments
    \item Send data
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{PAN advertisement and discovery}
  \begin{itemize}
  \item Coordinators and PAN coordinators shall advertise their PAN by sending beacons
    \begin{itemize}
    \item Either upon reception of a \code{BEACON REQUEST}
    \item Or ``passively'' at a given rate, in beacon-enabled PANs
    \end{itemize}
  \item Beacons are short frames with information about the emitting device and its PAN
  \end{itemize}
  \begin{columns}
    \column{0.5\textwidth}
    \begin{itemize}
    \item Devices can scan the various channels they support
      \begin{itemize}
      \item Passive scans to detect surrounding beacon enabled PANs with their LQI
      \item Active scans to detect surrounding beacon and non-beacon enabled PANs with their LQI
      \end{itemize}
    \end{itemize}
    \column{0.5\textwidth}
    \begin{center}
    \includegraphics[width=0.8\textwidth]{alex-network.png}
                    {\tiny \\Alexandre Belloni's IEEE 802.15.4 based home network}
    \end{center}
  \end{columns}
\end{frame}

\begin{frame}{MLME operations}
  \begin{itemize}
  \item MAC management commands
    \begin{itemize}
    \item Discovering surrounding devices (scanning, beaconing)
    \item Enlarging/shrinking the network (associating, dis-associating)
    \item Keeping all devices synchronized (beaconing, acknowledgments, etc)
    \item Handling faulty situations (loss of contact, conflicts, etc)
    \end{itemize}
  \end{itemize}
\end{frame}

\subsection{The Linux kernel IEEE 802.15.4 stack}

\begin{frame}{Architecture}
  \begin{center}
    \includegraphics[height=0.85\textheight]{linux-stack.pdf}
  \end{center}
\end{frame}

\begin{frame}{New MLME interfaces: scanning/beaconing}
  \begin{itemize}
  \item Netlink user requests with commands related payloads
    \begin{itemize}
    \item Type of scan
    \item Beacon interval
    \item Channels to use
    \end{itemize}
  \item Once processed, the request is forwarded to the MAC layer:
    \begin{itemize}
    \item Changes on the ongoing Tx traffic
    \item Hardware address filters update
    \item Start of a background thread
    \end{itemize}
  \item Background jobs can be aborted at any moment (netlink command)
    or may end naturally
    \begin{itemize}
    \item Upon completion/abort userspace gets notified
    \item The interface is set back in its original state
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{New MLME interfaces: associating/dis-associating}
  \begin{itemize}
  \item No background job involved
  \item MLME commands must be \code{ACK}ed
  \item Processing received requests often involves sending a response
  \item Association requests should be forwarded to userspace for
    validation (not implemented)
  \end{itemize}
\end{frame}

\begin{frame}{Demo time}
  Hardware setup:
  \begin{itemize}
  \item One ATUSB device acting like a PAN coordinator (wpan0/coord0)
  \item One ATUSB device acting like a leaf node (wpan1/coord1)
  \item One ATUSB device monitoring (wpan2/mon2)
  \item One Arduino Nano 33 BLE running Zephyr being a leaf node
  \end{itemize}
  \begin{center}
    \includegraphics[height=0.5\textheight]{hw.jpg}
  \end{center}
\end{frame}

\begin{frame}{Upstream proposals, discussions ongoing}
  \begin{itemize}
  \item Kernel patches:
    \begin{itemize}
    \item v2 {\tiny\url{https://lore.kernel.org/all/20220826144049.256134-1-miquel.raynal@bootlin.com/}}
    \item v3/only filtering {\tiny\url{https://lore.kernel.org/all/20220905203412.1322947-1-miquel.raynal@bootlin.com/}}
    \item Latest version {\tiny\url{https://github.com/miquelraynal/linux/tree/wpan-next/scan}}
    \end{itemize}
  \item wpan-tools patches:
    \begin{itemize}
    \item Last patches {\tiny\url{https://lore.kernel.org/all/20220701143434.1267864-1-miquel.raynal@bootlin.com/}}
    \item Latest version {\tiny\url{https://github.com/miquelraynal/wpan-tools/tree/wpan-master/scan}}
    \end{itemize}
  \item Zephyr changes {\tiny\url{https://github.com/zephyrproject-rtos/zephyr/pull/49947}}
  \end{itemize}
  No support for orphan notifications/coordinator realignments yet
\end{frame}

\subsection{Major issues, past and present}

\begin{frame}{MLME transmissions 1/2}
  Description of the problem:
  \begin{itemize}
  \item The wpan core expects transmit callbacks to be asynchronous
    \begin{itemize}
    \item Only packet offloading to the transceiver is synchronous
      \begin{itemize}
      \item Errors during this step can be returned
      \end{itemize}
    \item The actual packet transmission may happen later
      \begin{itemize}
      \item Can only happen when the medium is available
      \item Perhaps there won't be any timeslot available immediately
      \item The transceiver needs to wait for an \code{ACK}
      \item Possibility to repeat the packet up to 7 times (usually 3)
      \end{itemize}
    \item MLME transmissions {\bf must} be \code{ACK}ed, we need a status
    \item We want MLME operations to be over before resuming normal operations
    \end{itemize}
  \item Asynchronous transmissions cannot work alone, we need an alternative
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{MLME transmissions 2/2}
  Solution considered:
  \begin{itemize}
  \item A hot path is considered for data transmission
  \item Creation of a second, slow and synchronous Tx Path for MLME transmissions
    \begin{itemize}
    \item Device drivers already call helpers upon completion to:
      \begin{itemize}
      \item Handle Inter Frame Spacing (IFS), a short inactive period after each frame
      \item Consume the \code{skb}
      \end{itemize}
    \item We could use them to:
      \begin{itemize}
      \item Follow the count of ongoing transmissions
      \item Possibly return an error code, if any?
      \end{itemize}
    \end{itemize}
  \end{itemize}
  \begin{block}{include/net/mac802154.h}
    \fontsize{9}{9}\selectfont
    \begin{minted}{c}
    \end{minted}
void ieee802154\_xmit\_complete(struct ieee802154\_hw *hw, struct sk\_buff *skb, bool ifs\_handling);
void ieee802154\_xmit\_error(struct ieee802154\_hw *hw, struct sk\_buff *skb, int reason);
  \end{block}
\end{frame}

\begin{frame}[fragile]{Error codes 1/2}
  Sub-problem: forwarding errors
  \begin{itemize}
  \item It is important to know if the MLME frame was successfully received
  \item Example of status register: \code{TRAC}
    \begin{itemize}
    \item Not in the spec
    \item Hopefully wide spread
    \end{itemize}
  \end{itemize}
  \begin{block}{TRAC values}
    \fontsize{9}{9}\selectfont
    \begin{minted}{c}
TRAC_SUCCESS
TRAC_SUCCESS_DATA_PENDING
TRAC_SUCCESS_WAIT_FOR_ACK
TRAC_CHANNEL_ACCESS_FAILURE
TRAC_NO_ACK
TRAC_INVALID
    \end{minted}
  \end{block}
\end{frame}

\begin{frame}{Error codes 2/2}
  Down side:
  \begin{itemize}
  \item Using ATUSB devices: no \code{TRAC} register support in the firmware
  \end{itemize}
  Bright side:
  \begin{itemize}
  \item The firmware is open source
  \item Another driver (\code{at86rf230.c}) is very close and has \code{TRAC} support
  \item Alexander Aring (WPAN co-maintainer) does not need sleep and knows very well the firmware
  \item Patches now available\\
    {\footnotesize\url{https://lore.kernel.org/all/20220906082104.1338694-3-miquel.raynal@bootlin.com/}}
  \end{itemize}
  In general, all devices and drivers should have access to these information, otherwise they are badly designed
\end{frame}

\begin{frame}{Filtering constraints}
  \begin{itemize}
  \item Intermediate filtering levels not described
    \begin{itemize}
    \item Currently supported: ``no filtering'' or ``full filtering''
    \item Specific filtering modes shall be entered during scans
    \item Must be supported by software if not available in hardware
    \end{itemize}
  \item Enabling promiscuous mode (the one which disables all checks) also disables \code{ACK}s for sniffing devices
    \begin{itemize}
    \item As opposed to filtering levels, \code{ACK} generation cannot be handled by software
    \item Running interfaces in promiscuous mode and non promiscuous mode on the same PHY shall be prevented
    \end{itemize}
  \item The promiscuous mode alone does not make sense
    \begin{itemize}
    \item Alexander has proposed a first patch to move towards a more
      unified filtering API and give to the \code{drv_start()} hook a
      filtering level to work with
    \end{itemize}
%  \item Several interfaces on the same PHY vs. different filtering level expectations
%    \begin{itemize}
%    \item Today's PHYs have a single filtering level at a time, what about tomorrow?
%    \end{itemize}
  \end{itemize}
\end{frame}

%\begin{frame}{Lockdep hates me 1/3}
%  Situation:
%  \begin{itemize}
%  \item \code{rtnl} acquired during almost all netlink commands
%    \begin{itemize}
%    \item Structurally needed in the WPAN netlink layer right now
%    \item This dependency has been partially removed in the wireless subsystem
%    \end{itemize}
%  \item Need to serialize accesses to the structures defining the scan/beacon background jobs:
%    \begin{itemize}
%    \item Taking the \code{rtnl} in the background job to protect them would be costly
%    \item Introduction of \code{scan_lock}/\code{beacon_lock}
%      \begin{itemize}
%      \item Lock dependency \code{rtnl} $\rightarrow$ \code{scan_lock}/\code{beacon_lock}
%      \end{itemize}
%    \end{itemize}
%  \item The background jobs must send MLME frames (beacons or \code{BEACON REQUEST}s)
%    \begin{itemize}
%    \item The MLME Tx path acquires the \code{rtnl} to prevent device removal
%      \begin{itemize}
%      \item Lock dependency \code{scan_lock}/\code{beacon_lock} $\rightarrow$ \code{rtnl}
%      \end{itemize}
%    \end{itemize}
%  \item Circular dependency!
%  \end{itemize}
%  Workaround: create a device lock to avoid device removal during MLME Tx instead of using the \code{rtnl}
%\end{frame}

\begin{frame}{Lockdep hates me 1/2}
  There is still an issue with the scan:
  \begin{itemize}
  \item Scanning involves changing channels in the background job
    \begin{itemize}
    \item Channel changes are protected by the \code{rtnl}
    \item \code{mac802154_hwsim.c} for instance requires the \code{rtnl} when changing some of its PIB attributes like the channel/page.
      \begin{itemize}
      \item Lock dependency: \code{scan_lock} $\rightarrow$ \code{rtnl}
      \end{itemize}
    \end{itemize}
  \item The \code{rtnl} is always acquired before changing scan parameters
    \begin{itemize}
    \item There is an \code{ASSERT_RTNL()} in the \code{nl802154_pre_doit()} as soon as we need a \code{netdev}
      \begin{itemize}
      \item Lock dependency: \code{rtnl} $\rightarrow$ \code{scan_lock}
      \end{itemize}
    \end{itemize}
  \item Circular dependency!
  \item Mandatory to take the \code{rtnl} before the \code{scan_lock} in
    the background job
  \end{itemize}
  So the in the end the \code{scan_lock} is useless, besides showing what needs to be protected if we ever drop the \code{rtnl} there
\end{frame}

\begin{frame}{Lockdep hates me 2/2}
  Situation:
  \begin{itemize}
  \item Scanning/beaconing background jobs use the device's workqueue
    \begin{itemize}
    \item Workqueue completion lock acquired when the job is running
    \item The job acquires the \code{rtnl}
      \begin{itemize}
      \item Dependency lock: workqueue lock $\rightarrow$ \code{rtnl}
      \end{itemize}
    \item At \code{stop()} time the \code{rtnl} must be acquired
    \item Stopping a device involves flushing the workqueue, with its lock acquired
      \begin{itemize}
      \item Dependency lock: \code{rtnl} $\rightarrow$ workqueue lock
      \end{itemize}
    \item Circular dependency!
    \end{itemize}
  \end{itemize}
  Workaround: using another queue for the MLME background jobs, which must be stopped before removal anyway and does not need to be flushed explicitly with the \code{rtnl} acquired
\end{frame}

\questionslide

\end{document}
