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)
struct mlx5e_priv *priv = netdev_priv(dev);
struct devlink_port *port;
if (!netif_device_present(dev))
return NULL;
port = mlx5e_devlink_get_dl_port(priv);
if (port->registered)
return port;
......
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
// Copyright (c) 2020 Mellanox Technologies
#include <linux/ptp_classify.h>
#include "en/ptp.h"
#include "en/txrx.h"
#include "en/params.h"
......
......@@ -6,6 +6,7 @@
#include "en.h"
#include "en_stats.h"
#include <linux/ptp_classify.h>
struct mlx5e_ptpsq {
struct mlx5e_txqsq txqsq;
......@@ -43,6 +44,27 @@ struct mlx5e_ptp {
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,
u8 lag_port, struct mlx5e_ptp **cp);
void mlx5e_ptp_close(struct mlx5e_ptp *c);
......
......@@ -129,10 +129,9 @@ static void mlx5e_rep_neigh_update(struct work_struct *work)
work);
struct mlx5e_neigh_hash_entry *nhe = update_work->nhe;
struct neighbour *n = update_work->n;
struct mlx5e_encap_entry *e = NULL;
bool neigh_connected, same_dev;
struct mlx5e_encap_entry *e;
unsigned char ha[ETH_ALEN];
struct mlx5e_priv *priv;
u8 nud_state, dead;
rtnl_lock();
......@@ -156,14 +155,12 @@ static void mlx5e_rep_neigh_update(struct work_struct *work)
if (!same_dev)
goto out;
list_for_each_entry(e, &nhe->encap_list, encap_list) {
if (!mlx5e_encap_take(e))
continue;
/* mlx5e_get_next_init_encap() releases previous encap before returning
* the next one.
*/
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:
rtnl_unlock();
mlx5e_release_neigh_update_work(update_work);
......
......@@ -94,13 +94,9 @@ void mlx5e_rep_update_flows(struct mlx5e_priv *priv,
ASSERT_RTNL();
/* wait for encap to be fully initialized */
wait_for_completion(&e->res_ready);
mutex_lock(&esw->offloads.encap_tbl_lock);
encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID);
if (e->compl_result < 0 || (encap_connected == neigh_connected &&
ether_addr_equal(e->h_dest, ha)))
if (encap_connected == neigh_connected && ether_addr_equal(e->h_dest, ha))
goto unlock;
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);
}
typedef bool (match_cb)(struct mlx5e_encap_entry *);
static struct mlx5e_encap_entry *
mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe,
struct mlx5e_encap_entry *e)
mlx5e_get_next_matching_encap(struct mlx5e_neigh_hash_entry *nhe,
struct mlx5e_encap_entry *e,
match_cb match)
{
struct mlx5e_encap_entry *next = NULL;
......@@ -288,7 +291,7 @@ mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe,
/* wait for encap to be fully initialized */
wait_for_completion(&next->res_ready);
/* continue searching if encap entry is not in valid state after completion */
if (!(next->flags & MLX5_ENCAP_ENTRY_VALID)) {
if (!match(next)) {
e = next;
goto retry;
}
......@@ -296,6 +299,30 @@ mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe,
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)
{
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 net_device *netdev = priv->netdev;
if (!priv->ipsec)
return;
if (!(mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_CAP_ESP) ||
!MLX5_CAP_ETH(mdev, swp)) {
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,
int mlx5e_arfs_create_tables(struct mlx5e_priv *priv)
{
int err = 0;
int err = -ENOMEM;
int i;
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;
ntc = priv->channels.params.num_tc;
num_rxqs = nch * priv->profile->rq_groups;
if (priv->channels.params.ptp_rx)
num_rxqs++;
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)) {
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->hw_enc_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;
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL;
netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL;
}
if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_GRE)) {
netdev->hw_features |= NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM;
netdev->hw_enc_features |= NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM;
netdev->gso_partial_features |= NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM;
netdev->hw_features |= NETIF_F_GSO_GRE;
netdev->hw_enc_features |= NETIF_F_GSO_GRE;
netdev->gso_partial_features |= NETIF_F_GSO_GRE;
}
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) {
wait_for_completion(&hpe->res_ready);
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);
}
......
......@@ -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);
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_reoffload_flows_work(struct work_struct *work);
......
......@@ -32,7 +32,6 @@
#include <linux/tcp.h>
#include <linux/if_vlan.h>
#include <linux/ptp_classify.h>
#include <net/geneve.h>
#include <net/dsfield.h>
#include "en.h"
......@@ -67,24 +66,6 @@ static inline int mlx5e_get_dscp_up(struct mlx5e_priv *priv, struct sk_buff *skb
}
#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)
{
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);
if (unlikely(ptp_channel) &&
test_bit(MLX5E_PTP_STATE_TX, ptp_channel->state) &&
mlx5e_use_ptpsq(skb))
if (unlikely(ptp_channel &&
test_bit(MLX5E_PTP_STATE_TX, ptp_channel->state) &&
mlx5e_use_ptpsq(skb)))
return mlx5e_select_ptpsq(dev, skb);
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);
if (!eqe)
return 0;
goto out;
do {
struct mlx5_core_cq *cq;
......@@ -161,6 +161,8 @@ static int mlx5_eq_comp_int(struct notifier_block *nb,
++eq->cons_index;
} while ((++num_eqes < MLX5_EQ_POLLING_BUDGET) && (eqe = next_eqe_sw(eq)));
out:
eq_update_ci(eq, 1);
if (cqn != -1)
......@@ -248,9 +250,9 @@ static int mlx5_eq_async_int(struct notifier_block *nb,
++eq->cons_index;
} while ((++num_eqes < MLX5_EQ_POLLING_BUDGET) && (eqe = next_eqe_sw(eq)));
eq_update_ci(eq, 1);
out:
eq_update_ci(eq, 1);
mlx5_eq_async_int_unlock(eq_async, recovery, &flags);
return unlikely(recovery) ? num_eqes : 0;
......
......@@ -156,6 +156,9 @@ void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
{
int err;
if (!MLX5_CAP_GEN(dev, roce))
return;
err = mlx5_nic_vport_enable_roce(dev);
if (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
mlx5dr_is_supported(struct mlx5_core_dev *dev)
{
return MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner) ||
(MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner_v2) &&
(MLX5_CAP_GEN(dev, steering_format_version) <=
MLX5_STEERING_FORMAT_CONNECTX_6DX));
return MLX5_CAP_GEN(dev, roce) &&
(MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner) ||
(MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner_v2) &&
(MLX5_CAP_GEN(dev, steering_format_version) <=
MLX5_STEERING_FORMAT_CONNECTX_6DX)));
}
/* buddy functions & structure */
......
......@@ -424,6 +424,15 @@ static int mlx5_hairpin_pair_queues(struct mlx5_hairpin *hp)
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)
{
int i;
......@@ -432,13 +441,9 @@ static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp)
for (i = 0; i < hp->num_channels; i++)
mlx5_hairpin_modify_rq(hp->func_mdev, hp->rqn[i], MLX5_RQC_STATE_RDY,
MLX5_RQC_STATE_RST, 0, 0);
/* unset peer SQs */
if (hp->peer_gone)
return;
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);
if (!hp->peer_gone)
mlx5_hairpin_unpair_peer_sq(hp);
}
struct mlx5_hairpin *
......@@ -485,3 +490,16 @@ void mlx5_core_hairpin_destroy(struct mlx5_hairpin *hp)
mlx5_hairpin_destroy_queues(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);
void mlx5_core_hairpin_destroy(struct mlx5_hairpin *pair);
void mlx5_core_hairpin_clear_dead_peer(struct mlx5_hairpin *hp);
#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