bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
        dev_err(ds->dev, "Unsupported interface '%s' for port %d\n",
                phy_modes(state->interface), port);
 -      return;
  }
  
+ static void gswip_port_set_link(struct gswip_priv *priv, int port, bool link)
+ {
+       u32 mdio_phy;
+ 
+       if (link)
+               mdio_phy = GSWIP_MDIO_PHY_LINK_UP;
+       else
+               mdio_phy = GSWIP_MDIO_PHY_LINK_DOWN;
+ 
+       gswip_mdio_mask(priv, GSWIP_MDIO_PHY_LINK_MASK, mdio_phy,
+                       GSWIP_MDIO_PHYp(port));
+ }
+ 
+ static void gswip_port_set_speed(struct gswip_priv *priv, int port, int speed,
+                                phy_interface_t interface)
+ {
+       u32 mdio_phy = 0, mii_cfg = 0, mac_ctrl_0 = 0;
+ 
+       switch (speed) {
+       case SPEED_10:
+               mdio_phy = GSWIP_MDIO_PHY_SPEED_M10;
+ 
+               if (interface == PHY_INTERFACE_MODE_RMII)
+                       mii_cfg = GSWIP_MII_CFG_RATE_M50;
+               else
+                       mii_cfg = GSWIP_MII_CFG_RATE_M2P5;
+ 
+               mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_MII;
+               break;
+ 
+       case SPEED_100:
+               mdio_phy = GSWIP_MDIO_PHY_SPEED_M100;
+ 
+               if (interface == PHY_INTERFACE_MODE_RMII)
+                       mii_cfg = GSWIP_MII_CFG_RATE_M50;
+               else
+                       mii_cfg = GSWIP_MII_CFG_RATE_M25;
+ 
+               mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_MII;
+               break;
+ 
+       case SPEED_1000:
+               mdio_phy = GSWIP_MDIO_PHY_SPEED_G1;
+ 
+               mii_cfg = GSWIP_MII_CFG_RATE_M125;
+ 
+               mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_RGMII;
+               break;
+       }
+ 
+       gswip_mdio_mask(priv, GSWIP_MDIO_PHY_SPEED_MASK, mdio_phy,
+                       GSWIP_MDIO_PHYp(port));
+       gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_RATE_MASK, mii_cfg, port);
+       gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_GMII_MASK, mac_ctrl_0,
+                         GSWIP_MAC_CTRL_0p(port));
+ }
+ 
+ static void gswip_port_set_duplex(struct gswip_priv *priv, int port, int duplex)
+ {
+       u32 mac_ctrl_0, mdio_phy;
+ 
+       if (duplex == DUPLEX_FULL) {
+               mac_ctrl_0 = GSWIP_MAC_CTRL_0_FDUP_EN;
+               mdio_phy = GSWIP_MDIO_PHY_FDUP_EN;
+       } else {
+               mac_ctrl_0 = GSWIP_MAC_CTRL_0_FDUP_DIS;
+               mdio_phy = GSWIP_MDIO_PHY_FDUP_DIS;
+       }
+ 
+       gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_FDUP_MASK, mac_ctrl_0,
+                         GSWIP_MAC_CTRL_0p(port));
+       gswip_mdio_mask(priv, GSWIP_MDIO_PHY_FDUP_MASK, mdio_phy,
+                       GSWIP_MDIO_PHYp(port));
+ }
+ 
+ static void gswip_port_set_pause(struct gswip_priv *priv, int port,
+                                bool tx_pause, bool rx_pause)
+ {
+       u32 mac_ctrl_0, mdio_phy;
+ 
+       if (tx_pause && rx_pause) {
+               mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_RXTX;
+               mdio_phy = GSWIP_MDIO_PHY_FCONTX_EN |
+                          GSWIP_MDIO_PHY_FCONRX_EN;
+       } else if (tx_pause) {
+               mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_TX;
+               mdio_phy = GSWIP_MDIO_PHY_FCONTX_EN |
+                          GSWIP_MDIO_PHY_FCONRX_DIS;
+       } else if (rx_pause) {
+               mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_RX;
+               mdio_phy = GSWIP_MDIO_PHY_FCONTX_DIS |
+                          GSWIP_MDIO_PHY_FCONRX_EN;
+       } else {
+               mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_NONE;
+               mdio_phy = GSWIP_MDIO_PHY_FCONTX_DIS |
+                          GSWIP_MDIO_PHY_FCONRX_DIS;
+       }
+ 
+       gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_FCON_MASK,
+                         mac_ctrl_0, GSWIP_MAC_CTRL_0p(port));
+       gswip_mdio_mask(priv,
+                       GSWIP_MDIO_PHY_FCONTX_MASK |
+                       GSWIP_MDIO_PHY_FCONRX_MASK,
+                       mdio_phy, GSWIP_MDIO_PHYp(port));
+ }
+ 
  static void gswip_phylink_mac_config(struct dsa_switch *ds, int port,
                                     unsigned int mode,
                                     const struct phylink_link_state *state)
 
        int err;
  
        sq->channel   = c;
 -      sq->uar_map   = mdev->mlx5e_res.bfreg.map;
 +      sq->uar_map   = mdev->mlx5e_res.hw_objs.bfreg.map;
