Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Browse files Browse the repository at this point in the history
Pull networking fixes from David Miller:

 1) Fix rtlwifi crash, from Larry Finger.

 2) Memory disclosure in appletalk ipddp routing code, from Vlad
    Tsyrklevich.

 3) r8152 can erroneously split an RX packet into multiple URBs if the
    Rx FIFO is not empty when we suspend. Fix this by waiting for the
    FIFO to empty before suspending. From Hayes Wang.

 4) Two GRO fixes (enter slow path when not enough SKB tail room exists,
    disable frag0 optimizations when there are IPV6 extension headers)
    from Eric Dumazet and Herbert Xu.

 5) A series of mlx5e bug fixes (do source udp port offloading for
    tunnels properly, Ip fragment matching fixes, handling firmware
    errors properly when installing TC rules, etc.) from Saeed Mahameed,
    Or Gerlitz, Roi Dayan, Hadar Hen Zion, Gil Rockah, and Daniel
    Jurgens.

 6) Two VRF fixes from David Ahern (don't skip multipath selection for
    VRF paths, disallow VRF to be configured with table ID 0).

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (35 commits)
  net: vrf: do not allow table id 0
  net: phy: marvell: fix Marvell 88E1512 used in SGMII mode
  sctp: Fix spelling mistake: "Atempt" -> "Attempt"
  net: ipv4: Fix multipath selection with vrf
  cgroup: move CONFIG_SOCK_CGROUP_DATA to init/Kconfig
  gro: use min_t() in skb_gro_reset_offset()
  net/mlx5: Only cancel recovery work when cleaning up device
  net/mlx5e: Remove WARN_ONCE from adaptive moderation code
  net/mlx5e: Un-register uplink representor on nic_disable
  net/mlx5e: Properly handle FW errors while adding TC rules
  net/mlx5e: Fix kbuild warnings for uninitialized parameters
  net/mlx5e: Set inline mode requirements for matching on IP fragments
  net/mlx5e: Properly get address type of encapsulation IP headers
  net/mlx5e: TC ipv4 tunnel encap offload error flow fixes
  net/mlx5e: Warn when rejecting offload attempts of IP tunnels
  net/mlx5e: Properly handle offloading of source udp port for IP tunnels
  gro: Disable frag0 optimization on IPv6 ext headers
  gro: Enter slow-path if there is no tailroom
  mlx4: Return EOPNOTSUPP instead of ENOTSUPP
  net/af_iucv: don't use paged skbs for TX on HiperSockets
  ...
  • Loading branch information
Linus Torvalds committed Jan 11, 2017
2 parents a6b6e61 + 24c63bb commit cff3b2c
Show file tree
Hide file tree
Showing 31 changed files with 243 additions and 121 deletions.
2 changes: 1 addition & 1 deletion drivers/net/appletalk/ipddp.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ static netdev_tx_t ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
*/
static int ipddp_create(struct ipddp_route *new_rt)
{
struct ipddp_route *rt = kmalloc(sizeof(*rt), GFP_KERNEL);
struct ipddp_route *rt = kzalloc(sizeof(*rt), GFP_KERNEL);

if (rt == NULL)
return -ENOMEM;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx4/en_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2277,7 +2277,7 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)

if (priv->tx_ring_num[TX_XDP] &&
!mlx4_en_check_xdp_mtu(dev, new_mtu))
return -ENOTSUPP;
return -EOPNOTSUPP;

dev->mtu = new_mtu;

Expand Down
13 changes: 6 additions & 7 deletions drivers/net/ethernet/mellanox/mlx5/core/en_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3675,14 +3675,8 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev,

static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
{
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5_eswitch *esw = mdev->priv.eswitch;

mlx5e_vxlan_cleanup(priv);

if (MLX5_CAP_GEN(mdev, vport_group_manager))
mlx5_eswitch_unregister_vport_rep(esw, 0);

if (priv->xdp_prog)
bpf_prog_put(priv->xdp_prog);
}
Expand Down Expand Up @@ -3807,9 +3801,14 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)

static void mlx5e_nic_disable(struct mlx5e_priv *priv)
{
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5_eswitch *esw = mdev->priv.eswitch;

queue_work(priv->wq, &priv->set_rx_mode_work);
if (MLX5_CAP_GEN(mdev, vport_group_manager))
mlx5_eswitch_unregister_vport_rep(esw, 0);
mlx5e_disable_async_events(priv);
mlx5_lag_remove(priv->mdev);
mlx5_lag_remove(mdev);
}

