Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 190c3ee0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull networking fixes from David Miller:

 1) Some 'const'ing in qlogic networking drivers, from Bhumika Goyal.

 2) Fix scheduling while atomic in l2tp network namespace exit by
    deferring the work to the workqueue. From Ridge Kennedy.

 3) Fix use after free in dccp timewait handling, from Andrey Ryabinin.

 4) mlx5e CQE compression engine not initialized properly, from Tariq
    Toukan.

 5) Some UAPI header fixes from Dmitry V. Levin.

 6) Don't overwrite module parameter value in mlx4 driver, from Majd
    Dibbiny.

 7) Fix divide by zero in xt_hashlimit netfilter module, from Alban
    Browaeys.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (35 commits)
  bpf: Fix bpf_xdp_event_output
  net/mlx4_en: Use __skb_fill_page_desc()
  net/mlx4_core: Use cq quota in SRIOV when creating completion EQs
  net/mlx4_core: Fix VF overwrite of module param which disables DMFS on new probed PFs
  net/mlx4: Spoofcheck and zero MAC can't coexist
  net/mlx4: Change ENOTSUPP to EOPNOTSUPP
  uapi: fix linux/rds.h userspace compilation errors
  uapi: fix linux/seg6.h and linux/seg6_iptunnel.h userspace compilation errors
  lib: Remove string from parman config selection
  forcedeth: Remove return from a void function
  bpf: fix spelling mistake: "proccessed" -> "processed"
  uapi: fix linux/llc.h userspace compilation error
  uapi: fix linux/ip6_tunnel.h userspace compilation errors
  net/mlx5e: Fix wrong CQE decompression
  net/mlx5e: Update MPWQE stride size when modifying CQE compress state
  net/mlx5e: Fix broken CQE compression initialization
  net/mlx5e: Do not reduce LRO WQE size when not using build_skb
  net/mlx5e: Register/unregister vport representors on interface attach/detach
  net/mlx5e: s390 system compilation fix
  tcp: account for ts offset only if tsecr not zero
  ...
parents af17fe7a 9c471370
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ config IBM_EMAC
	tristate "IBM EMAC Ethernet support"
	depends on PPC_DCR
	select CRC32
	select PHYLIB
	help
	  This driver supports the IBM EMAC family of Ethernet controllers
	  typically found on 4xx embedded PowerPC chips, but also on the
+247 −7
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_net.h>
#include <linux/of_mdio.h>
#include <linux/slab.h>

#include <asm/processor.h>
@@ -2420,6 +2421,219 @@ static int emac_read_uint_prop(struct device_node *np, const char *name,
	return 0;
}

static void emac_adjust_link(struct net_device *ndev)
{
	struct emac_instance *dev = netdev_priv(ndev);
	struct phy_device *phy = dev->phy_dev;

	dev->phy.autoneg = phy->autoneg;
	dev->phy.speed = phy->speed;
	dev->phy.duplex = phy->duplex;
	dev->phy.pause = phy->pause;
	dev->phy.asym_pause = phy->asym_pause;
	dev->phy.advertising = phy->advertising;
}

static int emac_mii_bus_read(struct mii_bus *bus, int addr, int regnum)
{
	int ret = emac_mdio_read(bus->priv, addr, regnum);
	/* This is a workaround for powered down ports/phys.
	 * In the wild, this was seen on the Cisco Meraki MX60(W).
	 * This hardware disables ports as part of the handoff
	 * procedure. Accessing the ports will lead to errors
	 * (-ETIMEDOUT, -EREMOTEIO) that do more harm than good.
	 */
	return ret < 0 ? 0xffff : ret;
}

static int emac_mii_bus_write(struct mii_bus *bus, int addr,
			      int regnum, u16 val)
{
	emac_mdio_write(bus->priv, addr, regnum, val);
	return 0;
}

static int emac_mii_bus_reset(struct mii_bus *bus)
{
	struct emac_instance *dev = netdev_priv(bus->priv);

	return emac_reset(dev);
}

static int emac_mdio_setup_aneg(struct mii_phy *phy, u32 advertise)
{
	struct net_device *ndev = phy->dev;
	struct emac_instance *dev = netdev_priv(ndev);

	dev->phy.autoneg = AUTONEG_ENABLE;
	dev->phy.speed = SPEED_1000;
	dev->phy.duplex = DUPLEX_FULL;
	dev->phy.advertising = advertise;
	phy->autoneg = AUTONEG_ENABLE;
	phy->speed = dev->phy.speed;
	phy->duplex = dev->phy.duplex;
	phy->advertising = advertise;
	return phy_start_aneg(dev->phy_dev);
}

static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd)
{
	struct net_device *ndev = phy->dev;
	struct emac_instance *dev = netdev_priv(ndev);

	dev->phy.autoneg =  AUTONEG_DISABLE;
	dev->phy.speed = speed;
	dev->phy.duplex = fd;
	phy->autoneg = AUTONEG_DISABLE;
	phy->speed = speed;
	phy->duplex = fd;
	return phy_start_aneg(dev->phy_dev);
}