+       sq->reserved_room = param->stop_room;
  
        param->wq.db_numa_node = cpu_to_node(c->cpu);
        err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, wq, &sq->wq_ctrl);
 
        int err = 0;
  
        if (!mlx5_eswitch_termtbl_required(esw, attr, flow_act, spec) &&
-           MLX5_CAP_GEN(esw_attr->in_mdev, reg_c_preserve) &&
-           mlx5_eswitch_vport_match_metadata_enabled(esw) &&
-           MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, ignore_flow_level))
+           esw_src_port_rewrite_supported(esw))
                attr->flags |= MLX5_ESW_ATTR_FLAG_SRC_REWRITE;
  
 -      if (attr->dest_ft) {
 +      if (attr->flags & MLX5_ESW_ATTR_FLAG_SAMPLE) {
 +              esw_setup_sampler_dest(dest, flow_act, esw_attr, *i);
 +              (*i)++;
 +      } else if (attr->dest_ft) {
                esw_setup_ft_dest(dest, flow_act, esw, attr, spec, *i);
                (*i)++;
        } else if (attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) {
 
  struct bpf_local_storage_map;
  struct kobject;
  struct mem_cgroup;
+ struct module;
 +struct bpf_func_state;
  
  extern struct idr btf_idr;
  extern spinlock_t btf_idr_lock;
 
   */
  void ethtool_set_ethtool_phy_ops(const struct ethtool_phy_ops *ops);
  
 -/*
++/**
+  * ethtool_params_from_link_mode - Derive link parameters from a given link mode
+  * @link_ksettings: Link parameters to be derived from the link mode
+  * @link_mode: Link mode
+  */
+ void
+ ethtool_params_from_link_mode(struct ethtool_link_ksettings *link_ksettings,
+                             enum ethtool_link_mode_bit_indices link_mode);
++
 +/**
 + * ethtool_sprintf - Write formatted string to ethtool string data
 + * @data: Pointer to start of string to update
 + * @fmt: Format of string to write
 + *
 + * Write formatted string to data. Update data to point at start of
 + * next string.
 + */
 +extern __printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...);
  #endif /* _LINUX_ETHTOOL_H */
 
  static inline void sk_psock_restore_proto(struct sock *sk,
                                          struct sk_psock *psock)
  {
-       sk->sk_prot->unhash = psock->saved_unhash;
 -      if (inet_csk_has_ulp(sk)) {
 -              /* TLS does not have an unhash proto in SW cases, but we need
 -               * to ensure we stop using the sock_map unhash routine because
 -               * the associated psock is being removed. So use the original
 -               * unhash handler.
 -               */
 -              WRITE_ONCE(sk->sk_prot->unhash, psock->saved_unhash);
 -              tcp_update_ulp(sk, psock->sk_proto, psock->saved_write_space);
 -      } else {
 -              sk->sk_write_space = psock->saved_write_space;
 -              /* Pairs with lockless read in sk_clone_lock() */
 -              WRITE_ONCE(sk->sk_prot, psock->sk_proto);
 -      }
 +      if (psock->psock_update_sk_prot)
 +              psock->psock_update_sk_prot(sk, true);
  }
  
  static inline void sk_psock_set_state(struct sk_psock *psock,
 
        int ret = __SK_PASS;
  
        rcu_read_lock();
 -      prog = READ_ONCE(psock->progs.skb_verdict);
 +      prog = READ_ONCE(psock->progs.stream_verdict);
        if (likely(prog)) {
-               /* We skip full set_owner_r here because if we do a SK_PASS
-                * or SK_DROP we can skip skb memory accounting and use the
-                * TLS context.
-                */
                skb->sk = psock->sk;
 -              tcp_skb_bpf_redirect_clear(skb);
 -              ret = sk_psock_bpf_run(psock, prog, skb);
 -              ret = sk_psock_map_verd(ret, tcp_skb_bpf_redirect_fetch(skb));
 +              skb_dst_drop(skb);
 +              skb_bpf_redirect_clear(skb);
 +              ret = bpf_prog_run_pin_on_cpu(prog, skb);
 +              ret = sk_psock_map_verd(ret, skb_bpf_redirect_fetch(skb));
                skb->sk = NULL;
        }
        sk_psock_tls_verdict_apply(skb, psock->sk, ret);
                kfree_skb(skb);
                goto out;
        }
-       skb_set_owner_r(skb, sk);
 -      prog = READ_ONCE(psock->progs.skb_verdict);
 +      prog = READ_ONCE(psock->progs.stream_verdict);
        if (likely(prog)) {
 -              tcp_skb_bpf_redirect_clear(skb);
 -              ret = sk_psock_bpf_run(psock, prog, skb);
 -              ret = sk_psock_map_verd(ret, tcp_skb_bpf_redirect_fetch(skb));
+               skb->sk = sk;
 +              skb_dst_drop(skb);
 +              skb_bpf_redirect_clear(skb);
 +              ret = bpf_prog_run_pin_on_cpu(prog, skb);
 +              ret = sk_psock_map_verd(ret, skb_bpf_redirect_fetch(skb));
+               skb->sk = NULL;
        }
        sk_psock_verdict_apply(psock, skb, ret);
  out:
                kfree_skb(skb);
                goto out;
        }