static const struct mlx5e_profile mlx5e_nic_profile = {
Expand Down
7 changes: 1 addition & 6 deletions drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ static bool mlx5e_am_on_top(struct mlx5e_rx_am *am)
switch (am->tune_state) {
case MLX5E_AM_PARKING_ON_TOP:
case MLX5E_AM_PARKING_TIRED:
WARN_ONCE(true, "mlx5e_am_on_top: PARKING\n");
return true;
case MLX5E_AM_GOING_RIGHT:
return (am->steps_left > 1) && (am->steps_right == 1);
Expand All @@ -123,7 +122,6 @@ static void mlx5e_am_turn(struct mlx5e_rx_am *am)
switch (am->tune_state) {
case MLX5E_AM_PARKING_ON_TOP:
case MLX5E_AM_PARKING_TIRED:
WARN_ONCE(true, "mlx5e_am_turn: PARKING\n");
break;
case MLX5E_AM_GOING_RIGHT:
am->tune_state = MLX5E_AM_GOING_LEFT;
Expand All @@ -144,7 +142,6 @@ static int mlx5e_am_step(struct mlx5e_rx_am *am)
switch (am->tune_state) {
case MLX5E_AM_PARKING_ON_TOP:
case MLX5E_AM_PARKING_TIRED:
WARN_ONCE(true, "mlx5e_am_step: PARKING\n");
break;
case MLX5E_AM_GOING_RIGHT:
if (am->profile_ix == (MLX5E_PARAMS_AM_NUM_PROFILES - 1))
Expand Down Expand Up @@ -282,10 +279,8 @@ static void mlx5e_am_calc_stats(struct mlx5e_rx_am_sample *start,
u32 delta_us = ktime_us_delta(end->time, start->time);
unsigned int npkts = end->pkt_ctr - start->pkt_ctr;

if (!delta_us) {
WARN_ONCE(true, "mlx5e_am_calc_stats: delta_us=0\n");
if (!delta_us)
return;
}

curr_stats->ppms = (npkts * USEC_PER_MSEC) / delta_us;
curr_stats->epms = (MLX5E_AM_NEVENTS * USEC_PER_MSEC) / delta_us;
Expand Down
93 changes: 64 additions & 29 deletions drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,24 +161,28 @@ static void mlx5e_detach_encap(struct mlx5e_priv *priv,
}
}

/* we get here also when setting rule to the FW failed, etc. It means that the
* flow rule itself might not exist, but some offloading related to the actions
* should be cleaned.
*/
static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow)
{
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
struct mlx5_fc *counter = NULL;

counter = mlx5_flow_rule_counter(flow->rule);

mlx5_del_flow_rules(flow->rule);
if (!IS_ERR(flow->rule)) {
counter = mlx5_flow_rule_counter(flow->rule);
mlx5_del_flow_rules(flow->rule);
mlx5_fc_destroy(priv->mdev, counter);
}

if (esw && esw->mode == SRIOV_OFFLOADS) {
mlx5_eswitch_del_vlan_action(esw, flow->attr);
if (flow->attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP)
mlx5e_detach_encap(priv, flow);
}

mlx5_fc_destroy(priv->mdev, counter);

if (!mlx5e_tc_num_filters(priv) && (priv->fs.tc.t)) {
mlx5_destroy_flow_table(priv->fs.tc.t);
priv->fs.tc.t = NULL;
Expand Down Expand Up @@ -225,6 +229,11 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
void *headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
outer_headers);

struct flow_dissector_key_control *enc_control =
skb_flow_dissector_target(f->dissector,
FLOW_DISSECTOR_KEY_ENC_CONTROL,
f->key);

if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ENC_PORTS)) {
struct flow_dissector_key_ports *key =
skb_flow_dissector_target(f->dissector,
Expand All @@ -237,28 +246,34 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,

/* Full udp dst port must be given */
if (memchr_inv(&mask->dst, 0xff, sizeof(mask->dst)))
return -EOPNOTSUPP;

/* udp src port isn't supported */
if (memchr_inv(&mask->src, 0, sizeof(mask->src)))
return -EOPNOTSUPP;
goto vxlan_match_offload_err;

if (mlx5e_vxlan_lookup_port(priv, be16_to_cpu(key->dst)) &&
MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap))
parse_vxlan_attr(spec, f);
else
else {
netdev_warn(priv->netdev,
"%d isn't an offloaded vxlan udp dport\n", be16_to_cpu(key->dst));
return -EOPNOTSUPP;
}

MLX5_SET(fte_match_set_lyr_2_4, headers_c,
udp_dport, ntohs(mask->dst));
MLX5_SET(fte_match_set_lyr_2_4, headers_v,
udp_dport, ntohs(key->dst));

MLX5_SET(fte_match_set_lyr_2_4, headers_c,
udp_sport, ntohs(mask->src));
MLX5_SET(fte_match_set_lyr_2_4, headers_v,
udp_sport, ntohs(key->src));
} else { /* udp dst port must be given */
return -EOPNOTSUPP;
vxlan_match_offload_err:
netdev_warn(priv->netdev,
"IP tunnel decap offload supported only for vxlan, must set UDP dport\n");
return -EOPNOTSUPP;
}

if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
if (enc_control->addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
struct flow_dissector_key_ipv4_addrs *key =
skb_flow_dissector_target(f->dissector,
FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
Expand All @@ -280,10 +295,10 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
MLX5_SET(fte_match_set_lyr_2_4, headers_v,
dst_ipv4_dst_ipv6.ipv4_layout.ipv4,
ntohl(key->dst));
}

MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, ethertype);
MLX5_SET(fte_match_set_lyr_2_4, headers_v, ethertype, ETH_P_IP);
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, ethertype);
MLX5_SET(fte_match_set_lyr_2_4, headers_v, ethertype, ETH_P_IP);
}