static int emac_mdio_poll_link(struct mii_phy *phy)
{
	struct net_device *ndev = phy->dev;
	struct emac_instance *dev = netdev_priv(ndev);
	int res;

	res = phy_read_status(dev->phy_dev);
	if (res) {
		dev_err(&dev->ofdev->dev, "link update failed (%d).", res);
		return ethtool_op_get_link(ndev);
	}

	return dev->phy_dev->link;
}

static int emac_mdio_read_link(struct mii_phy *phy)
{
	struct net_device *ndev = phy->dev;
	struct emac_instance *dev = netdev_priv(ndev);
	int res;

	res = phy_read_status(dev->phy_dev);
	if (res)
		return res;

	dev->phy.speed = phy->speed;
	dev->phy.duplex = phy->duplex;
	dev->phy.pause = phy->pause;
	dev->phy.asym_pause = phy->asym_pause;
	return 0;
}

static int emac_mdio_init_phy(struct mii_phy *phy)
{
	struct net_device *ndev = phy->dev;
	struct emac_instance *dev = netdev_priv(ndev);

	phy_start(dev->phy_dev);
	dev->phy.autoneg = phy->autoneg;
	dev->phy.speed = phy->speed;
	dev->phy.duplex = phy->duplex;
	dev->phy.advertising = phy->advertising;
	dev->phy.pause = phy->pause;
	dev->phy.asym_pause = phy->asym_pause;

	return phy_init_hw(dev->phy_dev);
}

static const struct mii_phy_ops emac_dt_mdio_phy_ops = {
	.init		= emac_mdio_init_phy,
	.setup_aneg	= emac_mdio_setup_aneg,
	.setup_forced	= emac_mdio_setup_forced,
	.poll_link	= emac_mdio_poll_link,
	.read_link	= emac_mdio_read_link,
};

static int emac_dt_mdio_probe(struct emac_instance *dev)
{
	struct device_node *mii_np;
	int res;

	mii_np = of_get_child_by_name(dev->ofdev->dev.of_node, "mdio");
	if (!mii_np) {
		dev_err(&dev->ofdev->dev, "no mdio definition found.");
		return -ENODEV;
	}

	if (!of_device_is_available(mii_np)) {
		res = -ENODEV;
		goto put_node;
	}

	dev->mii_bus = devm_mdiobus_alloc(&dev->ofdev->dev);
	if (!dev->mii_bus) {
		res = -ENOMEM;
		goto put_node;
	}

	dev->mii_bus->priv = dev->ndev;
	dev->mii_bus->parent = dev->ndev->dev.parent;
	dev->mii_bus->name = "emac_mdio";
	dev->mii_bus->read = &emac_mii_bus_read;
	dev->mii_bus->write = &emac_mii_bus_write;
	dev->mii_bus->reset = &emac_mii_bus_reset;
	snprintf(dev->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev->ofdev->name);
	res = of_mdiobus_register(dev->mii_bus, mii_np);
	if (res) {
		dev_err(&dev->ofdev->dev, "cannot register MDIO bus %s (%d)",
			dev->mii_bus->name, res);
	}

 put_node:
	of_node_put(mii_np);
	return res;
}

static int emac_dt_phy_connect(struct emac_instance *dev,
			       struct device_node *phy_handle)
{
	int res;

	dev->phy.def = devm_kzalloc(&dev->ofdev->dev, sizeof(*dev->phy.def),
				    GFP_KERNEL);
	if (!dev->phy.def)
		return -ENOMEM;

	dev->phy_dev = of_phy_connect(dev->ndev, phy_handle, &emac_adjust_link,
				      0, dev->phy_mode);
	if (!dev->phy_dev) {
		dev_err(&dev->ofdev->dev, "failed to connect to PHY.\n");
		return -ENODEV;
	}

	dev->phy.def->phy_id = dev->phy_dev->drv->phy_id;
	dev->phy.def->phy_id_mask = dev->phy_dev->drv->phy_id_mask;
	dev->phy.def->name = dev->phy_dev->drv->name;
	dev->phy.def->ops = &emac_dt_mdio_phy_ops;
	dev->phy.features = dev->phy_dev->supported;
	dev->phy.address = dev->phy_dev->mdio.addr;
	dev->phy.mode = dev->phy_dev->interface;
	return 0;
}

static int emac_dt_phy_probe(struct emac_instance *dev)
{
	struct device_node *np = dev->ofdev->dev.of_node;
	struct device_node *phy_handle;
	int res = 0;

	phy_handle = of_parse_phandle(np, "phy-handle", 0);

	if (phy_handle) {
		res = emac_dt_mdio_probe(dev);
		if (!res) {
			res = emac_dt_phy_connect(dev, phy_handle);
			if (res)
				mdiobus_unregister(dev->mii_bus);
		}
	}

	of_node_put(phy_handle);
	return res;
}