-       skb_set_owner_r(skb, sk);
 -      prog = READ_ONCE(psock->progs.skb_verdict);
 +      prog = READ_ONCE(psock->progs.stream_verdict);
 +      if (!prog)
 +              prog = READ_ONCE(psock->progs.skb_verdict);
        if (likely(prog)) {
 -              tcp_skb_bpf_redirect_clear(skb);
 -              ret = sk_psock_bpf_run(psock, prog, skb);
 -              ret = sk_psock_map_verd(ret, tcp_skb_bpf_redirect_fetch(skb));
+               skb->sk = sk;
 +              skb_dst_drop(skb);
 +              skb_bpf_redirect_clear(skb);
 +              ret = bpf_prog_run_pin_on_cpu(prog, skb);
 +              ret = sk_psock_map_verd(ret, skb_bpf_redirect_fetch(skb));
+               skb->sk = NULL;
        }
        sk_psock_verdict_apply(psock, skb, ret);
  out:
 
        int family = sk->sk_family == AF_INET6 ? TCP_BPF_IPV6 : TCP_BPF_IPV4;
        int config = psock->progs.msg_parser   ? TCP_BPF_TX   : TCP_BPF_BASE;
  
 +      if (restore) {
 +              if (inet_csk_has_ulp(sk)) {
++                      /* TLS does not have an unhash proto in SW cases,
++                       * but we need to ensure we stop using the sock_map
++                       * unhash routine because the associated psock is being
++                       * removed. So use the original unhash handler.
++                       */
++                      WRITE_ONCE(sk->sk_prot->unhash, psock->saved_unhash);
 +                      tcp_update_ulp(sk, psock->sk_proto, psock->saved_write_space);
 +              } else {
 +                      sk->sk_write_space = psock->saved_write_space;
 +                      /* Pairs with lockless read in sk_clone_lock() */
 +                      WRITE_ONCE(sk->sk_prot, psock->sk_proto);
 +              }
 +              return 0;
 +      }
 +
 +      if (inet_csk_has_ulp(sk))
 +              return -EINVAL;
 +
        if (sk->sk_family == AF_INET6) {
                if (tcp_bpf_assert_proto_ops(psock->sk_proto))
 -                      return ERR_PTR(-EINVAL);
 +                      return -EINVAL;
  
                tcp_bpf_check_v6_needs_rebuild(psock->sk_proto);
        }
 
                }
        }
        xsk->ctx = ctx;
 +      xsk->ctx->has_bpf_link = xsk_probe_bpf_link();
  
-       if (rx) {
+       if (rx && !rx_setup_done) {
                err = setsockopt(xsk->fd, SOL_XDP, XDP_RX_RING,
                                 &xsk->config.rx_size,
                                 sizeof(xsk->config.rx_size));