• Vladimir Oltean's avatar
    net: dsa: tag_ocelot_8021q: add support for PTP timestamping · 0a6f17c6
    Vladimir Oltean authored
    For TX timestamping, we use the felix_txtstamp method which is common
    with the regular (non-8021q) ocelot tagger. This method says that skb
    deferral is needed, prepares a timestamp request ID, and puts a clone of
    the skb in a queue waiting for the timestamp IRQ.
    
    felix_txtstamp is called by dsa_skb_tx_timestamp() just before the
    tagger's xmit method. In the tagger xmit, we divert the packets
    classified by dsa_skb_tx_timestamp() as PTP towards the MMIO-based
    injection registers, and we declare them as dead towards dsa_slave_xmit.
    If not PTP, we proceed with normal tag_8021q stuff.
    
    Then the timestamp IRQ fires, the clone queued up from felix_txtstamp is
    matched to the TX timestamp retrieved from the switch's FIFO based on
    the timestamp request ID, and the clone is delivered to the stack.
    
    On RX, thanks to the VCAP IS2 rule that redirects the frames with an
    EtherType for 1588 towards two destinations:
    - the CPU port module (for MMIO based extraction) and
    - if the "no XTR IRQ" workaround is in place, the dsa_8021q CPU port
    the relevant data path processing starts in the ptp_classify_raw BPF
    classifier installed by DSA in the RX data path (post tagger, which is
    completely unaware that it saw a PTP packet).
    
    This time we can't reuse the same implementation of .port_rxtstamp that
    also works with the default ocelot tagger. That is because felix_rxtstamp
    is given an skb with a freshly stripped DSA header, and it says "I don't
    need deferral for its RX timestamp, it's right in it, let me show you";
    and it just points to the header right behind skb->data, from where it
    unpacks the timestamp and annotates the skb with it.
    
    The same thing cannot happen with tag_ocelot_8021q, because for one
    thing, the skb did not have an extraction frame header in the first
    place, but a VLAN tag with no timestamp information. So the code paths
    in felix_rxtstamp for the regular and 8021q tagger are completely
    independent. With tag_8021q, the timestamp must come from the packet's
    duplicate delivered to the CPU port module, but there is potentially
    complex logic to be handled [ and prone to reordering ] if we were to
    just start reading packets from the CPU port module, and try to match
    them to the one we received over Ethernet and which needs an RX
    timestamp. So we do something simple: we tell DSA "give me some time to
    think" (we request skb deferral by returning false from .port_rxtstamp)
    and we just drop the frame we got over Ethernet with no attempt to match
    it to anything - we just treat it as a notification that there's data to
    be processed from the CPU port module's queues. Then we proceed to read
    the packets from those, one by one, which we deliver up the stack,
    timestamped, using netif_rx - the same function that any driver would
    use anyway if it needed RX timestamp deferral. So the assumption is that
    we'll come across the PTP packet that triggered the CPU extraction
    notification eventually, but we don't know when exactly. Thanks to the
    VCAP IS2 trap/redirect rule and the exclusion of the CPU port module
    from the flooding replicators, only PTP frames should be present in the
    CPU port module's RX queues anyway.
    
    There is just one conflict between the VCAP IS2 trapping rule and the
    semantics of the BPF classifier. Namely, ptp_classify_raw() deems
    general messages as non-timestampable, but still, those are trapped to
    the CPU port module since they have an EtherType of ETH_P_1588. So, if
    the "no XTR IRQ" workaround is in place, we need to run another BPF
    classifier on the frames extracted over MMIO, to avoid duplicates being
    sent to the stack (once over Ethernet, once over MMIO). It doesn't look
    like it's possible to install VCAP IS2 rules based on keys extracted
    from the 1588 frame headers.
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    0a6f17c6
ocelot.h 25.4 KB