static int emac_init_phy(struct emac_instance *dev)
{
	struct device_node *np = dev->ofdev->dev.of_node;
@@ -2430,15 +2644,12 @@ static int emac_init_phy(struct emac_instance *dev)
	dev->phy.dev = ndev;
	dev->phy.mode = dev->phy_mode;

	/* PHY-less configuration.
	 * XXX I probably should move these settings to the dev tree
	 */
	if (dev->phy_address == 0xffffffff && dev->phy_map == 0xffffffff) {
	/* PHY-less configuration. */
	if ((dev->phy_address == 0xffffffff && dev->phy_map == 0xffffffff) ||
	    of_phy_is_fixed_link(np)) {
		emac_reset(dev);

		/* PHY-less configuration.
		 * XXX I probably should move these settings to the dev tree
		 */
		/* PHY-less configuration. */
		dev->phy.address = -1;
		dev->phy.features = SUPPORTED_MII;
		if (emac_phy_supports_gige(dev->phy_mode))
@@ -2447,6 +2658,16 @@ static int emac_init_phy(struct emac_instance *dev)
			dev->phy.features |= SUPPORTED_100baseT_Full;
		dev->phy.pause = 1;

		if (of_phy_is_fixed_link(np)) {
			int res = emac_dt_mdio_probe(dev);

			if (!res) {
				res = of_phy_register_fixed_link(np);
				if (res)
					mdiobus_unregister(dev->mii_bus);
			}
			return res;
		}
		return 0;
	}

@@ -2490,6 +2711,18 @@ static int emac_init_phy(struct emac_instance *dev)

	emac_configure(dev);

	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII)) {
		int res = emac_dt_phy_probe(dev);

		mutex_unlock(&emac_phy_map_lock);
		if (!res)
			goto init_phy;

		dev_err(&dev->ofdev->dev, "failed to attach dt phy (%d).\n",
			res);
		return res;
	}

	if (dev->phy_address != 0xffffffff)
		phy_map = ~(1 << dev->phy_address);

@@ -2517,6 +2750,7 @@ static int emac_init_phy(struct emac_instance *dev)
		return -ENXIO;
	}

 init_phy:
	/* Init PHY */
	if (dev->phy.def->ops->init)
		dev->phy.def->ops->init(&dev->phy);
@@ -2988,6 +3222,12 @@ static int emac_remove(struct platform_device *ofdev)
	if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
		zmii_detach(dev->zmii_dev, dev->zmii_port);

	if (dev->phy_dev)
		phy_disconnect(dev->phy_dev);

	if (dev->mii_bus)
		mdiobus_unregister(dev->mii_bus);

	busy_phy_map &= ~(1 << dev->phy.address);
	DBG(dev, "busy_phy_map now %#x" NL, busy_phy_map);

+4 −0
Original line number Diff line number Diff line
@@ -199,6 +199,10 @@ struct emac_instance {
	struct emac_instance		*mdio_instance;
	struct mutex			mdio_lock;

	/* Device-tree based phy configuration */
	struct mii_bus			*mii_bus;
	struct phy_device		*phy_dev;

	/* ZMII infos if any */
	u32				zmii_ph;
	u32				zmii_port;
+20 −2
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include <linux/semaphore.h>
#include <rdma/ib_smi.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>

#include <asm/io.h>

@@ -2955,7 +2956,7 @@ static bool mlx4_valid_vf_state_change(struct mlx4_dev *dev, int port,
	return false;
}

int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac)
int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u8 *mac)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_vport_state *s_info;
@@ -2964,13 +2965,22 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac)
	if (!mlx4_is_master(dev))
		return -EPROTONOSUPPORT;

	if (is_multicast_ether_addr(mac))
		return -EINVAL;

	slave = mlx4_get_slave_indx(dev, vf);
	if (slave < 0)
		return -EINVAL;

	port = mlx4_slaves_closest_port(dev, slave, port);
	s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
	s_info->mac = mac;

	if (s_info->spoofchk && is_zero_ether_addr(mac)) {
		mlx4_info(dev, "MAC invalidation is not allowed when spoofchk is on\n");
		return -EPERM;
	}

	s_info->mac = mlx4_mac_to_u64(mac);
	mlx4_info(dev, "default mac on vf %d port %d to %llX will take effect only after vf restart\n",
		  vf, port, s_info->mac);
	return 0;
@@ -3143,6 +3153,7 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting)
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_vport_state *s_info;
	int slave;
	u8 mac[ETH_ALEN];

	if ((!mlx4_is_master(dev)) ||
	    !(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FSM))
@@ -3154,6 +3165,13 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting)

	port = mlx4_slaves_closest_port(dev, slave, port);
	s_info = &priv->mfunc.master.vf_admin[slave].vport[port];

	mlx4_u64_to_mac(mac, s_info->mac);
	if (setting && !is_valid_ether_addr(mac)) {
		mlx4_info(dev, "Illegal MAC with spoofchk\n");
		return -EPERM;
	}

	s_info->spoofchk = setting;

	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -319,7 +319,7 @@ static int mlx4_en_ets_validate(struct mlx4_en_priv *priv, struct ieee_ets *ets)
		default:
			en_err(priv, "TC[%d]: Not supported TSA: %d\n",
					i, ets->tc_tsa[i]);
			return -ENOTSUPP;
			return -EOPNOTSUPP;
		}
	}

Loading