/* Enforce DMAC when offloading incoming tunneled flows.
* Flow counters require a match on the DMAC.
Expand Down Expand Up @@ -346,6 +361,9 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
if (parse_tunnel_attr(priv, spec, f))
return -EOPNOTSUPP;
break;
case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
netdev_warn(priv->netdev,
"IPv6 tunnel decap offload isn't supported\n");
default:
return -EOPNOTSUPP;
}
Expand Down Expand Up @@ -375,6 +393,10 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
MLX5_SET(fte_match_set_lyr_2_4, headers_c, frag, 1);
MLX5_SET(fte_match_set_lyr_2_4, headers_v, frag,
key->flags & FLOW_DIS_IS_FRAGMENT);

/* the HW doesn't need L3 inline to match on frag=no */
if (key->flags & FLOW_DIS_IS_FRAGMENT)
*min_inline = MLX5_INLINE_MODE_IP;
}
}

Expand Down Expand Up @@ -647,17 +669,14 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv,

#if IS_ENABLED(CONFIG_INET)
rt = ip_route_output_key(dev_net(mirred_dev), fl4);
if (IS_ERR(rt)) {
pr_warn("%s: no route to %pI4\n", __func__, &fl4->daddr);
return -EOPNOTSUPP;
}
if (IS_ERR(rt))
return PTR_ERR(rt);
#else
return -EOPNOTSUPP;
#endif

if (!switchdev_port_same_parent_id(priv->netdev, rt->dst.dev)) {
pr_warn("%s: Can't offload the flow, netdevices aren't on the same HW e-switch\n",
__func__);
pr_warn("%s: can't offload, devices not on same HW e-switch\n", __func__);
ip_rt_put(rt);
return -EOPNOTSUPP;
}
Expand Down Expand Up @@ -718,12 +737,12 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
struct net_device **out_dev)
{
int max_encap_size = MLX5_CAP_ESW(priv->mdev, max_encap_header_size);
struct neighbour *n = NULL;
struct flowi4 fl4 = {};
struct neighbour *n;
char *encap_header;
int encap_size;
__be32 saddr;
int ttl;
__be32 saddr = 0;
int ttl = 0;
int err;

encap_header = kzalloc(max_encap_size, GFP_KERNEL);
Expand All @@ -750,7 +769,8 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
e->out_dev = *out_dev;

if (!(n->nud_state & NUD_VALID)) {
err = -ENOTSUPP;
pr_warn("%s: can't offload, neighbour to %pI4 invalid\n", __func__, &fl4.daddr);
err = -EOPNOTSUPP;
goto out;
}

Expand All @@ -772,6 +792,8 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
err = mlx5_encap_alloc(priv->mdev, e->tunnel_type,
encap_size, encap_header, &e->encap_id);
out:
if (err && n)
neigh_release(n);
kfree(encap_header);
return err;
}
Expand All @@ -792,23 +814,36 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
int tunnel_type;
int err;

