Commit 388fa7f1 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 6cde05ab 54e1217b
...@@ -64,6 +64,8 @@ struct devlink_port *mlx5e_get_devlink_port(struct net_device *dev) ...@@ -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;
......
// 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 @@ ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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 @@ mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe, ...@@ -288,7 +291,7 @@ mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe,
/* 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 @@ mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe, ...@@ -296,6 +299,30 @@ mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe,
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) ...@@ -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 @@ static int arfs_create_table(struct mlx5e_priv *priv, ...@@ -356,7 +356,7 @@ static int arfs_create_table(struct mlx5e_priv *priv,
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) ...@@ -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) ...@@ -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, ...@@ -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 ...@@ -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 @@ ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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); ...@@ -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 @@ static int mlx5_hairpin_pair_queues(struct mlx5_hairpin *hp) ...@@ -424,6 +424,15 @@ static int mlx5_hairpin_pair_queues(struct mlx5_hairpin *hp)
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) ...@@ -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) ...@@ -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, ...@@ -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__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment