1. 20 8月, 2021 1 次提交
  2. 19 8月, 2021 1 次提交
  3. 16 8月, 2021 2 次提交
    • V
      net: mscc: ocelot: convert to phylink · e6e12df6
      Vladimir Oltean 提交于
      The felix DSA driver, which is a wrapper over the same hardware class as
      ocelot, is integrated with phylink, but ocelot is using the plain PHY
      library. It makes sense to bring together the two implementations, which
      is what this patch achieves.
      
      This is a large patch and hard to break up, but it does the following:
      
      The existing ocelot_adjust_link writes some registers, and
      felix_phylink_mac_link_up writes some registers, some of them are
      common, but both functions write to some registers to which the other
      doesn't.
      
      The main reasons for this are:
      - Felix switches so far have used an NXP PCS so they had no need to
        write the PCS1G registers that ocelot_adjust_link writes
      - Felix switches have the MAC fixed at 1G, so some of the MAC speed
        changes actually break the link and must be avoided.
      
      The naming conventions for the functions introduced in this patch are:
      - vsc7514_phylink_{mac_config,validate} are specific to the Ocelot
        instantiations and placed in ocelot_net.c which is built only for the
        ocelot switchdev driver.
      - ocelot_phylink_mac_link_{up,down} are shared between the ocelot
        switchdev driver and the felix DSA driver (they are put in the common
        lib).
      
      One by one, the registers written by ocelot_adjust_link are:
      
      DEV_MAC_MODE_CFG - felix_phylink_mac_link_up had no need to write this
                         register since its out-of-reset value was fine and
                         did not need changing. The write is moved to the
                         common ocelot_phylink_mac_link_up and on felix it is
                         guarded by a quirk bit that makes the written value
                         identical with the out-of-reset one
      DEV_PORT_MISC - runtime invariant, was moved to vsc7514_phylink_mac_config
      PCS1G_MODE_CFG - same as above
      PCS1G_SD_CFG - same as above
      PCS1G_CFG - same as above
      PCS1G_ANEG_CFG - same as above
      PCS1G_LB_CFG - same as above
      DEV_MAC_ENA_CFG - both ocelot_adjust_link and ocelot_port_disable
                        touched this. felix_phylink_mac_link_{up,down} also
                        do. We go with what felix does and put it in
                        ocelot_phylink_mac_link_up.
      DEV_CLOCK_CFG - ocelot_adjust_link and felix_phylink_mac_link_up both
                      write this, but to different values. Move to the common
                      ocelot_phylink_mac_link_up and make sure via the quirk
                      that the old values are preserved for both.
      ANA_PFC_PFC_CFG - ocelot_adjust_link wrote this, felix_phylink_mac_link_up
                        did not. Runtime invariant, speed does not matter since
                        PFC is disabled via the RX_PFC_ENA bits which are cleared.
                        Move to vsc7514_phylink_mac_config.
      QSYS_SWITCH_PORT_MODE_PORT_ENA - both ocelot_adjust_link and
                                       felix_phylink_mac_link_{up,down} wrote
                                       this. Ocelot also wrote this register
                                       from ocelot_port_disable. Keep what
                                       felix did, move in ocelot_phylink_mac_link_{up,down}
                                       and delete ocelot_port_disable.
      ANA_POL_FLOWC - same as above
      SYS_MAC_FC_CFG - same as above, except slight behavior change. Whereas
                       ocelot always enabled RX and TX flow control, felix
                       listened to phylink (for the most part, at least - see
                       the 2500base-X comment).
      
      The registers which only felix_phylink_mac_link_up wrote are:
      
      SYS_PAUSE_CFG_PAUSE_ENA - this is why I am not sure that flow control
                                worked on ocelot. Not it should, since the
                                code is shared with felix where it does.
      ANA_PORT_PORT_CFG - this is a Frame Analyzer block register, phylink
                          should be the one touching them, deleted.
      
      Other changes:
      
      - The old phylib registration code was in mscc_ocelot_init_ports. It is
        hard to work with 2 levels of indentation already in, and with hard to
        follow teardown logic. The new phylink registration code was moved
        inside ocelot_probe_port(), right between alloc_etherdev() and
        register_netdev(). It could not be done before (=> outside of)
        ocelot_probe_port() because ocelot_probe_port() allocates the struct
        ocelot_port which we then use to assign ocelot_port->phy_mode to. It
        is more preferable to me to have all PHY handling logic inside the
        same function.
      - On the same topic: struct ocelot_port_private :: serdes is only used
        in ocelot_port_open to set the SERDES protocol to Ethernet. This is
        logically a runtime invariant and can be done just once, when the port
        registers with phylink. We therefore don't even need to keep the
        serdes reference inside struct ocelot_port_private, or to use the devm
        variant of of_phy_get().
      - Phylink needs a valid phy-mode for phylink_create() to succeed, and
        the existing device tree bindings in arch/mips/boot/dts/mscc/ocelot_pcb120.dts
        don't define one for the internal PHY ports. So we patch
        PHY_INTERFACE_MODE_NA into PHY_INTERFACE_MODE_INTERNAL.
      - There was a strategically placed:
      
      	switch (priv->phy_mode) {
      	case PHY_INTERFACE_MODE_NA:
      	        continue;
      
        which made the code skip the serdes initialization for the internal
        PHY ports. Frankly that is not all that obvious, so now we explicitly
        initialize the serdes under an "if" condition and not rely on code
        jumps, so everything is clearer.
      - There was a write of OCELOT_SPEED_1000 to DEV_CLOCK_CFG for QSGMII
        ports. Since that is in fact the default value for the register field
        DEV_CLOCK_CFG_LINK_SPEED, I can only guess the intention was to clear
        the adjacent fields, MAC_TX_RST and MAC_RX_RST, aka take the port out
        of reset, which does match the comment. I don't even want to know why
        this code is placed there, but if there is indeed an issue that all
        ports that share a QSGMII lane must all be up, then this logic is
        already buggy, since mscc_ocelot_init_ports iterates using
        for_each_available_child_of_node, so nobody prevents the user from
        putting a 'status = "disabled";' for some QSGMII ports which would
        break the driver's assumption.
        In any case, in the eventuality that I'm right, we would have yet
        another issue if ocelot_phylink_mac_link_down would reset those ports
        and that would be forbidden, so since the ocelot_adjust_link logic did
        not do that (maybe for a reason), add another quirk to preserve the
        old logic.
      
      The ocelot driver teardown goes through all ports in one fell swoop.
      When initialization of one port fails, the ocelot->ports[port] pointer
      for that is reset to NULL, and teardown is done only for non-NULL ports,
      so there is no reason to do partial teardowns, let the central
      mscc_ocelot_release_ports() do its job.
      
      Tested bind, unbind, rebind, link up, link down, speed change on mock-up
      hardware (modified the driver to probe on Felix VSC9959). Also
      regression tested the felix DSA driver. Could not test the Ocelot
      specific bits (PCS1G, SERDES, device tree bindings).
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      e6e12df6
    • V
      net: dsa: felix: stop calling ocelot_port_{enable,disable} · 46efe4ef
      Vladimir Oltean 提交于
      ocelot_port_enable touches ANA_PORT_PORT_CFG, which has the following
      fields:
      
      - LOCKED_PORTMOVE_CPU, LEARNDROP, LEARNCPU, LEARNAUTO, RECV_ENA, all of
        which are written with their hardware default values, also runtime
        invariants. So it makes no sense to write these during every .ndo_open.
      
      - PORTID_VAL: this field has an out-of-reset value of zero for all ports
        and must be initialized by software. Additionally, the
        ocelot_setup_logical_port_ids() code path sets up different logical
        port IDs for the ports in a hardware LAG, and we absolutely don't want
        .ndo_open to interfere there and reset those values.
      
      So in fact the write from ocelot_port_enable can better be moved to
      ocelot_init_port, and the .ndo_open hook deleted.
      
      ocelot_port_disable touches DEV_MAC_ENA_CFG and QSYS_SWITCH_PORT_MODE_PORT_ENA,
      in an attempt to undo what ocelot_adjust_link did. But since .ndo_stop
      does not get called each time the link falls (i.e. this isn't a
      substitute for .phylink_mac_link_down), felix already does better at
      this by writing those registers already in felix_phylink_mac_link_down.
      
      So keep ocelot_port_disable (for now, until ocelot is converted to
      phylink too), and just delete the felix call to it, which is not
      necessary.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      46efe4ef
  4. 09 6月, 2021 1 次提交
  5. 28 4月, 2021 3 次提交
  6. 01 4月, 2021 1 次提交
  7. 24 3月, 2021 1 次提交
    • V
      net: ocelot: replay switchdev events when joining bridge · e4bd44e8
      Vladimir Oltean 提交于
      The premise of this change is that the switchdev port attributes and
      objects offloaded by ocelot might have been missed when we are joining
      an already existing bridge port, such as a bonding interface.
      
      The patch pulls these switchdev attributes and objects from the bridge,
      on behalf of the 'bridge port' net device which might be either the
      ocelot switch interface, or the bonding upper interface.
      
      The ocelot_net.c belongs strictly to the switchdev ocelot driver, while
      ocelot.c is part of a library shared with the DSA felix driver.
      The ocelot_port_bridge_leave function (part of the common library) used
      to call ocelot_port_vlan_filtering(false), something which is not
      necessary for DSA, since the framework deals with that already there.
      So we move this function to ocelot_switchdev_unsync, which is specific
      to the switchdev driver.
      
      The code movement described above makes ocelot_port_bridge_leave no
      longer return an error code, so we change its type from int to void.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      e4bd44e8
  8. 19 3月, 2021 1 次提交
    • V
      net: ocelot: support multiple bridges · df291e54
      Vladimir Oltean 提交于
      The ocelot switches are a bit odd in that they do not have an STP state
      to put the ports into. Instead, the forwarding configuration is delayed
      from the typical port_bridge_join into stp_state_set, when the port enters
      the BR_STATE_FORWARDING state.
      
      I can only guess that the implementation of this quirk is the reason that
      led to the simplification of the driver such that only one bridge could
      be offloaded at a time.
      
      We can simplify the data structures somewhat, and introduce a per-port
      bridge device pointer and STP state, similar to how the LAG offload
      works now (there we have a per-port bonding device pointer and TX
      enabled state). This allows offloading multiple bridges with relative
      ease, while still keeping in place the quirk to delay the programming of
      the PGIDs.
      
      We actually need this change now because we need to remove the bogus
      restriction from ocelot_bridge_stp_state_set that ocelot->bridge_mask
      needs to contain BIT(port), otherwise that function is a no-op.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      df291e54
  9. 17 3月, 2021 3 次提交
  10. 17 2月, 2021 1 次提交
    • H
      net: mscc: ocelot: Add support for MRP · d8ea7ff3
      Horatiu Vultur 提交于
      Add basic support for MRP. The HW will just trap all MRP frames on the
      ring ports to CPU and allow the SW to process them. In this way it is
      possible to for this node to behave both as MRM and MRC.
      
      Current limitations are:
      - it doesn't support Interconnect roles.
      - it supports only a single ring.
      - the HW should be able to do forwarding of MRP Test frames so the SW
        will not need to do this. So it would be able to have the role MRC
        without SW support.
      Signed-off-by: NHoratiu Vultur <horatiu.vultur@microchip.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      d8ea7ff3
  11. 16 2月, 2021 1 次提交
    • V
      net: mscc: ocelot: avoid type promotion when calling ocelot_ifh_set_dest · 1f778d50
      Vladimir Oltean 提交于
      Smatch is confused by the fact that a 32-bit BIT(port) macro is passed
      as argument to the ocelot_ifh_set_dest function and warns:
      
      ocelot_xmit() warn: should '(((1))) << (dp->index)' be a 64 bit type?
      seville_xmit() warn: should '(((1))) << (dp->index)' be a 64 bit type?
      
      The destination port mask is copied into a 12-bit field of the packet,
      starting at bit offset 67 and ending at 56.
      
      So this DSA tagging protocol supports at most 12 bits, which is clearly
      less than 32. Attempting to send to a port number > 12 will cause the
      packing() call to truncate way before there will be 32-bit truncation
      due to type promotion of the BIT(port) argument towards u64.
      
      Therefore, smatch's fears that BIT(port) will do the wrong thing and
      cause unexpected truncation for "port" values >= 32 are unfounded.
      Nonetheless, let's silence the warning by explicitly passing an u64
      value to ocelot_ifh_set_dest, such that the compiler does not need to do
      a questionable type promotion.
      Reported-by: Nkernel test robot <lkp@intel.com>
      Reported-by: NDan Carpenter <dan.carpenter@oracle.com>
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      1f778d50
  12. 15 2月, 2021 4 次提交
    • V
      net: dsa: tag_ocelot_8021q: add support for PTP timestamping · 0a6f17c6
      Vladimir Oltean 提交于
      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: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      0a6f17c6
    • V
      net: mscc: ocelot: refactor ocelot_xtr_irq_handler into ocelot_xtr_poll · 924ee317
      Vladimir Oltean 提交于
      Since the felix DSA driver will need to poll the CPU port module for
      extracted frames as well, let's create some common functions that read
      an Extraction Frame Header, and then an skb, from a CPU extraction
      group.
      
      We abuse the struct ocelot_ops :: port_to_netdev function a little bit,
      in order to retrieve the DSA port net_device or the ocelot switchdev
      net_device based on the source port information from the Extraction
      Frame Header, but it's all in the benefit of code simplification -
      netdev_alloc_skb needs it. Originally, the port_to_netdev method was
      intended for parsing act->dev from tc flower offload code.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      924ee317
    • V
      net: mscc: ocelot: use common tag parsing code with DSA · 40d3f295
      Vladimir Oltean 提交于
      The Injection Frame Header and Extraction Frame Header that the switch
      prepends to frames over the NPI port is also prepended to frames
      delivered over the CPU port module's queues.
      
      Let's unify the handling of the frame headers by making the ocelot
      driver call some helpers exported by the DSA tagger. Among other things,
      this allows us to get rid of the strange cpu_to_be32 when transmitting
      the Injection Frame Header on ocelot, since the packing API uses
      network byte order natively (when "quirks" is 0).
      
      The comments above ocelot_gen_ifh talk about setting pop_cnt to 3, and
      the cpu extraction queue mask to something, but the code doesn't do it,
      so we don't do it either.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      40d3f295
    • V
      net: mscc: ocelot: refactor ocelot_port_inject_frame out of ocelot_port_xmit · 137ffbc4
      Vladimir Oltean 提交于
      The felix DSA driver will inject some frames through register MMIO, same
      as ocelot switchdev currently does. So we need to be able to reuse the
      common code.
      
      Also create some shim definitions, since the DSA tagger can be compiled
      without support for the switch driver.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      137ffbc4
  13. 13 2月, 2021 2 次提交
  14. 10 2月, 2021 1 次提交
    • V
      net: dsa: felix: implement port flushing on .phylink_mac_link_down · eb4733d7
      Vladimir Oltean 提交于
      There are several issues which may be seen when the link goes down while
      forwarding traffic, all of which can be attributed to the fact that the
      port flushing procedure from the reference manual was not closely
      followed.
      
      With flow control enabled on both the ingress port and the egress port,
      it may happen when a link goes down that Ethernet packets are in flight.
      In flow control mode, frames are held back and not dropped. When there
      is enough traffic in flight (example: iperf3 TCP), then the ingress port
      might enter congestion and never exit that state. This is a problem,
      because it is the egress port's link that went down, and that has caused
      the inability of the ingress port to send packets to any other port.
      This is solved by flushing the egress port's queues when it goes down.
      
      There is also a problem when performing stream splitting for
      IEEE 802.1CB traffic (not yet upstream, but a sort of multicast,
      basically). There, if one port from the destination ports mask goes
      down, splitting the stream towards the other destinations will no longer
      be performed. This can be traced down to this line:
      
      	ocelot_port_writel(ocelot_port, 0, DEV_MAC_ENA_CFG);
      
      which should have been instead, as per the reference manual:
      
      	ocelot_port_rmwl(ocelot_port, 0, DEV_MAC_ENA_CFG_RX_ENA,
      			 DEV_MAC_ENA_CFG);
      
      Basically only DEV_MAC_ENA_CFG_RX_ENA should be disabled, but not
      DEV_MAC_ENA_CFG_TX_ENA - I don't have further insight into why that is
      the case, but apparently multicasting to several ports will cause issues
      if at least one of them doesn't have DEV_MAC_ENA_CFG_TX_ENA set.
      
      I am not sure what the state of the Ocelot VSC7514 driver is, but
      probably not as bad as Felix/Seville, since VSC7514 uses phylib and has
      the following in ocelot_adjust_link:
      
      	if (!phydev->link)
      		return;
      
      therefore the port is not really put down when the link is lost, unlike
      the DSA drivers which use .phylink_mac_link_down for that.
      
      Nonetheless, I put ocelot_port_flush() in the common ocelot.c because it
      needs to access some registers from drivers/net/ethernet/mscc/ocelot_rew.h
      which are not exported in include/soc/mscc/ and a bugfix patch should
      probably not move headers around.
      
      Fixes: bdeced75 ("net: dsa: felix: Add PCS operations for PHYLINK")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      eb4733d7
  15. 07 2月, 2021 8 次提交
  16. 30 1月, 2021 3 次提交
    • V
      net: dsa: felix: perform switch setup for tag_8021q · e21268ef
      Vladimir Oltean 提交于
      Unlike sja1105, the only other user of the software-defined tag_8021q.c
      tagger format, the implementation we choose for the Felix DSA switch
      driver preserves full functionality under a vlan_filtering bridge
      (i.e. IP termination works through the DSA user ports under all
      circumstances).
      
      The tag_8021q protocol just wants:
      - Identifying the ingress switch port based on the RX VLAN ID, as seen
        by the CPU. We achieve this by using the TCAM engines (which are also
        used for tc-flower offload) to push the RX VLAN as a second, outer
        tag, on egress towards the CPU port.
      - Steering traffic injected into the switch from the network stack
        towards the correct front port based on the TX VLAN, and consuming
        (popping) that header on the switch's egress.
      
      A tc-flower pseudocode of the static configuration done by the driver
      would look like this:
      
      $ tc qdisc add dev <cpu-port> clsact
      $ for eth in swp0 swp1 swp2 swp3; do \
      	tc filter add dev <cpu-port> egress flower indev ${eth} \
      		action vlan push id <rxvlan> protocol 802.1ad; \
      	tc filter add dev <cpu-port> ingress protocol 802.1Q flower
      		vlan_id <txvlan> action vlan pop \
      		action mirred egress redirect dev ${eth}; \
      done
      
      but of course since DSA does not register network interfaces for the CPU
      port, this configuration would be impossible for the user to do. Also,
      due to the same reason, it is impossible for the user to inadvertently
      delete these rules using tc. These rules do not collide in any way with
      tc-flower, they just consume some TCAM space, which is something we can
      live with.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      e21268ef
    • V
      net: mscc: ocelot: don't use NPI tag prefix for the CPU port module · cacea62f
      Vladimir Oltean 提交于
      Context: Ocelot switches put the injection/extraction frame header in
      front of the Ethernet header. When used in NPI mode, a DSA master would
      see junk instead of the destination MAC address, and it would most
      likely drop the packets. So the Ocelot frame header can have an optional
      prefix, which is just "ff:ff:ff:ff:ff:fe > ff:ff:ff:ff:ff:ff" padding
      put before the actual tag (still before the real Ethernet header) such
      that the DSA master thinks it's looking at a broadcast frame with a
      strange EtherType.
      
      Unfortunately, a lesson learned in commit 69df578c ("net: mscc:
      ocelot: eliminate confusion between CPU and NPI port") seems to have
      been forgotten in the meanwhile.
      
      The CPU port module and the NPI port have independent settings for the
      length of the tag prefix. However, the driver is using the same variable
      to program both of them.
      
      There is no reason really to use any tag prefix with the CPU port
      module, since that is not connected to any Ethernet port. So this patch
      makes the inj_prefix and xtr_prefix variables apply only to the NPI
      port (which the switchdev ocelot_vsc7514 driver does not use).
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      cacea62f
    • V
      net: mscc: ocelot: reapply bridge forwarding mask on bonding join/leave · 9b521250
      Vladimir Oltean 提交于
      Applying the bridge forwarding mask currently is done only on the STP
      state changes for any port. But it depends on both STP state changes,
      and bonding interface state changes. Export the bit that recalculates
      the forwarding mask so that it could be reused, and call it when a port
      starts and stops offloading a bonding interface.
      
      Now that the logic is split into a separate function, we can rename "p"
      into "port", since the "port" variable was already taken in
      ocelot_bridge_stp_state_set. Also, we can rename "i" into "lag", to make
      it more clear what is it that we're iterating through.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NAlexandre Belloni <alexandre.belloni@bootlin.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      9b521250
  17. 21 1月, 2021 1 次提交
    • A
      net: mscc: ocelot: Fix multicast to the CPU port · 584b7cfc
      Alban Bedel 提交于
      Multicast entries in the MAC table use the high bits of the MAC
      address to encode the ports that should get the packets. But this port
      mask does not work for the CPU port, to receive these packets on the
      CPU port the MAC_CPU_COPY flag must be set.
      
      Because of this IPv6 was effectively not working because neighbor
      solicitations were never received. This was not apparent before commit
      9403c158 (net: mscc: ocelot: support IPv4, IPv6 and plain Ethernet mdb
      entries) as the IPv6 entries were broken so all incoming IPv6
      multicast was then treated as unknown and flooded on all ports.
      
      To fix this problem rework the ocelot_mact_learn() to set the
      MAC_CPU_COPY flag when a multicast entry that target the CPU port is
      added. For this we have to read back the ports endcoded in the pseudo
      MAC address by the caller. It is not a very nice design but that avoid
      changing the callers and should make backporting easier.
      Signed-off-by: NAlban Bedel <alban.bedel@aerq.com>
      Fixes: 9403c158 ("net: mscc: ocelot: support IPv4, IPv6 and plain Ethernet mdb entries")
      Link: https://lore.kernel.org/r/20210119140638.203374-1-alban.bedel@aerq.comSigned-off-by: NJakub Kicinski <kuba@kernel.org>
      584b7cfc
  18. 16 1月, 2021 3 次提交
    • V
      net: mscc: ocelot: configure watermarks using devlink-sb · f59fd9ca
      Vladimir Oltean 提交于
      Using devlink-sb, we can configure 12/16 (the important 75%) of the
      switch's controlling watermarks for congestion drops, and we can monitor
      50% of the watermark occupancies (we can monitor the reservation
      watermarks, but not the sharing watermarks, which are exposed as pool
      sizes).
      
      The following definitions can be made:
      
      SB_BUF=0 # The devlink-sb for frame buffers
      SB_REF=1 # The devlink-sb for frame references
      POOL_ING=0 # The pool for ingress traffic. Both devlink-sb instances
                 # have one of these.
      POOL_EGR=1 # The pool for egress traffic. Both devlink-sb instances
                 # have one of these.
      
      Editing the hardware watermarks is done in the following way:
      BUF_xxxx_I is accessed when sb=$SB_BUF and pool=$POOL_ING
      REF_xxxx_I is accessed when sb=$SB_REF and pool=$POOL_ING
      BUF_xxxx_E is accessed when sb=$SB_BUF and pool=$POOL_EGR
      REF_xxxx_E is accessed when sb=$SB_REF and pool=$POOL_EGR
      
      Configuring the sharing watermarks for COL_SHR(dp=0) is done implicitly
      by modifying the corresponding pool size. By default, the pool size has
      maximum size, so this can be skipped.
      
      devlink sb pool set pci/0000:00:00.5 sb $SB_BUF pool $POOL_ING \
      	size 129840 thtype static
      
      Since by default there is no buffer reservation, the above command has
      maxed out BUF_COL_SHR_I(dp=0).
      
      Configuring the per-port reservation watermark (P_RSRV) is done in the
      following way:
      
      devlink sb port pool set pci/0000:00:00.5/0 sb $SB_BUF \
      	pool $POOL_ING th 1000
      
      The above command sets BUF_P_RSRV_I(port 0) to 1000 bytes. After this
      command, the sharing watermarks are internally reconfigured with 1000
      bytes less, i.e. from 129840 bytes to 128840 bytes.
      
      Configuring the per-port-tc reservation watermarks (Q_RSRV) is done in
      the following way:
      
      for tc in {0..7}; do
      	devlink sb tc bind set pci/0000:00:00.5/0 sb 0 tc $tc \
      		type ingress pool $POOL_ING \
      		th 3000
      done
      
      The above command sets BUF_Q_RSRV_I(port 0, tc 0..7) to 3000 bytes.
      The sharing watermarks are again reconfigured with 24000 bytes less.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      f59fd9ca
    • V
      net: mscc: ocelot: initialize watermarks to sane defaults · a4ae997a
      Vladimir Oltean 提交于
      This is meant to be a gentle introduction into the world of watermarks
      on ocelot. The code is placed in ocelot_devlink.c because it will be
      integrated with devlink, even if it isn't right now.
      
      My first step was intended to be to replicate the default configuration
      of the congestion watermarks programatically, since they are now going
      to be tuned by the user.
      
      But after studying and understanding through trial and error how they
      work, I now believe that the configuration used out of reset does not do
      justice to the word "reservation", since the sum of all reservations
      exceeds the total amount of resources (otherwise said, all reservations
      cannot be fulfilled at the same time, which means that, contrary to the
      reference manual, they don't guarantee anything).
      
      As an example, here's a dump of the reservation watermarks for frame
      buffers, for port 0 (for brevity, the ports 1-6 were omitted, but they
      have the same configuration):
      
      BUF_Q_RSRV_I(port 0, prio 0) = max 3000 bytes
      BUF_Q_RSRV_I(port 0, prio 1) = max 3000 bytes
      BUF_Q_RSRV_I(port 0, prio 2) = max 3000 bytes
      BUF_Q_RSRV_I(port 0, prio 3) = max 3000 bytes
      BUF_Q_RSRV_I(port 0, prio 4) = max 3000 bytes
      BUF_Q_RSRV_I(port 0, prio 5) = max 3000 bytes
      BUF_Q_RSRV_I(port 0, prio 6) = max 3000 bytes
      BUF_Q_RSRV_I(port 0, prio 7) = max 3000 bytes
      
      Otherwise said, every port-tc has an ingress reservation of 3000 bytes,
      and there are 7 ports in VSC9959 Felix (6 user ports and 1 CPU port).
      Concentrating only on the ingress reservations, there are, in total,
      8 [traffic classes] x 7 [ports] x 3000 [bytes] = 168,000 bytes of memory
      reserved on ingress.
      But, surprise, Felix only has 128 KB of packet buffer in total...
      A similar thing happens with Seville, which has a larger packet buffer,
      but also more ports, and the default configuration is also overcommitted.
      
      This patch disables the (apparently) bogus reservations and moves all
      resources to the shared area. This way, real reservations can be set up
      by the user, using devlink-sb.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      a4ae997a
    • V
      net: mscc: ocelot: auto-detect packet buffer size and number of frame references · f6fe01d6
      Vladimir Oltean 提交于
      Instead of reading these values from the reference manual and writing
      them down into the driver, it appears that the hardware gives us the
      option of detecting them dynamically.
      
      The number of frame references corresponds to what the reference manual
      notes, however it seems that the frame buffers are reported as slightly
      less than the books would indicate. On VSC9959 (Felix), the books say it
      should have 128KB of packet buffer, but the registers indicate only
      129840 bytes (126.79 KB). Also, the unit of measurement for FREECNT from
      the documentation of all these devices is incorrect (taken from an older
      generation). This was confirmed by Younes Leroul from Microchip support.
      
      Not having anything better to do with these values at the moment* (this
      will change soon), let's just print them.
      
      *The frame buffer size is, in fact, used to calculate the tail dropping
      watermarks.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      f6fe01d6
  19. 12 1月, 2021 1 次提交
    • V
      net: switchdev: remove the transaction structure from port attributes · bae33f2b
      Vladimir Oltean 提交于
      Since the introduction of the switchdev API, port attributes were
      transmitted to drivers for offloading using a two-step transactional
      model, with a prepare phase that was supposed to catch all errors, and a
      commit phase that was supposed to never fail.
      
      Some classes of failures can never be avoided, like hardware access, or
      memory allocation. In the latter case, merely attempting to move the
      memory allocation to the preparation phase makes it impossible to avoid
      memory leaks, since commit 91cf8ece ("switchdev: Remove unused
      transaction item queue") which has removed the unused mechanism of
      passing on the allocated memory between one phase and another.
      
      It is time we admit that separating the preparation from the commit
      phase is something that is best left for the driver to decide, and not
      something that should be baked into the API, especially since there are
      no switchdev callers that depend on this.
      
      This patch removes the struct switchdev_trans member from switchdev port
      attribute notifier structures, and converts drivers to not look at this
      member.
      
      In part, this patch contains a revert of my previous commit 2e554a7a
      ("net: dsa: propagate switchdev vlan_filtering prepare phase to
      drivers").
      
      For the most part, the conversion was trivial except for:
      - Rocker's world implementation based on Broadcom OF-DPA had an odd
        implementation of ofdpa_port_attr_bridge_flags_set. The conversion was
        done mechanically, by pasting the implementation twice, then only
        keeping the code that would get executed during prepare phase on top,
        then only keeping the code that gets executed during the commit phase
        on bottom, then simplifying the resulting code until this was obtained.
      - DSA's offloading of STP state, bridge flags, VLAN filtering and
        multicast router could be converted right away. But the ageing time
        could not, so a shim was introduced and this was left for a further
        commit.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Acked-by: NLinus Walleij <linus.walleij@linaro.org>
      Acked-by: NJiri Pirko <jiri@nvidia.com>
      Reviewed-by: Kurt Kanzenbach <kurt@linutronix.de> # hellcreek
      Reviewed-by: Linus Walleij <linus.walleij@linaro.org> # RTL8366RB
      Reviewed-by: NIdo Schimmel <idosch@nvidia.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      bae33f2b
  20. 15 12月, 2020 1 次提交