/* udp dst port must be given */
/* udp dst port must be set */
if (!memchr_inv(&key->tp_dst, 0, sizeof(key->tp_dst)))
goto vxlan_encap_offload_err;

/* setting udp src port isn't supported */
if (memchr_inv(&key->tp_src, 0, sizeof(key->tp_src))) {
vxlan_encap_offload_err:
netdev_warn(priv->netdev,
"must set udp dst port and not set udp src port\n");
return -EOPNOTSUPP;
}

if (mlx5e_vxlan_lookup_port(priv, be16_to_cpu(key->tp_dst)) &&
MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap)) {
info.tp_dst = key->tp_dst;
info.tun_id = tunnel_id_to_key32(key->tun_id);
tunnel_type = MLX5_HEADER_TYPE_VXLAN;
} else {
netdev_warn(priv->netdev,
"%d isn't an offloaded vxlan udp dport\n", be16_to_cpu(key->tp_dst));
return -EOPNOTSUPP;
}

switch (family) {
case AF_INET:
info.daddr = key->u.ipv4.dst;
break;
case AF_INET6:
netdev_warn(priv->netdev,
"IPv6 tunnel encap offload isn't supported\n");
default:
return -EOPNOTSUPP;
}
Expand Down Expand Up @@ -986,7 +1021,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,

if (IS_ERR(flow->rule)) {
err = PTR_ERR(flow->rule);
goto err_free;
goto err_del_rule;
}

err = rhashtable_insert_fast(&tc->ht, &flow->node,
Expand All @@ -997,7 +1032,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
goto out;

err_del_rule:
mlx5_del_flow_rules(flow->rule);
mlx5e_tc_del_flow(priv, flow);

err_free:
kfree(flow);
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1195,7 +1195,8 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
{
int err = 0;

mlx5_drain_health_wq(dev);
if (cleanup)
mlx5_drain_health_wq(dev);

mutex_lock(&dev->intf_state_mutex);
if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) {
Expand Down Expand Up @@ -1359,9 +1360,10 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev,

mlx5_enter_error_state(dev);
mlx5_unload_one(dev, priv, false);
/* In case of kernel call save the pci state */
/* In case of kernel call save the pci state and drain the health wq */
if (state) {
pci_save_state(pdev);
mlx5_drain_health_wq(dev);
mlx5_pci_disable_device(dev);
}

Expand Down
1 change: 1 addition & 0 deletions drivers/net/phy/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ config MARVELL_PHY

config MESON_GXL_PHY
tristate "Amlogic Meson GXL Internal PHY"
depends on ARCH_MESON || COMPILE_TEST
---help---
Currently has a driver for the Amlogic Meson GXL Internal PHY

Expand Down
3 changes: 2 additions & 1 deletion drivers/net/phy/marvell.c
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@ static int marvell_read_status(struct phy_device *phydev)
int err;

/* Check the fiber mode first */
if (phydev->supported & SUPPORTED_FIBRE) {
if (phydev->supported & SUPPORTED_FIBRE &&
phydev->interface != PHY_INTERFACE_MODE_SGMII) {
err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER);
if (err < 0)
goto error;
Expand Down
9 changes: 9 additions & 0 deletions drivers/net/phy/phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,15 @@ void phy_state_machine(struct work_struct *work)
if (old_link != phydev->link)
phydev->state = PHY_CHANGELINK;
}
/*
* Failsafe: check that nobody set phydev->link=0 between two
* poll cycles, otherwise we won't leave RUNNING state as long
* as link remains down.
*/
if (!phydev->link && phydev->state == PHY_RUNNING) {
phydev->state = PHY_CHANGELINK;
phydev_err(phydev, "no link in PHY_RUNNING\n");
}
break;
case PHY_CHANGELINK:
err = phy_read_status(phydev);
Expand Down
Loading

0 comments on commit cff3b2c

Please sign in to comment.