Merge tag 'mlx5-fixes-2021-06-09' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux
Saeed Mahameed says: ==================== mlx5-fixes-2021-06-09 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -64,6 +64,8 @@ struct devlink_port *mlx5e_get_devlink_port(struct net_device *dev)
|
|||||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||||
struct devlink_port *port;
|
struct devlink_port *port;
|
||||||
|
|
||||||
|
if (!netif_device_present(dev))
|
||||||
|
return NULL;
|
||||||
port = mlx5e_devlink_get_dl_port(priv);
|
port = mlx5e_devlink_get_dl_port(priv);
|
||||||
if (port->registered)
|
if (port->registered)
|
||||||
return port;
|
return port;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||||
// Copyright (c) 2020 Mellanox Technologies
|
// Copyright (c) 2020 Mellanox Technologies
|
||||||
|
|
||||||
#include <linux/ptp_classify.h>
|
|
||||||
#include "en/ptp.h"
|
#include "en/ptp.h"
|
||||||
#include "en/txrx.h"
|
#include "en/txrx.h"
|
||||||
#include "en/params.h"
|
#include "en/params.h"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "en.h"
|
#include "en.h"
|
||||||
#include "en_stats.h"
|
#include "en_stats.h"
|
||||||
|
#include <linux/ptp_classify.h>
|
||||||
|
|
||||||
struct mlx5e_ptpsq {
|
struct mlx5e_ptpsq {
|
||||||
struct mlx5e_txqsq txqsq;
|
struct mlx5e_txqsq txqsq;
|
||||||
@@ -43,6 +44,27 @@ struct mlx5e_ptp {
|
|||||||
DECLARE_BITMAP(state, MLX5E_PTP_STATE_NUM_STATES);
|
DECLARE_BITMAP(state, MLX5E_PTP_STATE_NUM_STATES);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline bool mlx5e_use_ptpsq(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct flow_keys fk;
|
||||||
|
|
||||||
|
if (!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (fk.basic.n_proto == htons(ETH_P_1588))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (fk.basic.n_proto != htons(ETH_P_IP) &&
|
||||||
|
fk.basic.n_proto != htons(ETH_P_IPV6))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (fk.basic.ip_proto == IPPROTO_UDP &&
|
||||||
|
fk.ports.dst == htons(PTP_EV_PORT));
|
||||||
|
}
|
||||||
|
|
||||||
int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
|
int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
|
||||||
u8 lag_port, struct mlx5e_ptp **cp);
|
u8 lag_port, struct mlx5e_ptp **cp);
|
||||||
void mlx5e_ptp_close(struct mlx5e_ptp *c);
|
void mlx5e_ptp_close(struct mlx5e_ptp *c);
|
||||||
|
|||||||
@@ -129,10 +129,9 @@ static void mlx5e_rep_neigh_update(struct work_struct *work)
|
|||||||
work);
|
work);
|
||||||
struct mlx5e_neigh_hash_entry *nhe = update_work->nhe;
|
struct mlx5e_neigh_hash_entry *nhe = update_work->nhe;
|
||||||
struct neighbour *n = update_work->n;
|
struct neighbour *n = update_work->n;
|
||||||
|
struct mlx5e_encap_entry *e = NULL;
|
||||||
bool neigh_connected, same_dev;
|
bool neigh_connected, same_dev;
|
||||||
struct mlx5e_encap_entry *e;
|
|
||||||
unsigned char ha[ETH_ALEN];
|
unsigned char ha[ETH_ALEN];
|
||||||
struct mlx5e_priv *priv;
|
|
||||||
u8 nud_state, dead;
|
u8 nud_state, dead;
|
||||||
|
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
@@ -156,14 +155,12 @@ static void mlx5e_rep_neigh_update(struct work_struct *work)
|
|||||||
if (!same_dev)
|
if (!same_dev)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
list_for_each_entry(e, &nhe->encap_list, encap_list) {
|
/* mlx5e_get_next_init_encap() releases previous encap before returning
|
||||||
if (!mlx5e_encap_take(e))
|
* the next one.
|
||||||
continue;
|
*/
|
||||||
|
while ((e = mlx5e_get_next_init_encap(nhe, e)) != NULL)
|
||||||
|
mlx5e_rep_update_flows(netdev_priv(e->out_dev), e, neigh_connected, ha);
|
||||||
|
|
||||||
priv = netdev_priv(e->out_dev);
|
|
||||||
mlx5e_rep_update_flows(priv, e, neigh_connected, ha);
|
|
||||||
mlx5e_encap_put(priv, e);
|
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
mlx5e_release_neigh_update_work(update_work);
|
mlx5e_release_neigh_update_work(update_work);
|
||||||
|
|||||||
@@ -94,13 +94,9 @@ void mlx5e_rep_update_flows(struct mlx5e_priv *priv,
|
|||||||
|
|
||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
/* wait for encap to be fully initialized */
|
|
||||||
wait_for_completion(&e->res_ready);
|
|
||||||
|
|
||||||
mutex_lock(&esw->offloads.encap_tbl_lock);
|
mutex_lock(&esw->offloads.encap_tbl_lock);
|
||||||
encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID);
|
encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID);
|
||||||
if (e->compl_result < 0 || (encap_connected == neigh_connected &&
|
if (encap_connected == neigh_connected && ether_addr_equal(e->h_dest, ha))
|
||||||
ether_addr_equal(e->h_dest, ha)))
|
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
mlx5e_take_all_encap_flows(e, &flow_list);
|
mlx5e_take_all_encap_flows(e, &flow_list);
|
||||||
|
|||||||
@@ -251,9 +251,12 @@ static void mlx5e_take_all_route_decap_flows(struct mlx5e_route_entry *r,
|
|||||||
mlx5e_take_tmp_flow(flow, flow_list, 0);
|
mlx5e_take_tmp_flow(flow, flow_list, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef bool (match_cb)(struct mlx5e_encap_entry *);
|
||||||
|
|
||||||
static struct mlx5e_encap_entry *
|
static struct mlx5e_encap_entry *
|
||||||
mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe,
|
mlx5e_get_next_matching_encap(struct mlx5e_neigh_hash_entry *nhe,
|
||||||
struct mlx5e_encap_entry *e)
|
struct mlx5e_encap_entry *e,
|
||||||
|
match_cb match)
|
||||||
{
|
{
|
||||||
struct mlx5e_encap_entry *next = NULL;
|
struct mlx5e_encap_entry *next = NULL;
|
||||||
|
|
||||||
@@ -288,7 +291,7 @@ retry:
|
|||||||
/* wait for encap to be fully initialized */
|
/* wait for encap to be fully initialized */
|
||||||
wait_for_completion(&next->res_ready);
|
wait_for_completion(&next->res_ready);
|
||||||
/* continue searching if encap entry is not in valid state after completion */
|
/* continue searching if encap entry is not in valid state after completion */
|
||||||
if (!(next->flags & MLX5_ENCAP_ENTRY_VALID)) {
|
if (!match(next)) {
|
||||||
e = next;
|
e = next;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
@@ -296,6 +299,30 @@ retry:
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool mlx5e_encap_valid(struct mlx5e_encap_entry *e)
|
||||||
|
{
|
||||||
|
return e->flags & MLX5_ENCAP_ENTRY_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mlx5e_encap_entry *
|
||||||
|
mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe,
|
||||||
|
struct mlx5e_encap_entry *e)
|
||||||
|
{
|
||||||
|
return mlx5e_get_next_matching_encap(nhe, e, mlx5e_encap_valid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mlx5e_encap_initialized(struct mlx5e_encap_entry *e)
|
||||||
|
{
|
||||||
|
return e->compl_result >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mlx5e_encap_entry *
|
||||||
|
mlx5e_get_next_init_encap(struct mlx5e_neigh_hash_entry *nhe,
|
||||||
|
struct mlx5e_encap_entry *e)
|
||||||
|
{
|
||||||
|
return mlx5e_get_next_matching_encap(nhe, e, mlx5e_encap_initialized);
|
||||||
|
}
|
||||||
|
|
||||||
void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe)
|
void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe)
|
||||||
{
|
{
|
||||||
struct mlx5e_neigh *m_neigh = &nhe->m_neigh;
|
struct mlx5e_neigh *m_neigh = &nhe->m_neigh;
|
||||||
|
|||||||
@@ -532,9 +532,6 @@ void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv)
|
|||||||
struct mlx5_core_dev *mdev = priv->mdev;
|
struct mlx5_core_dev *mdev = priv->mdev;
|
||||||
struct net_device *netdev = priv->netdev;
|
struct net_device *netdev = priv->netdev;
|
||||||
|
|
||||||
if (!priv->ipsec)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!(mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_CAP_ESP) ||
|
if (!(mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_CAP_ESP) ||
|
||||||
!MLX5_CAP_ETH(mdev, swp)) {
|
!MLX5_CAP_ETH(mdev, swp)) {
|
||||||
mlx5_core_dbg(mdev, "mlx5e: ESP and SWP offload not supported\n");
|
mlx5_core_dbg(mdev, "mlx5e: ESP and SWP offload not supported\n");
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ err:
|
|||||||
|
|
||||||
int mlx5e_arfs_create_tables(struct mlx5e_priv *priv)
|
int mlx5e_arfs_create_tables(struct mlx5e_priv *priv)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = -ENOMEM;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!(priv->netdev->hw_features & NETIF_F_NTUPLE))
|
if (!(priv->netdev->hw_features & NETIF_F_NTUPLE))
|
||||||
|
|||||||
@@ -2705,8 +2705,6 @@ static int mlx5e_update_netdev_queues(struct mlx5e_priv *priv)
|
|||||||
nch = priv->channels.params.num_channels;
|
nch = priv->channels.params.num_channels;
|
||||||
ntc = priv->channels.params.num_tc;
|
ntc = priv->channels.params.num_tc;
|
||||||
num_rxqs = nch * priv->profile->rq_groups;
|
num_rxqs = nch * priv->profile->rq_groups;
|
||||||
if (priv->channels.params.ptp_rx)
|
|
||||||
num_rxqs++;
|
|
||||||
|
|
||||||
mlx5e_netdev_set_tcs(netdev, nch, ntc);
|
mlx5e_netdev_set_tcs(netdev, nch, ntc);
|
||||||
|
|
||||||
@@ -4824,22 +4822,15 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev)) {
|
if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev)) {
|
||||||
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
|
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||||
netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
|
netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
|
||||||
netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
|
||||||
netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL |
|
|
||||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_GRE)) {
|
if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_GRE)) {
|
||||||
netdev->hw_features |= NETIF_F_GSO_GRE |
|
netdev->hw_features |= NETIF_F_GSO_GRE;
|
||||||
NETIF_F_GSO_GRE_CSUM;
|
netdev->hw_enc_features |= NETIF_F_GSO_GRE;
|
||||||
netdev->hw_enc_features |= NETIF_F_GSO_GRE |
|
netdev->gso_partial_features |= NETIF_F_GSO_GRE;
|
||||||
NETIF_F_GSO_GRE_CSUM;
|
|
||||||
netdev->gso_partial_features |= NETIF_F_GSO_GRE |
|
|
||||||
NETIF_F_GSO_GRE_CSUM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_IPIP)) {
|
if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_IPIP)) {
|
||||||
|
|||||||
@@ -4765,7 +4765,7 @@ static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv,
|
|||||||
list_for_each_entry_safe(hpe, tmp, &init_wait_list, dead_peer_wait_list) {
|
list_for_each_entry_safe(hpe, tmp, &init_wait_list, dead_peer_wait_list) {
|
||||||
wait_for_completion(&hpe->res_ready);
|
wait_for_completion(&hpe->res_ready);
|
||||||
if (!IS_ERR_OR_NULL(hpe->hp) && hpe->peer_vhca_id == peer_vhca_id)
|
if (!IS_ERR_OR_NULL(hpe->hp) && hpe->peer_vhca_id == peer_vhca_id)
|
||||||
hpe->hp->pair->peer_gone = true;
|
mlx5_core_hairpin_clear_dead_peer(hpe->hp->pair);
|
||||||
|
|
||||||
mlx5e_hairpin_put(priv, hpe);
|
mlx5e_hairpin_put(priv, hpe);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,6 +178,9 @@ void mlx5e_take_all_encap_flows(struct mlx5e_encap_entry *e, struct list_head *f
|
|||||||
void mlx5e_put_flow_list(struct mlx5e_priv *priv, struct list_head *flow_list);
|
void mlx5e_put_flow_list(struct mlx5e_priv *priv, struct list_head *flow_list);
|
||||||
|
|
||||||
struct mlx5e_neigh_hash_entry;
|
struct mlx5e_neigh_hash_entry;
|
||||||
|
struct mlx5e_encap_entry *
|
||||||
|
mlx5e_get_next_init_encap(struct mlx5e_neigh_hash_entry *nhe,
|
||||||
|
struct mlx5e_encap_entry *e);
|
||||||
void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe);
|
void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe);
|
||||||
|
|
||||||
void mlx5e_tc_reoffload_flows_work(struct work_struct *work);
|
void mlx5e_tc_reoffload_flows_work(struct work_struct *work);
|
||||||
|
|||||||
@@ -32,7 +32,6 @@
|
|||||||
|
|
||||||
#include <linux/tcp.h>
|
#include <linux/tcp.h>
|
||||||
#include <linux/if_vlan.h>
|
#include <linux/if_vlan.h>
|
||||||
#include <linux/ptp_classify.h>
|
|
||||||
#include <net/geneve.h>
|
#include <net/geneve.h>
|
||||||
#include <net/dsfield.h>
|
#include <net/dsfield.h>
|
||||||
#include "en.h"
|
#include "en.h"
|
||||||
@@ -67,24 +66,6 @@ static inline int mlx5e_get_dscp_up(struct mlx5e_priv *priv, struct sk_buff *skb
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool mlx5e_use_ptpsq(struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
struct flow_keys fk;
|
|
||||||
|
|
||||||
if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (fk.basic.n_proto == htons(ETH_P_1588))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (fk.basic.n_proto != htons(ETH_P_IP) &&
|
|
||||||
fk.basic.n_proto != htons(ETH_P_IPV6))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return (fk.basic.ip_proto == IPPROTO_UDP &&
|
|
||||||
fk.ports.dst == htons(PTP_EV_PORT));
|
|
||||||
}
|
|
||||||
|
|
||||||
static u16 mlx5e_select_ptpsq(struct net_device *dev, struct sk_buff *skb)
|
static u16 mlx5e_select_ptpsq(struct net_device *dev, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||||
@@ -145,9 +126,9 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ptp_channel = READ_ONCE(priv->channels.ptp);
|
ptp_channel = READ_ONCE(priv->channels.ptp);
|
||||||
if (unlikely(ptp_channel) &&
|
if (unlikely(ptp_channel &&
|
||||||
test_bit(MLX5E_PTP_STATE_TX, ptp_channel->state) &&
|
test_bit(MLX5E_PTP_STATE_TX, ptp_channel->state) &&
|
||||||
mlx5e_use_ptpsq(skb))
|
mlx5e_use_ptpsq(skb)))
|
||||||
return mlx5e_select_ptpsq(dev, skb);
|
return mlx5e_select_ptpsq(dev, skb);
|
||||||
|
|
||||||
txq_ix = netdev_pick_tx(dev, skb, NULL);
|
txq_ix = netdev_pick_tx(dev, skb, NULL);
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ static int mlx5_eq_comp_int(struct notifier_block *nb,
|
|||||||
|
|
||||||
eqe = next_eqe_sw(eq);
|
eqe = next_eqe_sw(eq);
|
||||||
if (!eqe)
|
if (!eqe)
|
||||||
return 0;
|
goto out;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
struct mlx5_core_cq *cq;
|
struct mlx5_core_cq *cq;
|
||||||
@@ -161,6 +161,8 @@ static int mlx5_eq_comp_int(struct notifier_block *nb,
|
|||||||
++eq->cons_index;
|
++eq->cons_index;
|
||||||
|
|
||||||
} while ((++num_eqes < MLX5_EQ_POLLING_BUDGET) && (eqe = next_eqe_sw(eq)));
|
} while ((++num_eqes < MLX5_EQ_POLLING_BUDGET) && (eqe = next_eqe_sw(eq)));
|
||||||
|
|
||||||
|
out:
|
||||||
eq_update_ci(eq, 1);
|
eq_update_ci(eq, 1);
|
||||||
|
|
||||||
if (cqn != -1)
|
if (cqn != -1)
|
||||||
@@ -248,9 +250,9 @@ static int mlx5_eq_async_int(struct notifier_block *nb,
|
|||||||
++eq->cons_index;
|
++eq->cons_index;
|
||||||
|
|
||||||
} while ((++num_eqes < MLX5_EQ_POLLING_BUDGET) && (eqe = next_eqe_sw(eq)));
|
} while ((++num_eqes < MLX5_EQ_POLLING_BUDGET) && (eqe = next_eqe_sw(eq)));
|
||||||
eq_update_ci(eq, 1);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
eq_update_ci(eq, 1);
|
||||||
mlx5_eq_async_int_unlock(eq_async, recovery, &flags);
|
mlx5_eq_async_int_unlock(eq_async, recovery, &flags);
|
||||||
|
|
||||||
return unlikely(recovery) ? num_eqes : 0;
|
return unlikely(recovery) ? num_eqes : 0;
|
||||||
|
|||||||
@@ -156,6 +156,9 @@ void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (!MLX5_CAP_GEN(dev, roce))
|
||||||
|
return;
|
||||||
|
|
||||||
err = mlx5_nic_vport_enable_roce(dev);
|
err = mlx5_nic_vport_enable_roce(dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err);
|
mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err);
|
||||||
|
|||||||
@@ -124,10 +124,11 @@ int mlx5dr_action_destroy(struct mlx5dr_action *action);
|
|||||||
static inline bool
|
static inline bool
|
||||||
mlx5dr_is_supported(struct mlx5_core_dev *dev)
|
mlx5dr_is_supported(struct mlx5_core_dev *dev)
|
||||||
{
|
{
|
||||||
return MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner) ||
|
return MLX5_CAP_GEN(dev, roce) &&
|
||||||
(MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner_v2) &&
|
(MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner) ||
|
||||||
(MLX5_CAP_GEN(dev, steering_format_version) <=
|
(MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner_v2) &&
|
||||||
MLX5_STEERING_FORMAT_CONNECTX_6DX));
|
(MLX5_CAP_GEN(dev, steering_format_version) <=
|
||||||
|
MLX5_STEERING_FORMAT_CONNECTX_6DX)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* buddy functions & structure */
|
/* buddy functions & structure */
|
||||||
|
|||||||
@@ -424,6 +424,15 @@ err_modify_sq:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mlx5_hairpin_unpair_peer_sq(struct mlx5_hairpin *hp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < hp->num_channels; i++)
|
||||||
|
mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY,
|
||||||
|
MLX5_SQC_STATE_RST, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp)
|
static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -432,13 +441,9 @@ static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp)
|
|||||||
for (i = 0; i < hp->num_channels; i++)
|
for (i = 0; i < hp->num_channels; i++)
|
||||||
mlx5_hairpin_modify_rq(hp->func_mdev, hp->rqn[i], MLX5_RQC_STATE_RDY,
|
mlx5_hairpin_modify_rq(hp->func_mdev, hp->rqn[i], MLX5_RQC_STATE_RDY,
|
||||||
MLX5_RQC_STATE_RST, 0, 0);
|
MLX5_RQC_STATE_RST, 0, 0);
|
||||||
|
|
||||||
/* unset peer SQs */
|
/* unset peer SQs */
|
||||||
if (hp->peer_gone)
|
if (!hp->peer_gone)
|
||||||
return;
|
mlx5_hairpin_unpair_peer_sq(hp);
|
||||||
for (i = 0; i < hp->num_channels; i++)
|
|
||||||
mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY,
|
|
||||||
MLX5_SQC_STATE_RST, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mlx5_hairpin *
|
struct mlx5_hairpin *
|
||||||
@@ -485,3 +490,16 @@ void mlx5_core_hairpin_destroy(struct mlx5_hairpin *hp)
|
|||||||
mlx5_hairpin_destroy_queues(hp);
|
mlx5_hairpin_destroy_queues(hp);
|
||||||
kfree(hp);
|
kfree(hp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mlx5_core_hairpin_clear_dead_peer(struct mlx5_hairpin *hp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mlx5_hairpin_unpair_peer_sq(hp);
|
||||||
|
|
||||||
|
/* destroy peer SQ */
|
||||||
|
for (i = 0; i < hp->num_channels; i++)
|
||||||
|
mlx5_core_destroy_sq(hp->peer_mdev, hp->sqn[i]);
|
||||||
|
|
||||||
|
hp->peer_gone = true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -85,4 +85,5 @@ mlx5_core_hairpin_create(struct mlx5_core_dev *func_mdev,
|
|||||||
struct mlx5_hairpin_params *params);
|
struct mlx5_hairpin_params *params);
|
||||||
|
|
||||||
void mlx5_core_hairpin_destroy(struct mlx5_hairpin *pair);
|
void mlx5_core_hairpin_destroy(struct mlx5_hairpin *pair);
|
||||||
|
void mlx5_core_hairpin_clear_dead_peer(struct mlx5_hairpin *hp);
|
||||||
#endif /* __TRANSOBJ_H__ */
|
#endif /* __TRANSOBJ_H__ */
|
||||||
|
|||||||
Reference in New Issue
Block a user