1. 04 8月, 2021 1 次提交
  2. 30 7月, 2021 3 次提交
    • I
      dpaa2-switch: offload shared block mirror filters when binding to a port · 7a91f907
      Ioana Ciornei 提交于
      When mirroring rules are added in shared filter blocks, the same
      mirroring rule has to be configured on all the switch ports that are
      part of the same block.
      
      In case a switch port joins a shared block after mirroring filters have
      been already added to it, then all the mirror rules should be offloaded
      to the port. The reverse, removal of mirroring rules, has to be done at
      block unbind.
      
      For this purpose, the dpaa2_switch_block_offload_mirror() and
      dpaa2_switch_block_unoffload_mirror() functions are added and called
      upon binding and unbinding a switch port to/from a block.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      7a91f907
    • I
      dpaa2-switch: add support for port mirroring · e0ead825
      Ioana Ciornei 提交于
      Add support for per port mirroring for the DPAA2 switch. We support
      only single mirror port, therefore we allow mirroring rules only as long
      as the destination port is always the same.
      
      Unlike all the actions (drop, redirect, trap) already supported by the
      dpaa2-switch driver, adding mirroring filters in shared blocks is not
      achieved by a singular ACL entry added in a table shared by the ports.
      This is why, when a new mirror filter is added in a block we have to got
      through all the switch ports sharing it and configure the filter
      individually on all.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      e0ead825
    • I
      dpaa2-switch: rename dpaa2_switch_acl_tbl into filter_block · adcb7aa3
      Ioana Ciornei 提交于
      Until now, shared filter blocks were implemented only by ACL tables
      shared between ports. Going forward, when the mirroring support will be
      added, this will not be true anymore.
      
      Rename the dpaa2_switch_acl_tbl into dpaa2_switch_filter_block so that
      we make it clear that the structure is used not only for filters that
      use the ACL table but will be used for all the filters that are added in
      a block.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      adcb7aa3
  3. 23 7月, 2021 1 次提交
    • T
      net: bridge: switchdev: allow the TX data plane forwarding to be offloaded · 47211192
      Tobias Waldekranz 提交于
      Allow switchdevs to forward frames from the CPU in accordance with the
      bridge configuration in the same way as is done between bridge
      ports. This means that the bridge will only send a single skb towards
      one of the ports under the switchdev's control, and expects the driver
      to deliver the packet to all eligible ports in its domain.
      
      Primarily this improves the performance of multicast flows with
      multiple subscribers, as it allows the hardware to perform the frame
      replication.
      
      The basic flow between the driver and the bridge is as follows:
      
      - When joining a bridge port, the switchdev driver calls
        switchdev_bridge_port_offload() with tx_fwd_offload = true.
      
      - The bridge sends offloadable skbs to one of the ports under the
        switchdev's control using skb->offload_fwd_mark = true.
      
      - The switchdev driver checks the skb->offload_fwd_mark field and lets
        its FDB lookup select the destination port mask for this packet.
      
      v1->v2:
      - convert br_input_skb_cb::fwd_hwdoms to a plain unsigned long
      - introduce a static key "br_switchdev_fwd_offload_used" to minimize the
        impact of the newly introduced feature on all the setups which don't
        have hardware that can make use of it
      - introduce a check for nbp->flags & BR_FWD_OFFLOAD to optimize cache
        line access
      - reorder nbp_switchdev_frame_mark_accel() and br_handle_vlan() in
        __br_forward()
      - do not strip VLAN on egress if forwarding offload on VLAN-aware bridge
        is being used
      - propagate errors from .ndo_dfwd_add_station() if not EOPNOTSUPP
      
      v2->v3:
      - replace the solution based on .ndo_dfwd_add_station with a solution
        based on switchdev_bridge_port_offload
      - rename BR_FWD_OFFLOAD to BR_TX_FWD_OFFLOAD
      v3->v4: rebase
      v4->v5:
      - make sure the static key is decremented on bridge port unoffload
      - more function and variable renaming and comments for them:
        br_switchdev_fwd_offload_used to br_switchdev_tx_fwd_offload
        br_switchdev_accels_skb to br_switchdev_frame_uses_tx_fwd_offload
        nbp_switchdev_frame_mark_tx_fwd to nbp_switchdev_frame_mark_tx_fwd_to_hwdom
        nbp_switchdev_frame_mark_accel to nbp_switchdev_frame_mark_tx_fwd_offload
        fwd_accel to tx_fwd_offload
      Signed-off-by: NTobias Waldekranz <tobias@waldekranz.com>
      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>
      47211192
  4. 22 7月, 2021 5 次提交
    • I
      dpaa2-switch: seed the buffer pool after allocating the swp · 7aaa0f31
      Ioana Ciornei 提交于
      Any interraction with the buffer pool (seeding a buffer, acquire one) is
      made through a software portal (SWP, a DPIO object).
      There are circumstances where the dpaa2-switch driver probes on a DPSW
      before any DPIO devices have been probed. In this case, seeding of the
      buffer pool will lead to a panic since no SWPs are initialized.
      
      To fix this, seed the buffer pool after making sure that the software
      portals have been probed and are ready to be used.
      
      Fixes: 0b1b7137 ("staging: dpaa2-switch: handle Rx path on control interface")
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      7aaa0f31
    • V
      net: bridge: move the switchdev object replay helpers to "push" mode · 4e51bf44
      Vladimir Oltean 提交于
      Starting with commit 4f2673b3 ("net: bridge: add helper to replay
      port and host-joined mdb entries"), DSA has introduced some bridge
      helpers that replay switchdev events (FDB/MDB/VLAN additions and
      deletions) that can be lost by the switchdev drivers in a variety of
      circumstances:
      
      - an IP multicast group was host-joined on the bridge itself before any
        switchdev port joined the bridge, leading to the host MDB entries
        missing in the hardware database.
      - during the bridge creation process, the MAC address of the bridge was
        added to the FDB as an entry pointing towards the bridge device
        itself, but with no switchdev ports being part of the bridge yet, this
        local FDB entry would remain unknown to the switchdev hardware
        database.
      - a VLAN/FDB/MDB was added to a bridge port that is a LAG interface,
        before any switchdev port joined that LAG, leading to the hardware
        database missing those entries.
      - a switchdev port left a LAG that is a bridge port, while the LAG
        remained part of the bridge, and all FDB/MDB/VLAN entries remained
        installed in the hardware database of the switchdev port.
      
      Also, since commit 0d2cfbd4 ("net: bridge: ignore switchdev events
      for LAG ports which didn't request replay"), DSA introduced a method,
      based on a const void *ctx, to ensure that two switchdev ports under the
      same LAG that is a bridge port do not see the same MDB/VLAN entry being
      replayed twice by the bridge, once for every bridge port that joins the
      LAG.
      
      With so many ordering corner cases being possible, it seems unreasonable
      to expect a switchdev driver writer to get it right from the first try.
      Therefore, now that DSA has experimented with the bridge replay helpers
      for a little bit, we can move the code to the bridge driver where it is
      more readily available to all switchdev drivers.
      
      To convert the switchdev object replay helpers from "pull mode" (where
      the driver asks for them) to a "push mode" (where the bridge offers them
      automatically), the biggest problem is that the bridge needs to be aware
      when a switchdev port joins and leaves, even when the switchdev is only
      indirectly a bridge port (for example when the bridge port is a LAG
      upper of the switchdev).
      
      Luckily, we already have a hook for that, in the form of the newly
      introduced switchdev_bridge_port_offload() and
      switchdev_bridge_port_unoffload() calls. These offer a natural place for
      hooking the object addition and deletion replays.
      
      Extend the above 2 functions with:
      - pointers to the switchdev atomic notifier (for FDB replays) and the
        blocking notifier (for MDB and VLAN replays).
      - the "const void *ctx" argument required for drivers to be able to
        disambiguate between which port is targeted, when multiple ports are
        lowers of the same LAG that is a bridge port. Most of the drivers pass
        NULL to this argument, except the ones that support LAG offload and have
        the proper context check already in place in the switchdev blocking
        notifier handler.
      
      Also unexport the replay helpers, since nobody except the bridge calls
      them directly now.
      
      Note that:
      (a) we abuse the terminology slightly, because FDB entries are not
          "switchdev objects", but we count them as objects nonetheless.
          With no direct way to prove it, I think they are not modeled as
          switchdev objects because those can only be installed by the bridge
          to the hardware (as opposed to FDB entries which can be propagated
          in the other direction too). This is merely an abuse of terms, FDB
          entries are replayed too, despite not being objects.
      (b) the bridge does not attempt to sync port attributes to newly joined
          ports, just the countable stuff (the objects). The reason for this
          is simple: no universal and symmetric way to sync and unsync them is
          known. For example, VLAN filtering: what to do on unsync, disable or
          leave it enabled? Similarly, STP state, ageing timer, etc etc. What
          a switchdev port does when it becomes standalone again is not really
          up to the bridge's competence, and the driver should deal with it.
          On the other hand, replaying deletions of switchdev objects can be
          seen a matter of cleanup and therefore be treated by the bridge,
          hence this patch.
      
      We make the replay helpers opt-in for drivers, because they might not
      bring immediate benefits for them:
      
      - nbp_vlan_init() is called _after_ netdev_master_upper_dev_link(),
        so br_vlan_replay() should not do anything for the new drivers on
        which we call it. The existing drivers where there was even a slight
        possibility for there to exist a VLAN on a bridge port before they
        join it are already guarded against this: mlxsw and prestera deny
        joining LAG interfaces that are members of a bridge.
      
      - br_fdb_replay() should now notify of local FDB entries, but I patched
        all drivers except DSA to ignore these new entries in commit
        2c4eca3e ("net: bridge: switchdev: include local flag in FDB
        notifications"). Driver authors can lift this restriction as they
        wish, and when they do, they can also opt into the FDB replay
        functionality.
      
      - br_mdb_replay() should fix a real issue which is described in commit
        4f2673b3 ("net: bridge: add helper to replay port and host-joined
        mdb entries"). However most drivers do not offload the
        SWITCHDEV_OBJ_ID_HOST_MDB to see this issue: only cpsw and am65_cpsw
        offload this switchdev object, and I don't completely understand the
        way in which they offload this switchdev object anyway. So I'll leave
        it up to these drivers' respective maintainers to opt into
        br_mdb_replay().
      
      So most of the drivers pass NULL notifier blocks for the replay helpers,
      except:
      - dpaa2-switch which was already acked/regression-tested with the
        helpers enabled (and there isn't much of a downside in having them)
      - ocelot which already had replay logic in "pull" mode
      - DSA which already had replay logic in "pull" mode
      
      An important observation is that the drivers which don't currently
      request bridge event replays don't even have the
      switchdev_bridge_port_{offload,unoffload} calls placed in proper places
      right now. This was done to avoid unnecessary rework for drivers which
      might never even add support for this. For driver writers who wish to
      add replay support, this can be used as a tentative placement guide:
      https://patchwork.kernel.org/project/netdevbpf/patch/20210720134655.892334-11-vladimir.oltean@nxp.com/
      
      Cc: Vadym Kochan <vkochan@marvell.com>
      Cc: Taras Chornyi <tchornyi@marvell.com>
      Cc: Ioana Ciornei <ioana.ciornei@nxp.com>
      Cc: Lars Povlsen <lars.povlsen@microchip.com>
      Cc: Steen Hegelund <Steen.Hegelund@microchip.com>
      Cc: UNGLinuxDriver@microchip.com
      Cc: Claudiu Manoil <claudiu.manoil@nxp.com>
      Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
      Cc: Grygorii Strashko <grygorii.strashko@ti.com>
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Acked-by: Ioana Ciornei <ioana.ciornei@nxp.com> # dpaa2-switch
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4e51bf44
    • V
      net: bridge: switchdev: let drivers inform which bridge ports are offloaded · 2f5dc00f
      Vladimir Oltean 提交于
      On reception of an skb, the bridge checks if it was marked as 'already
      forwarded in hardware' (checks if skb->offload_fwd_mark == 1), and if it
      is, it assigns the source hardware domain of that skb based on the
      hardware domain of the ingress port. Then during forwarding, it enforces
      that the egress port must have a different hardware domain than the
      ingress one (this is done in nbp_switchdev_allowed_egress).
      
      Non-switchdev drivers don't report any physical switch id (neither
      through devlink nor .ndo_get_port_parent_id), therefore the bridge
      assigns them a hardware domain of 0, and packets coming from them will
      always have skb->offload_fwd_mark = 0. So there aren't any restrictions.
      
      Problems appear due to the fact that DSA would like to perform software
      fallback for bonding and team interfaces that the physical switch cannot
      offload.
      
             +-- br0 ---+
            / /   |      \
           / /    |       \
          /  |    |      bond0
         /   |    |     /    \
       swp0 swp1 swp2 swp3 swp4
      
      There, it is desirable that the presence of swp3 and swp4 under a
      non-offloaded LAG does not preclude us from doing hardware bridging
      beteen swp0, swp1 and swp2. The bandwidth of the CPU is often times high
      enough that software bridging between {swp0,swp1,swp2} and bond0 is not
      impractical.
      
      But this creates an impossible paradox given the current way in which
      port hardware domains are assigned. When the driver receives a packet
      from swp0 (say, due to flooding), it must set skb->offload_fwd_mark to
      something.
      
      - If we set it to 0, then the bridge will forward it towards swp1, swp2
        and bond0. But the switch has already forwarded it towards swp1 and
        swp2 (not to bond0, remember, that isn't offloaded, so as far as the
        switch is concerned, ports swp3 and swp4 are not looking up the FDB,
        and the entire bond0 is a destination that is strictly behind the
        CPU). But we don't want duplicated traffic towards swp1 and swp2, so
        it's not ok to set skb->offload_fwd_mark = 0.
      
      - If we set it to 1, then the bridge will not forward the skb towards
        the ports with the same switchdev mark, i.e. not to swp1, swp2 and
        bond0. Towards swp1 and swp2 that's ok, but towards bond0? It should
        have forwarded the skb there.
      
      So the real issue is that bond0 will be assigned the same hardware
      domain as {swp0,swp1,swp2}, because the function that assigns hardware
      domains to bridge ports, nbp_switchdev_add(), recurses through bond0's
      lower interfaces until it finds something that implements devlink (calls
      dev_get_port_parent_id with bool recurse = true). This is a problem
      because the fact that bond0 can be offloaded by swp3 and swp4 in our
      example is merely an assumption.
      
      A solution is to give the bridge explicit hints as to what hardware
      domain it should use for each port.
      
      Currently, the bridging offload is very 'silent': a driver registers a
      netdevice notifier, which is put on the netns's notifier chain, and
      which sniffs around for NETDEV_CHANGEUPPER events where the upper is a
      bridge, and the lower is an interface it knows about (one registered by
      this driver, normally). Then, from within that notifier, it does a bunch
      of stuff behind the bridge's back, without the bridge necessarily
      knowing that there's somebody offloading that port. It looks like this:
      
           ip link set swp0 master br0
                        |
                        v
       br_add_if() calls netdev_master_upper_dev_link()
                        |
                        v
              call_netdevice_notifiers
                        |
                        v
             dsa_slave_netdevice_event
                        |
                        v
              oh, hey! it's for me!
                        |
                        v
                 .port_bridge_join
      
      What we do to solve the conundrum is to be less silent, and change the
      switchdev drivers to present themselves to the bridge. Something like this:
      
           ip link set swp0 master br0
                        |
                        v
       br_add_if() calls netdev_master_upper_dev_link()
                        |
                        v                    bridge: Aye! I'll use this
              call_netdevice_notifiers           ^  ppid as the
                        |                        |  hardware domain for
                        v                        |  this port, and zero
             dsa_slave_netdevice_event           |  if I got nothing.
                        |                        |
                        v                        |
              oh, hey! it's for me!              |
                        |                        |
                        v                        |
                 .port_bridge_join               |
                        |                        |
                        +------------------------+
                   switchdev_bridge_port_offload(swp0, swp0)
      
      Then stacked interfaces (like bond0 on top of swp3/swp4) would be
      treated differently in DSA, depending on whether we can or cannot
      offload them.
      
      The offload case:
      
          ip link set bond0 master br0
                        |
                        v
       br_add_if() calls netdev_master_upper_dev_link()
                        |
                        v                    bridge: Aye! I'll use this
              call_netdevice_notifiers           ^  ppid as the
                        |                        |  switchdev mark for
                        v                        |        bond0.
             dsa_slave_netdevice_event           | Coincidentally (or not),
                        |                        | bond0 and swp0, swp1, swp2
                        v                        | all have the same switchdev
              hmm, it's not quite for me,        | mark now, since the ASIC
               but my driver has already         | is able to forward towards
                 called .port_lag_join           | all these ports in hw.
                for it, because I have           |
            a port with dp->lag_dev == bond0.    |
                        |                        |
                        v                        |
                 .port_bridge_join               |
                 for swp3 and swp4               |
                        |                        |
                        +------------------------+
                  switchdev_bridge_port_offload(bond0, swp3)
                  switchdev_bridge_port_offload(bond0, swp4)
      
      And the non-offload case:
      
          ip link set bond0 master br0
                        |
                        v
       br_add_if() calls netdev_master_upper_dev_link()
                        |
                        v                    bridge waiting:
              call_netdevice_notifiers           ^  huh, switchdev_bridge_port_offload
                        |                        |  wasn't called, okay, I'll use a
                        v                        |  hwdom of zero for this one.
             dsa_slave_netdevice_event           :  Then packets received on swp0 will
                        |                        :  not be software-forwarded towards
                        v                        :  swp1, but they will towards bond0.
               it's not for me, but
             bond0 is an upper of swp3
            and swp4, but their dp->lag_dev
             is NULL because they couldn't
                  offload it.
      
      Basically we can draw the conclusion that the lowers of a bridge port
      can come and go, so depending on the configuration of lowers for a
      bridge port, it can dynamically toggle between offloaded and unoffloaded.
      Therefore, we need an equivalent switchdev_bridge_port_unoffload too.
      
      This patch changes the way any switchdev driver interacts with the
      bridge. From now on, everybody needs to call switchdev_bridge_port_offload
      and switchdev_bridge_port_unoffload, otherwise the bridge will treat the
      port as non-offloaded and allow software flooding to other ports from
      the same ASIC.
      
      Note that these functions lay the ground for a more complex handshake
      between switchdev drivers and the bridge in the future.
      
      For drivers that will request a replay of the switchdev objects when
      they offload and unoffload a bridge port (DSA, dpaa2-switch, ocelot), we
      place the call to switchdev_bridge_port_unoffload() strategically inside
      the NETDEV_PRECHANGEUPPER notifier's code path, and not inside
      NETDEV_CHANGEUPPER. This is because the switchdev object replay helpers
      need the netdev adjacency lists to be valid, and that is only true in
      NETDEV_PRECHANGEUPPER.
      
      Cc: Vadym Kochan <vkochan@marvell.com>
      Cc: Taras Chornyi <tchornyi@marvell.com>
      Cc: Ioana Ciornei <ioana.ciornei@nxp.com>
      Cc: Lars Povlsen <lars.povlsen@microchip.com>
      Cc: Steen Hegelund <Steen.Hegelund@microchip.com>
      Cc: UNGLinuxDriver@microchip.com
      Cc: Claudiu Manoil <claudiu.manoil@nxp.com>
      Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
      Cc: Grygorii Strashko <grygorii.strashko@ti.com>
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com> # dpaa2-switch: regression
      Acked-by: Ioana Ciornei <ioana.ciornei@nxp.com> # dpaa2-switch
      Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com> # ocelot-switch
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2f5dc00f
    • V
      net: dpaa2-switch: refactor prechangeupper sanity checks · 45035feb
      Vladimir Oltean 提交于
      Make more room for some extra code in the NETDEV_PRECHANGEUPPER handler
      by moving what already exists into a dedicated function.
      
      Cc: Ioana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Acked-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      45035feb
    • V
      net: dpaa2-switch: use extack in dpaa2_switch_port_bridge_join · 123338d7
      Vladimir Oltean 提交于
      We need to propagate the extack argument for
      dpaa2_switch_port_bridge_join to use it in a future patch, and it looks
      like there is already an error message there which is currently printed
      to the console. Move it over netlink so it is properly transmitted to
      user space.
      
      Cc: Ioana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Tested-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Acked-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      123338d7
  5. 29 6月, 2021 1 次提交
    • V
      net: switchdev: add a context void pointer to struct switchdev_notifier_info · 69bfac96
      Vladimir Oltean 提交于
      In the case where the driver asks for a replay of a certain type of
      event (port object or attribute) for a bridge port that is a LAG, it may
      do so because this port has just joined the LAG.
      
      But there might already be other switchdev ports in that LAG, and it is
      preferable that those preexisting switchdev ports do not act upon the
      replayed event.
      
      The solution is to add a context to switchdev events, which is NULL most
      of the time (when the bridge layer initiates the call) but which can be
      set to a value controlled by the switchdev driver when a replay is
      requested. The driver can then check the context to figure out if all
      ports within the LAG should act upon the switchdev event, or just the
      ones that match the context.
      
      We have to modify all switchdev_handle_* helper functions as well as the
      prototypes in the drivers that use these helpers too, because these
      helpers hide the underlying struct switchdev_notifier_info from us and
      there is no way to retrieve the context otherwise.
      
      The context structure will be populated and used in later patches.
      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>
      69bfac96
  6. 17 4月, 2021 1 次提交
  7. 14 4月, 2021 5 次提交
  8. 31 3月, 2021 5 次提交
  9. 23 3月, 2021 6 次提交
  10. 11 3月, 2021 12 次提交
    • I
      staging: dpaa2-switch: move the driver out of staging · f48298d3
      Ioana Ciornei 提交于
      Now that the dpaa2-switch driver has basic I/O capabilities on the
      switch port net_devices and multiple bridging domains are supported,
      move the driver out of staging.
      
      The dpaa2-switch driver is placed right next to the dpaa2-eth driver
      since, in the near future, they will be sharing most of the data path.
      I didn't implement code reuse in this patch series because I wanted to
      keep it as small as possible.
      
      Also, the README is removed from staging with the intention to add
      proper rst documentation afterwards to actually match was is supported
      by the driver.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      f48298d3
    • I
      staging: dpaa2-switch: prevent joining a bridge while VLAN uppers are present · 1c4928fc
      Ioana Ciornei 提交于
      Each time a switch port joins a bridge, it will start to use a FDB table
      common with all the other switch ports that are under the same bridge.
      This means that any VLAN added prior to a bridge join, will retain its
      previous FDB table destination. With this patch, I choose to restrict
      when a switch port can change it's upper device (either join or leave)
      so that the driver does not have to delete all the previously installed
      VLANs from the previous FDB and add them into the new one.
      
      Thus, in the PRECHANGEUPPER  notification we check if there are any VLAN
      type upper devices and if that's true, deny the CHANGEUPPER.
      
      This way, the user is not restricted in the topology but rather in the
      order in which the setup is done: it must first create the bridging
      domain layout and after that add the necessary VLAN devices if
      necessary. The teardown is similar, the VLAN devices will need to be
      destroyed prior to a change in the bridging layout.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      1c4928fc
    • I
      staging: dpaa2-switch: add fast-ageing on bridge leave · 685b4801
      Ioana Ciornei 提交于
      Upon leaving a bridge, any MAC addresses learnt on the switch port prior
      to this point have to be removed so that we preserve the bridging domain
      configuration.
      
      Restructure the dpaa2_switch_port_fdb_dump() function in order to have a
      common dpaa2_switch_fdb_iterate() function between the FDB dump callback
      and the fast age procedure. To accomplish this, add a new callback -
      dpaa2_switch_fdb_cb_t - which will be called on each MAC addr and,
      depending on the situation, will either dump the FDB entry into a
      netlink message or will delete the address from the FDB table, in case
      of the fast-age.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      685b4801
    • I
      staging: dpaa2-switch: accept only vlan-aware upper devices · d671407f
      Ioana Ciornei 提交于
      The DPAA2 Switch is not capable to handle traffic in a VLAN unaware
      fashion, thus the previous handling of both the accepted upper devices
      and the SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING flag was wrong.
      
      Fix this by checking if the bridge that we are joining is indeed VLAN
      aware, if not return an error. Also, the RX VLAN filtering feature is
      defined as 'on [fixed]' and the .ndo_vlan_rx_add_vid() and
      .ndo_vlan_rx_kill_vid() callbacks are implemented just by recreating a
      switchdev_obj_port_vlan object and then calling the same functions used
      on the switchdev notifier path.
      In addition, changing the vlan_filtering flag to 0 on a bridge under
      which a DPAA2 switch interface is present is not supported, thus
      rejected when SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING is received with
      such a request.
      
      This patch is also adding the use of the switchdev_handle_port_attr_set
      function so that we can iterate through all the lower devices of the
      bridge that the notification was received on and actually catch if the
      user is trying to change the vlan_filtering state. Since on a VLAN
      filtering change the net_device is the bridge, we also move the
      dpaa2_switch_port_dev_check call so that we do not return NOTIFY_DONE
      right away.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Reviewed-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      d671407f
    • I
      staging: dpaa2-switch: move the notifier register to module_init() · 16abb6ad
      Ioana Ciornei 提交于
      Move the notifier blocks register into the module_init() step, instead of
      object probe, so that all DPSW devices probed by the dpaa2-switch driver
      can use the same notifiers.
      
      This will enable us to have a more straightforward approach in
      determining if an event is intended for an object managed by this driver
      or not. Previously, the dpaa2_switch_port_dev_check() function was
      forced to also check the notifier block beside the net_device_ops
      structure to determine if the event is for us or not.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      16abb6ad
    • I
      staging: dpaa2-switch: properly setup switching domains · 539dda3c
      Ioana Ciornei 提交于
      Until now, the DPAA2 switch was not capable to properly setup its
      switching domains depending on the existence, or lack thereof, of a
      upper bridge device. This meant that all switch ports of a DPSW object
      were switching by default even though they were not under the same
      bridge device.
      
      Another issue was the inability to actually add the CPU in the flooding
      domains (broadcast, unknown unicast etc) of a particular switch port.
      This meant that a simple ping on a switch interface was not possible
      since no broadcast ARP frame would actually reach the CPU queues.
      
      This patch tries to fix exactly these problems by:
      
      * Creating and managing a FDB table for each flooding domain. This means
        that when a switch interface is not bridged it will use its own FDB
        table. While in bridged mode all DPAA2 switch interfaces under the
        same upper will use the same FDB table, thus leverage the same FDB
        entries.
      
      * Adding a new MC firmware command - dpsw_set_egress_flood() - through
        which the driver can setup the flooding domains as needed. For
        example, when the switch interface is standalone, thus not in a
        bridge with any other DPAA2 switch port, it will setup its broadcast
        and unknown unicast flooding domains to only include the control
        interface (the queues that reach the CPU and the driver can dequeue
        from). This flooding domain changes when the interface joins a bridge
        and is configured to include, beside the control interface, all other
        DPAA2 switch interfaces.
      
      We impose a minimum limit of FDB tables available equal to the number of
      switch interfaces so that we guarantee that, in the maximal
      configuration - all interfaces are standalone, each switch port will
      have a private FDB table. At the same time, we only probe DPSW objects
      that have the flooding and broadcast replicators configured to be per
      FDB (DPSW_*_PER_FDB). Without this, the dpaa2-switch driver would not
      be able to configure multiple switching domains.
      
      At probe time, a FDB table will be allocated for each port. At a bridge
      join event, the switch port will either continue to use the current FDB
      table (if it's the first dpaa2-switch port to join that bridge) or will
      switch to use the FDB table associated with the port that it's already
      under the bridge. If a FDB switch is necessary, the private FDB table
      which was previously used will be returned to the pool of unused FDBs.
      
      Upon a bridge leave, the switch port needs a private FDB table thus it
      will search and get the first unused FDB table. This way, all the other
      ports remaining under the bridge will continue to use the same FDB
      table.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Reviewed-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      539dda3c
    • I
      staging: dpaa2-switch: enable the control interface · 613c0a58
      Ioana Ciornei 提交于
      Enable the CTRL_IF of the switch object, now that all the pieces are in
      place (buffer and queue management, interrupts, NAPI instances etc).
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Reviewed-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      613c0a58
    • I
      staging: dpaa2-switch: add .ndo_start_xmit() callback · 7fd94d86
      Ioana Ciornei 提交于
      Implement the .ndo_start_xmit() callback for the switch port interfaces.
      For each of the switch ports, gather the corresponding queue
      destination ID (QDID) necessary for Tx enqueueing.
      
      We'll reserve 64 bytes for software annotations, where we keep a skb
      backpointer used on the Tx confirmation side for releasing the allocated
      memory. At the moment, we only support linear skbs.
      
      Also, add support for the Tx confirmation path which for the most part
      shares the code path with the normal Rx queue.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      7fd94d86
    • I
      staging: dpaa2-switch: handle Rx path on control interface · 0b1b7137
      Ioana Ciornei 提交于
      The dpaa2-ethsw supports only one Rx queue that is shared by all switch
      ports. This means that information about which port was the ingress port
      for a specific frame needs to be passed in metadata. In our case, the
      Flow Context (FLC) field from the frame descriptor holds this
      information. Besides the interface ID of the ingress port we also
      receive the virtual QDID of the port. Below is a visual description of
      the 64 bits of FLC.
      
      63           47           31           15           0
      +---------------------------------------------------+
      |            |            |            |            |
      |  RESERVED  |    IF_ID   |  RESERVED  |  IF QDID   |
      |            |            |            |            |
      +---------------------------------------------------+
      
      Because all switch ports share the same Rx and Tx conf queues, NAPI
      management takes into consideration when there is at least one switch
      interface open to enable the NAPI instance.
      
      The Rx path is common, for the most part, for both Rx and Tx conf with
      the mention that each of them has its own consume function of a frame
      descriptor. Dequeueing from a FQ, consuming dequeued store and also the
      NAPI poll function is common between both queues.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Reviewed-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      0b1b7137
    • I
      staging: dpaa2-switch: setup dpio · 04abc97d
      Ioana Ciornei 提交于
      Setup interrupts on the control interface queues. We do not force an
      exact affinity between the interrupts received from a specific queue and
      a cpu.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Reviewed-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      04abc97d
    • I
      staging: dpaa2-switch: setup buffer pool and RX path rings · 2877e4f7
      Ioana Ciornei 提交于
      Allocate and setup a buffer pool, needed on the Rx path of the control
      interface. Also, define the Rx buffer size seen by the WRIOP from the
      PAGE_SIZE buffers seeded.
      
      Also, create the needed Rx rings for both frame queues used on the
      control interface.  On the Rx path, when a pull-dequeue operation is
      performed on a software portal, available frame descriptors are put in a
      ring - a DMA memory storage - for further usage.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Reviewed-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2877e4f7
    • I
      staging: dpaa2-switch: get control interface attributes · 26d419f3
      Ioana Ciornei 提交于
      Introduce a new structure to hold all necessary info related to an RX
      queue for the control interface and populate the FQ IDs.
      We only have one Rx queue and one Tx confirmation queue on the control
      interface, both shared by all the switch ports.
      
      Also, increase the minimum version of the object supported by the driver
      since for a basic switch driver support we'll be in need for some ABIs
      added in the latest version of firmware.
      Signed-off-by: NIoana Ciornei <ioana.ciornei@nxp.com>
      Reviewed-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      26d419f3