Netdev List
 help / color / mirror / Atom feed
* [PATCH] DSA support for Micrel KSZ8895
From: Pavel Machek @ 2017-08-27 12:36 UTC (permalink / raw)
  To: Woojung.Huh, nathan.leigh.conrad
  Cc: vivien.didelot, f.fainelli, netdev, linux-kernel, Tristram.Ha,
	andrew, pavel
In-Reply-To: <9235D6609DB808459E95D78E17F2E43D40AFF8C1@CHN-SV-EXMX02.mchp-main.com>

[-- Attachment #1: Type: text/plain, Size: 62101 bytes --]

Hi!

So I fought with the driver a bit more, and now I have something that
kind-of-works.

"great great hack" belows worries me.

Yeah, disabled code needs to be removed before merge.

No, tag_ksz part probably is not acceptable. Do you see solution
better than just copying it into tag_ksz1 file?

Any more comments, etc?

Help would be welcome.

Best regards,
									Pavel

Signed-off-by: Pavel Machek <pavel@denx.de>

diff --git a/drivers/net/dsa/microchip/Kconfig b/drivers/net/dsa/microchip/Kconfig
index a8b8f59099ce..7b7d7ddb3488 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -1,12 +1,25 @@
 menuconfig MICROCHIP_KSZ
-	tristate "Microchip KSZ series switch support"
+	tristate "Microchip KSZ 9477 series switch support"
+	depends on NET_DSA
+	select NET_DSA_TAG_KSZ
+	help
+	  This driver adds support for Microchip KSZ switch chips.
+
+menuconfig MICROCHIP_KSZ_8895
+	tristate "Microchip KSZ 8895 series switch support"
 	depends on NET_DSA
 	select NET_DSA_TAG_KSZ
 	help
 	  This driver adds support for Microchip KSZ switch chips.
 
 config MICROCHIP_KSZ_SPI_DRIVER
-	tristate "KSZ series SPI connected switch driver"
+	tristate "KSZ 9477 series SPI connected switch driver"
 	depends on MICROCHIP_KSZ && SPI
 	help
 	  Select to enable support for registering switches configured through SPI.
+
+config MICROCHIP_KSZ_8895_SPI_DRIVER
+	tristate "KSZ 8895 series SPI connected switch driver"
+	depends on MICROCHIP_KSZ_8895 && SPI
+	help
+	  Select to enable support for registering switches configured through SPI.
diff --git a/drivers/net/dsa/microchip/Makefile b/drivers/net/dsa/microchip/Makefile
index ed335e29fae8..b6a17f79d2d9 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,4 @@
 obj-$(CONFIG_MICROCHIP_KSZ)	        += ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ_8895)        += ksz_8895.o
 obj-$(CONFIG_MICROCHIP_KSZ_SPI_DRIVER)	+= ksz_spi.o
+obj-$(CONFIG_MICROCHIP_KSZ_8895_SPI_DRIVER)	+= ksz_8895_spi.o
diff --git a/drivers/net/dsa/microchip/ksz_8895.c b/drivers/net/dsa/microchip/ksz_8895.c
new file mode 100644
index 000000000000..d546e08b1281
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz_8895.c
@@ -0,0 +1,721 @@
+/*
+ * Microchip switch driver main logic
+ *
+ * Copyright (C) 2017
+ * Copyright (C) 2017 Pavel Machek <pavel@denx.de>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_data/microchip-ksz.h>
+#include <linux/phy.h>
+#include <linux/etherdevice.h>
+#include <linux/if_bridge.h>
+#include <net/dsa.h>
+#include <net/switchdev.h>
+
+#include "ksz_8895_reg.h"
+#include "ksz_priv.h"
+
+static const struct {
+	int index;
+	char string[ETH_GSTRING_LEN];
+} mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+	{ 0x00, "???" },
+};
+
+static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
+{
+	u8 data;
+
+	ksz_read8(dev, addr, &data);
+	if (set)
+		data |= bits;
+	else
+		data &= ~bits;
+	ksz_write8(dev, addr, data);
+}
+
+#if 0
+static void ksz_cfg32(struct ksz_device *dev, u32 addr, u32 bits, bool set)
+{
+	u32 data;
+
+	ksz_read32(dev, addr, &data);
+	if (set)
+		data |= bits;
+	else
+		data &= ~bits;
+	ksz_write32(dev, addr, data);
+}
+#endif
+
+static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits,
+			 bool set)
+{
+	u32 addr;
+	u8 data;
+
+	addr = PORT_CTRL_ADDR(port, offset);
+	ksz_read8(dev, addr, &data);
+
+	if (set)
+		data |= bits;
+	else
+		data &= ~bits;
+
+	ksz_write8(dev, addr, data);
+}
+
+#if 0
+static void ksz_port_cfg32(struct ksz_device *dev, int port, int offset,
+			   u32 bits, bool set)
+{
+	u32 addr;
+	u32 data;
+
+	addr = PORT_CTRL_ADDR(port, offset);
+	ksz_read32(dev, addr, &data);
+
+	if (set)
+		data |= bits;
+	else
+		data &= ~bits;
+
+	ksz_write32(dev, addr, data);
+}
+#endif
+
+#define NOTIMPL() do { NOTIMPLV(); return -EJUKEBOX; } while (0)
+#define NOTIMPLV() do { printk("Not implemented -- %s\n",  __func__); } while (0)
+
+static int ksz_reset_switch(struct dsa_switch *ds)
+{
+	struct ksz_device *dev = ds->priv;
+#if 0
+	/* This seems to break the code. */
+	ksz_write8(dev, REG_POWER_MANAGEMENT_1, SW_SOFTWARE_POWER_DOWN << SW_POWER_MANAGEMENT_MODE_S);
+        ksz_write8(dev, REG_POWER_MANAGEMENT_1, 0);
+#endif
+	return 0;
+}
+
+#define PORT_MAC_LOOPBACK_my 0x80
+#define REG_PORT_CTRL_LOOPBACK 0x0f
+
+static void port_setup(struct ksz_device *dev, int port, bool cpu_port)
+{
+	printk("Port setup %d, %d\n", port, cpu_port);
+
+	if (cpu_port && port != 4)
+		printk("!!! tail tagging only works on port 5\n");
+	if (cpu_port) {
+		printk("enable tail tagging\n");
+		ksz_cfg(dev, S_TAIL_TAG_CTRL, SW_TAIL_TAG_ENABLE, true);
+	}
+
+	ksz_port_cfg(dev, port, REG_PORT_CTRL_LOOPBACK, PORT_MAC_LOOPBACK_my, false);
+#ifdef FIXME
+	/* set back pressure */
+	ksz_port_cfg(dev, port, REG_PORT_MAC_CTRL_1, PORT_BACK_PRESSURE, true);
+
+	/* set flow control */
+	ksz_port_cfg(dev, port, REG_PORT_CTRL_0,
+		     PORT_FORCE_TX_FLOW_CTRL | PORT_FORCE_RX_FLOW_CTRL, true);
+
+	/* enable broadcast storm limit */
+	ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true);
+
+	/* disable DiffServ priority */
+	ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_DIFFSERV_PRIO_ENABLE, false);
+
+	/* replace priority */
+	ksz_port_cfg(dev, port, REG_PORT_MRI_MAC_CTRL, PORT_USER_PRIO_CEILING,
+		     false);
+	ksz_port_cfg32(dev, port, REG_PORT_MTI_QUEUE_CTRL_0__4,
+		       MTI_PVID_REPLACE, false);
+
+	/* enable 802.1p priority */
+	ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_PRIO_ENABLE, true);
+
+	/* configure MAC to 1G & RGMII mode */
+	ksz_pread8(dev, port, REG_PORT_XMII_CTRL_1, &data8);
+	data8 |= PORT_RGMII_ID_EG_ENABLE;
+	data8 &= ~PORT_MII_NOT_1GBIT;
+	data8 &= ~PORT_MII_SEL_M;
+	data8 |= PORT_RGMII_SEL;
+	ksz_pwrite8(dev, port, REG_PORT_XMII_CTRL_1, data8);
+
+	/* clear pending interrupts */
+	ksz_pread16(dev, port, REG_PORT_PHY_INT_ENABLE, &data16);
+#endif
+}
+
+static void ksz_config_cpu_port(struct dsa_switch *ds)
+{
+	struct ksz_device *dev = ds->priv;
+	int i;
+
+	ds->num_ports = dev->port_cnt;
+
+	for (i = 0; i < ds->num_ports; i++) {
+		if (dsa_is_cpu_port(ds, i) && (dev->cpu_ports & (1 << i))) {
+			dev->cpu_port = i;
+
+			/* enable cpu port */
+			port_setup(dev, i, true);
+		}
+	}
+}
+
+#if 0
+/*
+ * sw_init_vlan - initialize switch VLAN
+ *
+ * Everyone can communicate with CPU, ports do not communicate with each other
+ */
+static void sw_init_vlan(struct ksz_device *dev)
+{
+	int port;
+	
+	for (port = 0; port < dev->port_cnt; port++) {
+		//port_get_def_vid(sw, port, &info->port_cfg[port].vid);
+		//port_r(sw, port, P_MIRROR_CTRL, &data);
+
+		ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_VLAN_MEMBERSHIP, false);
+		ksz_port_cfg(dev, port, P_MIRROR_CTRL, 1<<port, true);		
+#if 0
+		port_cfg(sw, port, P_INS_SRC_PVID_CTRL,
+			(PORT_INS_TAG_FOR_PORT_5 | PORT_INS_TAG_FOR_PORT_4 |
+			PORT_INS_TAG_FOR_PORT_3 | PORT_INS_TAG_FOR_PORT_2),
+			true);
+#endif
+	}
+	ksz_port_cfg(dev, dev->port_cnt-1, P_MIRROR_CTRL, PORT_VLAN_MEMBERSHIP, true);
+}
+
+static void sw_init_bridge(struct ksz_device *dev)
+{
+	int port;
+
+	for (port = 0; port < dev->port_cnt; port++) {
+		ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_VLAN_MEMBERSHIP, true);
+	}
+}
+#endif
+
+static void br_update(struct dsa_switch *ds)
+{
+	struct ksz_device *dev = ds->priv;
+	int i,j;
+	int mask[5];
+	u8 val;
+
+	for (i = 0; i < dev->port_cnt; i++) {
+		mask[i] = 0;
+	}
+
+	for (i = 0; i < dev->port_cnt; i++) {
+		for (j = 0; j < dev->port_cnt; j++) {
+			//printk("port %d bridge %lx\n", i, (unsigned long) ds->ports[i].bridge_dev);
+			if (ds->ports[i].bridge_dev &&
+			    (ds->ports[i].bridge_dev == ds->ports[j].bridge_dev))
+				mask[i] |= 1<<j;
+		}
+	}
+
+	for (i = 0; i < dev->port_cnt-1; i++) {
+		printk("port %d mask %x\n", i, mask[i]);
+		ksz_pread8(dev, i, P_MIRROR_CTRL, &val);
+		val &= ~PORT_VLAN_MEMBERSHIP;
+		val |= mask[i] | 0x10 | (1 << i);
+		ksz_pwrite8(dev, i, P_MIRROR_CTRL, val);
+	}
+
+	ksz_pread8(dev, dev->port_cnt-1, P_MIRROR_CTRL, &val);
+	val &= ~PORT_VLAN_MEMBERSHIP;
+	val |= mask[i] | 0x1f;
+	ksz_pwrite8(dev, dev->port_cnt-1, P_MIRROR_CTRL, val);
+
+}
+
+
+/* bridge_change -- need to get it here */
+
+int ksz_br_join(struct dsa_switch *ds, int port, struct net_device *br)
+{
+	struct ksz_device *dev = ds->priv;
+
+	br_update(ds);
+	return 0;
+}
+
+void ksz_br_leave(struct dsa_switch *ds, int port, struct net_device *br)
+{
+	struct ksz_device *dev = ds->priv;
+
+//	sw_init_vlan(dev);
+	
+	br_update(ds);
+}
+
+
+
+static int ksz_setup(struct dsa_switch *ds)
+{
+	struct ksz_device *dev = ds->priv;
+	int ret = 0;
+
+	dev->vlan_cache = devm_kcalloc(dev->dev, sizeof(struct vlan_table),
+				       dev->num_vlans, GFP_KERNEL);
+	if (!dev->vlan_cache)
+		return -ENOMEM;
+
+	ret = ksz_reset_switch(ds);
+	if (ret) {
+		dev_err(ds->dev, "failed to reset switch\n");
+		return ret;
+	}
+
+	/* accept packet up to 2000bytes */
+	//ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_LEGAL_PACKET_DISABLE, true);
+
+	ksz_config_cpu_port(ds);
+
+	ksz_cfg(dev, REG_SW_CTRL_2, MULTICAST_STORM_DISABLE, true);
+
+	/* queue based egress rate limit */
+	//ksz_cfg(dev, REG_SW_MAC_CTRL_5, SW_OUT_RATE_LIMIT_QUEUE_BASED, true);
+
+	//sw_init_broad_storm(sw);
+        //sw_init_prio(sw);
+        //sw_init_prio_rate(sw);
+	//sw_init_vlan(ds); FIXME!!!
+
+	/* start switch */
+	ksz_cfg(dev, REG_CHIP_ID1, SW_START, true);
+
+	return 0;
+}
+
+static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds)
+{
+	return DSA_TAG_PROTO_KSZ;
+}
+
+#include "ksz_mdio_emulation.c"
+
+static int ksz_enable_port(struct dsa_switch *ds, int port,
+			   struct phy_device *phy)
+{
+	struct ksz_device *dev = ds->priv;
+
+	/* setup slave port */
+	port_setup(dev, port, false);
+
+	return 0;
+}
+
+
+static void ksz_disable_port(struct dsa_switch *ds, int port,
+			     struct phy_device *phy)
+{
+	struct ksz_device *dev = ds->priv;
+
+	/* there is no port disable */
+	ksz_port_cfg(dev, port, REG_PORT_CTRL_LOOPBACK, PORT_MAC_LOOPBACK_my, true);
+}
+
+static int ksz_sset_count(struct dsa_switch *ds)
+{
+	return TOTAL_SWITCH_COUNTER_NUM;
+}
+
+static void ksz_get_strings(struct dsa_switch *ds, int port, uint8_t *buf)
+{
+	int i;
+
+	for (i = 0; i < TOTAL_SWITCH_COUNTER_NUM; i++) {
+		memcpy(buf + i * ETH_GSTRING_LEN, mib_names[i].string,
+		       ETH_GSTRING_LEN);
+	}
+}
+
+static void ksz_get_ethtool_stats(struct dsa_switch *ds, int port,
+				  uint64_t *buf)
+{
+	NOTIMPLV();
+}
+
+#if 0
+static void ksz_dump(struct ksz_device *dev)
+{
+	int i;
+	u8 v;
+
+	printk("ksz: dumping:\n");
+	for (i = 0; i < 0x100; i++) {
+		if (!(i % 0x10))
+			printk("\n %x: ", i);
+		ksz_read8(dev, i, &v);
+		printk("%02x ", v);
+	}
+	printk("\nksz: dump done\n");
+}
+#endif
+
+static void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+{
+	struct ksz_device *dev = ds->priv;
+	u8 data;
+
+	printk("port %d state %d\n", port, state);
+	ksz_pread8(dev, port, P_STP_CTRL, &data);
+	data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);
+
+	switch (state) {
+	case BR_STATE_DISABLED:
+		printk("port %d state %d disable\n", port, state);				
+		data |= PORT_LEARN_DISABLE;
+		break;
+	case BR_STATE_LISTENING:
+		printk("port %d state %d listen\n", port, state);
+		data |= (PORT_RX_ENABLE | PORT_LEARN_DISABLE);
+		break;
+	case BR_STATE_LEARNING:
+		printk("port %d state %d learn\n", port, state);
+		data |= PORT_RX_ENABLE;
+		break;
+	case BR_STATE_FORWARDING:
+		printk("port %d state %d forwarding\n", port, state);		
+		data |= (PORT_TX_ENABLE | PORT_RX_ENABLE);
+		break;
+	case BR_STATE_BLOCKING:
+		printk("port %d state %d blocking\n", port, state);
+		data |= PORT_LEARN_DISABLE;
+		break;
+	default:
+		dev_err(ds->dev, "invalid STP state: %d\n", state);
+		return;
+	}
+	/* FIXME: great great hack */
+	data |= (PORT_RX_ENABLE | PORT_TX_ENABLE);
+	
+
+	ksz_pwrite8(dev, port, P_STP_CTRL, data);
+	//ksz_dump(dev);
+}
+
+static void ksz_port_fast_age(struct dsa_switch *ds, int port)
+{
+	NOTIMPLV();
+	
+}
+
+static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag)
+{
+	NOTIMPL();
+	return 0;
+}
+
+static int ksz_port_vlan_prepare(struct dsa_switch *ds, int port,
+				 const struct switchdev_obj_port_vlan *vlan,
+				 struct switchdev_trans *trans)
+{
+	/* nothing needed */
+
+	return 0;
+}
+
+static void ksz_port_vlan_add(struct dsa_switch *ds, int port,
+			      const struct switchdev_obj_port_vlan *vlan,
+			      struct switchdev_trans *trans)
+{
+	NOTIMPLV();
+}
+
+static int ksz_port_vlan_del(struct dsa_switch *ds, int port,
+			     const struct switchdev_obj_port_vlan *vlan)
+{
+	NOTIMPL();
+
+	return 0;
+}
+
+static int ksz_port_vlan_dump(struct dsa_switch *ds, int port,
+			      struct switchdev_obj_port_vlan *vlan,
+			      switchdev_obj_dump_cb_t *cb)
+{
+	NOTIMPL();
+}
+
+static int ksz_port_fdb_prepare(struct dsa_switch *ds, int port,
+				const struct switchdev_obj_port_fdb *fdb,
+				struct switchdev_trans *trans)
+{
+	/* nothing needed */
+
+	return 0;
+}
+
+struct alu_struct {
+	/* entry 1 */
+	u8	is_static:1;
+	u8	is_src_filter:1;
+	u8	is_dst_filter:1;
+	u8	prio_age:3;
+	u32	_reserv_0_1:23;
+	u8	mstp:3;
+	/* entry 2 */
+	u8	is_override:1;
+	u8	is_use_fid:1;
+	u32	_reserv_1_1:23;
+	u8	port_forward:7;
+	/* entry 3 & 4*/
+	u32	_reserv_2_1:9;
+	u8	fid:7;
+	u8	mac[ETH_ALEN];
+};
+
+static void ksz_port_fdb_add(struct dsa_switch *ds, int port,
+			     const struct switchdev_obj_port_fdb *fdb,
+			     struct switchdev_trans *trans)
+{
+	NOTIMPLV();
+}
+
+static int ksz_port_fdb_del(struct dsa_switch *ds, int port,
+			    const struct switchdev_obj_port_fdb *fdb)
+{
+	NOTIMPL();
+}
+
+static int ksz_port_fdb_dump(struct dsa_switch *ds, int port,
+			     struct switchdev_obj_port_fdb *fdb,
+			     switchdev_obj_dump_cb_t *cb)
+{
+	NOTIMPL();
+}
+
+static int ksz_port_mdb_prepare(struct dsa_switch *ds, int port,
+				const struct switchdev_obj_port_mdb *mdb,
+				struct switchdev_trans *trans)
+{
+	/* nothing to do */
+	return 0;
+}
+
+static void ksz_port_mdb_add(struct dsa_switch *ds, int port,
+			     const struct switchdev_obj_port_mdb *mdb,
+			     struct switchdev_trans *trans)
+{
+	NOTIMPLV();
+}
+
+static int ksz_port_mdb_del(struct dsa_switch *ds, int port,
+			    const struct switchdev_obj_port_mdb *mdb)
+{
+	NOTIMPL();
+}
+
+static int ksz_port_mdb_dump(struct dsa_switch *ds, int port,
+			     struct switchdev_obj_port_mdb *mdb,
+			     switchdev_obj_dump_cb_t *cb)
+{
+	/* this is not called by switch layer */
+	return 0;
+}
+
+static int ksz_port_mirror_add(struct dsa_switch *ds, int port,
+			       struct dsa_mall_mirror_tc_entry *mirror,
+			       bool ingress)
+{
+	NOTIMPL();
+
+}
+
+static void ksz_port_mirror_del(struct dsa_switch *ds, int port,
+				struct dsa_mall_mirror_tc_entry *mirror)
+{
+	NOTIMPLV();
+}
+
+static const struct dsa_switch_ops ksz_switch_ops = {
+	.get_tag_protocol	= ksz_get_tag_protocol,
+	.setup			= ksz_setup,
+	.phy_read		= ksz_phy_read16,
+	.phy_write		= ksz_phy_write16,
+	.port_enable		= ksz_enable_port,
+	.port_disable		= ksz_disable_port,
+	.get_strings		= ksz_get_strings,
+	.get_ethtool_stats	= ksz_get_ethtool_stats,
+	.get_sset_count		= ksz_sset_count,
+	.port_bridge_join	= ksz_br_join,
+	.port_bridge_leave	= ksz_br_leave,
+	.port_stp_state_set	= ksz_port_stp_state_set,
+	.port_fast_age		= ksz_port_fast_age,
+	.port_vlan_filtering	= ksz_port_vlan_filtering,
+	.port_vlan_prepare	= ksz_port_vlan_prepare,
+	.port_vlan_add		= ksz_port_vlan_add,
+	.port_vlan_del		= ksz_port_vlan_del,
+	.port_vlan_dump		= ksz_port_vlan_dump,
+	.port_fdb_prepare	= ksz_port_fdb_prepare,
+	.port_fdb_dump		= ksz_port_fdb_dump,
+	.port_fdb_add		= ksz_port_fdb_add,
+	.port_fdb_del		= ksz_port_fdb_del,
+	.port_mdb_prepare       = ksz_port_mdb_prepare,
+	.port_mdb_add           = ksz_port_mdb_add,
+	.port_mdb_del           = ksz_port_mdb_del,
+	.port_mdb_dump          = ksz_port_mdb_dump,
+	.port_mirror_add	= ksz_port_mirror_add,
+	.port_mirror_del	= ksz_port_mirror_del,
+};
+
+struct ksz_chip_data {
+	u32 chip_id;
+	const char *dev_name;
+	int num_vlans;
+	int num_alus;
+	int num_statics;
+	int cpu_ports;
+	int port_cnt;
+};
+
+static const struct ksz_chip_data ksz_switch_chips[] = {
+	{
+		.chip_id = 0x95600c04,
+		.dev_name = "KSZ8895",
+		.num_vlans = 4096, /* FIXME ? */
+		.num_alus = 4096,
+		.num_statics = 16,
+		.cpu_ports = 0x10,	/* can be configured as cpu port */
+		.port_cnt = 5,		/* total physical port count */
+	},
+};
+
+static int ksz_switch_init(struct ksz_device *dev)
+{
+	int i;
+
+	mutex_init(&dev->reg_mutex);
+	mutex_init(&dev->stats_mutex);
+	mutex_init(&dev->alu_mutex);
+	mutex_init(&dev->vlan_mutex);
+
+	dev->ds->ops = &ksz_switch_ops;
+
+	for (i = 0; i < ARRAY_SIZE(ksz_switch_chips); i++) {
+		const struct ksz_chip_data *chip = &ksz_switch_chips[i];
+
+		if (dev->chip_id == chip->chip_id) {
+			dev->name = chip->dev_name;
+			dev->num_vlans = chip->num_vlans;
+			dev->num_alus = chip->num_alus;
+			dev->num_statics = chip->num_statics;
+			dev->port_cnt = chip->port_cnt;
+			dev->cpu_ports = chip->cpu_ports;
+
+			break;
+		}
+	}
+	
+	printk("ksz_switch_init: detected %s\n", dev->name);
+
+	/* no switch found */
+	if (!dev->port_cnt)
+		return -ENODEV;
+
+	return 0;
+}
+
+struct ksz_device *ksz_switch_alloc(struct device *base,
+				    const struct ksz_io_ops *ops,
+				    void *priv)
+{
+	struct dsa_switch *ds;
+	struct ksz_device *swdev;
+
+	ds = dsa_switch_alloc(base, DSA_MAX_PORTS);
+	if (!ds)
+		return NULL;
+
+	swdev = devm_kzalloc(base, sizeof(*swdev), GFP_KERNEL);
+	if (!swdev)
+		return NULL;
+
+	ds->priv = swdev;
+	swdev->dev = base;
+
+	swdev->ds = ds;
+	swdev->priv = priv;
+	swdev->ops = ops;
+
+	return swdev;
+}
+EXPORT_SYMBOL(ksz_switch_alloc);
+
+int ksz_switch_detect(struct ksz_device *dev)
+{
+	u8 data8;
+	u32 id32;
+	int ret;
+
+	/* read chip id */
+	ret = ksz_read32(dev, REG_CHIP_ID0__1, &id32);
+	if (ret)
+		return ret;
+	
+	ret = ksz_read8(dev, 0, &data8);
+	ret = ksz_read8(dev, 1, &data8);
+	ret = ksz_read8(dev, 2, &data8);
+	ret = ksz_read8(dev, 3, &data8);
+	
+	dev->chip_id = id32;
+
+	return 0;
+}
+EXPORT_SYMBOL(ksz_switch_detect);
+
+int ksz_switch_register(struct ksz_device *dev)
+{
+	int ret;
+
+	if (dev->pdata)
+		dev->chip_id = dev->pdata->chip_id;
+
+	if (ksz_switch_detect(dev))
+		return -EINVAL;
+
+	ret = ksz_switch_init(dev);
+	if (ret)
+		return ret;
+
+
+	return dsa_register_switch(dev->ds);
+}
+EXPORT_SYMBOL(ksz_switch_register);
+
+void ksz_switch_remove(struct ksz_device *dev)
+{
+	dsa_unregister_switch(dev->ds);
+}
+EXPORT_SYMBOL(ksz_switch_remove);
+
+MODULE_AUTHOR("Woojung Huh <Woojung.Huh@microchip.com>");
+MODULE_DESCRIPTION("Microchip KSZ Series Switch DSA Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/microchip/ksz_8895_reg.h b/drivers/net/dsa/microchip/ksz_8895_reg.h
new file mode 100644
index 000000000000..b6490c42448e
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz_8895_reg.h
@@ -0,0 +1,769 @@
+/*
+ * Microchip KSZ9477 register definitions
+ *
+ * Copyright (C) 2017
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __KSZ9477_REGS_H
+#define __KSZ9477_REGS_H
+
+#define KS_PRIO_M			0x3
+#define KS_PRIO_S			2
+
+/* 0 - Operation */
+#define REG_CHIP_ID0__1			0x0000
+
+#define REG_CHIP_ID1__1			0x0001
+
+#define SW_START 1
+
+#define FAMILY_ID			0x95
+#define FAMILY_ID_94			0x94
+#define FAMILY_ID_95			0x95
+#define FAMILY_ID_85			0x85
+#define FAMILY_ID_98			0x98
+#define FAMILY_ID_88			0x88
+
+#define TOTAL_SWITCH_COUNTER_NUM	1
+#define PORT_CTRL_ADDR(port, addr)	((addr) | (((port) + 1) << 4))
+
+#define ADDR_SHIFT			14
+#define ADDR_8				1
+#define ADDR_16				2
+#define ADDR_24				3
+#define ADDR_32				4
+
+#define BANK_SHIFT			12
+
+#define PHY_REG(addr, reg)		\
+	(((addr) << ADDR_SHIFT) | (reg))
+
+#define PHY_BANK_REG(addr, bank, reg)	\
+	(((addr) << ADDR_SHIFT) | ((bank) << BANK_SHIFT) | (reg))
+
+/* Use PHY access if no direct access. */
+#ifndef SW_R8
+#define SW_R8(s, r)	phy_read(s->phydev, PHY_REG(ADDR_8, r))
+#define SW_W8(s, r, v)	phy_write(s->phydev, PHY_REG(ADDR_8, r), v)
+#define SW_R16(s, r)	phy_read(s->phydev, PHY_REG(ADDR_16, r))
+#define SW_W16(s, r, v)	phy_write(s->phydev, PHY_REG(ADDR_16, r), v)
+#define SW_R32(s, r)	phy_read(s->phydev, PHY_REG(ADDR_32, r))
+#define SW_W32(s, r, v) \
+	do { \
+		phy_write(s->phydev, PHY_REG(ADDR_32, (r) + 2), (v) >> 16); \
+		phy_write(s->phydev, PHY_REG(ADDR_32, r), v); \
+	} while (0)
+#define SW_LOCK(s)				\
+	do {					\
+		mutex_lock(s->hwlock);		\
+	} while (0)
+#define SW_UNLOCK(s)				\
+	do {					\
+		mutex_unlock(s->hwlock);	\
+	} while (0)
+#endif
+
+
+#define KS_PORT_M			0x1F
+
+#define REG_CHIP_ID0			0x00
+
+#define FAMILY_ID			0x95
+
+#define REG_CHIP_ID1			0x01
+
+#define SW_CHIP_ID_M			0xF0
+#define SW_CHIP_ID_S			4
+#define SW_REVISION_M			0x0E
+#define SW_REVISION_S			1
+
+#define CHIP_ID_95			0x40
+#define CHIP_ID_95R			0x60
+
+#define REG_SW_CTRL_0			0x02
+
+#define SW_NEW_BACKOFF			(1 << 7)
+#define SW_FLUSH_DYN_MAC_TABLE		(1 << 5)
+#define SW_FLUSH_STA_MAC_TABLE		(1 << 4)
+#define SW_UNH_MODE			(1 << 1)
+#define SW_LINK_AUTO_AGING		(1 << 0)
+
+#define REG_SW_CTRL_1			0x03
+
+#define SW_PASS_ALL			(1 << 7)
+#define SW_2K_PACKET			(1 << 6)
+#define SW_TX_FLOW_CTRL_DISABLE		(1 << 5)
+#define SW_RX_FLOW_CTRL_DISABLE		(1 << 4)
+#define SW_CHECK_LENGTH			(1 << 3)
+#define SW_AGING_ENABLE			(1 << 2)
+#define SW_FAST_AGING			(1 << 1)
+#define SW_AGGR_BACKOFF			(1 << 0)
+
+#define REG_SW_CTRL_2			0x04
+
+#define UNICAST_VLAN_BOUNDARY		(1 << 7)
+#define MULTICAST_STORM_DISABLE		(1 << 6)
+#define SW_BACK_PRESSURE		(1 << 5)
+#define FAIR_FLOW_CTRL			(1 << 4)
+#define NO_EXC_COLLISION_DROP		(1 << 3)
+#define SW_HUGE_PACKET			(1 << 2)
+#define SW_LEGAL_PACKET			(1 << 1)
+
+#define REG_SW_CTRL_3			0x05
+#define SW_VLAN_ENABLE			(1 << 7)
+#define SW_IGMP_SNOOP			(1 << 6)
+#define SW_DIRECT			(1 << 5)
+#define SW_PRE_TAG			(1 << 4)
+#define SW_VLAN_TAG			(1 << 1)
+#define SW_MIRROR_RX_TX			(1 << 0)
+
+#define REG_SW_CTRL_4			0x06
+
+#define SW_HALF_DUPLEX_FLOW_CTRL	(1 << 7)
+#define SW_HALF_DUPLEX			(1 << 6)
+#define SW_FLOW_CTRL			(1 << 5)
+#define SW_10_MBIT			(1 << 4)
+#define SW_REPLACE_VID			(1 << 3)
+#define BROADCAST_STORM_RATE_HI		0x07
+
+#define REG_SW_CTRL_5			0x07
+
+#define BROADCAST_STORM_RATE_LO		0xFF
+#define BROADCAST_STORM_RATE		0x07FF
+
+#define REG_SW_CTRL_9			0x0B
+
+#define SW_DATA_SAMPLING_NEG		(1 << 6)
+#define SW_PHY_POWER_SAVE_DISABLE	(1 << 3)
+#define SW_LED_MODE_1			(1 << 1)
+#define SW_SPI_SAMPLING_RISING		(1 << 0)
+
+#define REG_SW_CTRL_10			0x0C
+
+#define SPI_CLK_125_MHZ			0x20
+#define SPI_CLK_83_33_MHZ		0x10
+#define SPI_CLK_41_67_MHZ		0x00
+#define SW_TAIL_TAG_ENABLE		(1 << 1)
+#define SW_PASS_PAUSE			(1 << 0)
+
+#define REG_SW_CTRL_11			0x0D
+
+#define REG_POWER_MANAGEMENT_1		0x0E
+
+#define SW_PLL_POWER_DOWN		(1 << 5)
+#define SW_POWER_MANAGEMENT_MODE_M	0x3
+#define SW_POWER_MANAGEMENT_MODE_S	3
+#define SW_POWER_NORMAL			0
+#define SW_ENERGY_DETECTION		1
+#define SW_SOFTWARE_POWER_DOWN		2
+#define SW_POWER_SAVING			3
+
+#define REG_POWER_MANAGEMENT_2		0x0F
+
+
+#define REG_PORT_1_CTRL_0		0x10
+#define REG_PORT_2_CTRL_0		0x20
+#define REG_PORT_3_CTRL_0		0x30
+#define REG_PORT_4_CTRL_0		0x40
+#define REG_PORT_5_CTRL_0		0x50
+
+#define PORT_BROADCAST_STORM		(1 << 7)
+#define PORT_DIFFSERV_ENABLE		(1 << 6)
+#define PORT_802_1P_ENABLE		(1 << 5)
+#define PORT_BASED_PRIO_S		3
+#define PORT_BASED_PRIO_M		(KS_PRIO_M << PORT_BASED_PRIO_S)
+#define PORT_PORT_PRIO_0		0
+#define PORT_PORT_PRIO_1		1
+#define PORT_PORT_PRIO_2		2
+#define PORT_PORT_PRIO_3		3
+#define PORT_INSERT_TAG			(1 << 2)
+#define PORT_REMOVE_TAG			(1 << 1)
+#define PORT_QUEUE_SPLIT_L		(1 << 0)
+
+#define REG_PORT_1_CTRL_1		0x11
+#define REG_PORT_2_CTRL_1		0x21
+#define REG_PORT_3_CTRL_1		0x31
+#define REG_PORT_4_CTRL_1		0x41
+#define REG_PORT_5_CTRL_1		0x51
+
+#define PORT_MIRROR_SNIFFER		(1 << 7)
+#define PORT_MIRROR_RX			(1 << 6)
+#define PORT_MIRROR_TX			(1 << 5)
+#define PORT_VLAN_MEMBERSHIP		KS_PORT_M
+
+#define REG_PORT_1_CTRL_2		0x12
+#define REG_PORT_2_CTRL_2		0x22
+#define REG_PORT_3_CTRL_2		0x32
+#define REG_PORT_4_CTRL_2		0x42
+#define REG_PORT_5_CTRL_2		0x52
+
+#define PORT_802_1P_REMAPPING		(1 << 7)
+#define PORT_INGRESS_FILTER		(1 << 6)
+#define PORT_DISCARD_NON_VID		(1 << 5)
+#define PORT_FORCE_FLOW_CTRL		(1 << 4)
+#define PORT_BACK_PRESSURE		(1 << 3)
+#define PORT_TX_ENABLE			(1 << 2)
+#define PORT_RX_ENABLE			(1 << 1)
+#define PORT_LEARN_DISABLE		(1 << 0)
+
+#define REG_PORT_1_CTRL_3		0x13
+#define REG_PORT_2_CTRL_3		0x23
+#define REG_PORT_3_CTRL_3		0x33
+#define REG_PORT_4_CTRL_3		0x43
+#define REG_PORT_5_CTRL_3		0x53
+#define REG_PORT_1_CTRL_4		0x14
+#define REG_PORT_2_CTRL_4		0x24
+#define REG_PORT_3_CTRL_4		0x34
+#define REG_PORT_4_CTRL_4		0x44
+#define REG_PORT_5_CTRL_4		0x54
+
+#define PORT_DEFAULT_VID		0x0001
+
+#define REG_PORT_1_STATUS_0		0x19
+#define REG_PORT_2_STATUS_0		0x29
+#define REG_PORT_3_STATUS_0		0x39
+#define REG_PORT_4_STATUS_0		0x49
+#define REG_PORT_5_STATUS_0		0x59
+
+#define PORT_HP_MDIX			(1 << 7)
+#define PORT_REVERSED_POLARITY		(1 << 5)
+#define PORT_TX_FLOW_CTRL		(1 << 4)
+#define PORT_RX_FLOW_CTRL		(1 << 3)
+#define PORT_STAT_SPEED_100MBIT		(1 << 2)
+#define PORT_STAT_FULL_DUPLEX		(1 << 1)
+
+#define REG_PORT_1_LINK_MD_CTRL		0x1A
+#define REG_PORT_2_LINK_MD_CTRL		0x2A
+#define REG_PORT_3_LINK_MD_CTRL		0x3A
+#define REG_PORT_4_LINK_MD_CTRL		0x4A
+#define REG_PORT_5_LINK_MD_CTRL		0x5A
+
+#define PORT_CABLE_10M_SHORT		(1 << 7)
+#define PORT_CABLE_DIAG_RESULT_M	0x3
+#define PORT_CABLE_DIAG_RESULT_S	5
+#define PORT_CABLE_STAT_NORMAL		0
+#define PORT_CABLE_STAT_OPEN		1
+#define PORT_CABLE_STAT_SHORT		2
+#define PORT_CABLE_STAT_FAILED		3
+#define PORT_START_CABLE_DIAG		(1 << 4)
+#define PORT_FORCE_LINK			(1 << 3)
+#define PORT_POWER_SAVING		(1 << 2)
+#define PORT_PHY_REMOTE_LOOPBACK	(1 << 1)
+#define PORT_CABLE_FAULT_COUNTER_H	0x01
+
+#define REG_PORT_1_LINK_MD_RESULT	0x1B
+#define REG_PORT_2_LINK_MD_RESULT	0x2B
+#define REG_PORT_3_LINK_MD_RESULT	0x3B
+#define REG_PORT_4_LINK_MD_RESULT	0x4B
+#define REG_PORT_5_LINK_MD_RESULT	0x5B
+
+#define PORT_CABLE_FAULT_COUNTER_L	0xFF
+#define PORT_CABLE_FAULT_COUNTER	0x1FF
+
+#define REG_PORT_1_CTRL_5		0x1C
+#define REG_PORT_2_CTRL_5		0x2C
+#define REG_PORT_3_CTRL_5		0x3C
+#define REG_PORT_4_CTRL_5		0x4C
+#define REG_PORT_5_CTRL_5		0x5C
+
+#define PORT_AUTO_NEG_DISABLE		(1 << 7)
+#define PORT_FORCE_100_MBIT		(1 << 6)
+#define PORT_FORCE_FULL_DUPLEX		(1 << 5)
+#define PORT_AUTO_NEG_SYM_PAUSE		(1 << 4)
+#define PORT_AUTO_NEG_100BTX_FD		(1 << 3)
+#define PORT_AUTO_NEG_100BTX		(1 << 2)
+#define PORT_AUTO_NEG_10BT_FD		(1 << 1)
+#define PORT_AUTO_NEG_10BT		(1 << 0)
+
+#define REG_PORT_1_CTRL_6		0x1D
+#define REG_PORT_2_CTRL_6		0x2D
+#define REG_PORT_3_CTRL_6		0x3D
+#define REG_PORT_4_CTRL_6		0x4D
+#define REG_PORT_5_CTRL_6		0x5D
+
+#define PORT_LED_OFF			(1 << 7)
+#define PORT_TX_DISABLE			(1 << 6)
+#define PORT_AUTO_NEG_RESTART		(1 << 5)
+#define PORT_POWER_DOWN			(1 << 3)
+#define PORT_AUTO_MDIX_DISABLE		(1 << 2)
+#define PORT_FORCE_MDIX			(1 << 1)
+#define PORT_MAC_LOOPBACK		(1 << 0)
+
+#define REG_PORT_1_STATUS_1		0x1E
+#define REG_PORT_2_STATUS_1		0x2E
+#define REG_PORT_3_STATUS_1		0x3E
+#define REG_PORT_4_STATUS_1		0x4E
+#define REG_PORT_5_STATUS_1		0x5E
+
+#define PORT_MDIX_STATUS		(1 << 7)
+#define PORT_AUTO_NEG_COMPLETE		(1 << 6)
+#define PORT_STAT_LINK_GOOD		(1 << 5)
+#define PORT_REMOTE_SYM_PAUSE		(1 << 4)
+#define PORT_REMOTE_100BTX_FD		(1 << 3)
+#define PORT_REMOTE_100BTX		(1 << 2)
+#define PORT_REMOTE_10BT_FD		(1 << 1)
+#define PORT_REMOTE_10BT		(1 << 0)
+
+#define REG_PORT_1_STATUS_2		0x1F
+#define REG_PORT_2_STATUS_2		0x2F
+#define REG_PORT_3_STATUS_2		0x3F
+#define REG_PORT_4_STATUS_2		0x4F
+#define REG_PORT_5_STATUS_2		0x5F
+
+#define PORT_PHY_LOOPBACK		(1 << 7)
+#define PORT_PHY_ISOLATE		(1 << 5)
+#define PORT_PHY_SOFT_RESET		(1 << 4)
+#define PORT_PHY_FORCE_LINK		(1 << 3)
+#define PORT_PHY_MODE_M			0x7
+#define PHY_MODE_IN_AUTO_NEG		1
+#define PHY_MODE_10BT_HALF		2
+#define PHY_MODE_100BT_HALF		3
+#define PHY_MODE_10BT_FULL		5
+#define PHY_MODE_100BT_FULL		6
+#define PHY_MODE_ISOLDATE		7
+
+#define REG_PORT_CTRL_0			0x00
+#define REG_PORT_CTRL_1			0x01
+#define REG_PORT_CTRL_2			0x02
+#define REG_PORT_CTRL_VID		0x03
+
+#define REG_PORT_STATUS_0		0x09
+#define REG_PORT_LINK_MD_CTRL		0x0A
+#define REG_PORT_LINK_MD_RESULT		0x0B
+#define REG_PORT_CTRL_5			0x0C
+#define REG_PORT_CTRL_6			0x0D
+#define REG_PORT_STATUS_1		0x0E
+#define REG_PORT_STATUS_2		0x0F
+
+#define REG_PORT_CTRL_8			0xA0
+#define REG_PORT_CTRL_9			0xA1
+#define REG_PORT_RATE_CTRL_3		0xA2
+#define REG_PORT_RATE_CTRL_2		0xA3
+#define REG_PORT_RATE_CTRL_1		0xA4
+#define REG_PORT_RATE_CTRL_0		0xA5
+#define REG_PORT_RATE_LIMIT		0xA6
+#define REG_PORT_IN_RATE_0		0xA7
+#define REG_PORT_IN_RATE_1		0xA8
+#define REG_PORT_IN_RATE_2		0xA9
+#define REG_PORT_IN_RATE_3		0xAA
+#define REG_PORT_OUT_RATE_0		0xAB
+#define REG_PORT_OUT_RATE_1		0xAC
+#define REG_PORT_OUT_RATE_2		0xAD
+#define REG_PORT_OUT_RATE_3		0xAE
+
+#define REG_SW_MAC_ADDR_0		0x68
+#define REG_SW_MAC_ADDR_1		0x69
+#define REG_SW_MAC_ADDR_2		0x6A
+#define REG_SW_MAC_ADDR_3		0x6B
+#define REG_SW_MAC_ADDR_4		0x6C
+#define REG_SW_MAC_ADDR_5		0x6D
+
+#define REG_IND_CTRL_0			0x6E
+
+#define TABLE_READ			(1 << 4)
+#define TABLE_SELECT_S			2
+#define TABLE_STATIC_MAC		(0 << TABLE_SELECT_S)
+#define TABLE_VLAN			(1 << TABLE_SELECT_S)
+#define TABLE_DYNAMIC_MAC		(2 << TABLE_SELECT_S)
+#define TABLE_MIB			(3 << TABLE_SELECT_S)
+
+#define REG_IND_CTRL_1			0x6F
+
+#define TABLE_ENTRY_MASK		0x03FF
+
+#define REG_IND_DATA_8			0x70
+#define REG_IND_DATA_7			0x71
+#define REG_IND_DATA_6			0x72
+#define REG_IND_DATA_5			0x73
+#define REG_IND_DATA_4			0x74
+#define REG_IND_DATA_3			0x75
+#define REG_IND_DATA_2			0x76
+#define REG_IND_DATA_1			0x77
+#define REG_IND_DATA_0			0x78
+
+#define REG_IND_DATA_CHECK		REG_IND_DATA_6
+#define REG_IND_MIB_CHECK		REG_IND_DATA_3
+#define REG_IND_DATA_HI			REG_IND_DATA_7
+#define REG_IND_DATA_LO			REG_IND_DATA_3
+
+#define REG_INT_STATUS			0x7C
+#define REG_INT_ENABLE			0x7D
+
+#define INT_PORT_5			(1 << 4)
+#define INT_PORT_4			(1 << 3)
+#define INT_PORT_3			(1 << 2)
+#define INT_PORT_2			(1 << 1)
+#define INT_PORT_1			(1 << 0)
+
+#define REG_SW_CTRL_12			0x80
+#define REG_SW_CTRL_13			0x81
+
+#define SWITCH_802_1P_MASK		3
+#define SWITCH_802_1P_BASE		3
+#define SWITCH_802_1P_SHIFT		2
+
+#define SW_802_1P_MAP_M			KS_PRIO_M
+#define SW_802_1P_MAP_S			KS_PRIO_S
+
+#define REG_SWITCH_CTRL_14		0x82
+
+#define SW_PRIO_MAPPING_M		KS_PRIO_M
+#define SW_PRIO_MAPPING_S		6
+#define SW_PRIO_MAP_3_HI		0
+#define SW_PRIO_MAP_2_HI		2
+#define SW_PRIO_MAP_0_LO		3
+
+#define REG_SW_CTRL_15			0x83
+#define REG_SW_CTRL_16			0x84
+
+#define SW_DRIVE_STRENGTH_M		0x3
+#define SW_DRIVE_STRENGTH_4MA		0
+#define SW_DRIVE_STRENGTH_8MA		1
+#define SW_DRIVE_STRENGTH_10MA		2
+#define SW_DRIVE_STRENGTH_14MA		3
+#define SW_MII_DRIVE_STRENGTH_S		6
+
+#define REG_SW_CTRL_17			0x85
+#define REG_SW_CTRL_18			0x86
+
+#define SW_SELF_ADDR_FILTER_ENABLE	(1 << 6)
+
+#define REG_SW_UNK_UCAST_CTRL		0x83
+#define REG_SW_UNK_MCAST_CTRL		0x84
+#define REG_SW_UNK_VID_CTRL		0x85
+#define REG_SW_UNK_IP_MCAST_CTRL	0x86
+
+#define SW_UNK_FWD_ENABLE		(1 << 5)
+#define SW_UNK_FWD_MAP			KS_PORT_M
+
+#define REG_SW_CTRL_19			0x87
+
+#define SW_IN_RATE_LIMIT_PERIOD_M	0x3
+#define SW_IN_RATE_LIMIT_PERIOD_S	4
+#define SW_IN_RATE_LIMIT_16_MS		0
+#define SW_IN_RATE_LIMIT_64_MS		1
+#define SW_IN_RATE_LIMIT_256_MS		2
+#define SW_QUEUE_BASED_OUT_RATE_LIMIT	(1 << 3)
+#define SW_INS_TAG_ENABLE		(1 << 2)
+
+#define REG_TOS_PRIO_CTRL_0		0x90
+#define REG_TOS_PRIO_CTRL_1		0x91
+#define REG_TOS_PRIO_CTRL_2		0x92
+#define REG_TOS_PRIO_CTRL_3		0x93
+#define REG_TOS_PRIO_CTRL_4		0x94
+#define REG_TOS_PRIO_CTRL_5		0x95
+#define REG_TOS_PRIO_CTRL_6		0x96
+#define REG_TOS_PRIO_CTRL_7		0x97
+#define REG_TOS_PRIO_CTRL_8		0x98
+#define REG_TOS_PRIO_CTRL_9		0x99
+#define REG_TOS_PRIO_CTRL_10		0x9A
+#define REG_TOS_PRIO_CTRL_11		0x9B
+#define REG_TOS_PRIO_CTRL_12		0x9C
+#define REG_TOS_PRIO_CTRL_13		0x9D
+#define REG_TOS_PRIO_CTRL_14		0x9E
+#define REG_TOS_PRIO_CTRL_15		0x9F
+
+#define TOS_PRIO_M			KS_PRIO_M
+#define TOS_PRIO_S			KS_PRIO_S
+
+
+#define REG_PORT_1_CTRL_8		0xB0
+#define REG_PORT_2_CTRL_8		0xC0
+#define REG_PORT_3_CTRL_8		0xD0
+#define REG_PORT_4_CTRL_8		0xE0
+#define REG_PORT_5_CTRL_8		0xF0
+
+#define PORT_INS_TAG_FOR_PORT_5_S	3
+#define PORT_INS_TAG_FOR_PORT_5		(1 << 3)
+#define PORT_INS_TAG_FOR_PORT_4		(1 << 2)
+#define PORT_INS_TAG_FOR_PORT_3		(1 << 1)
+#define PORT_INS_TAG_FOR_PORT_2		(1 << 0)
+
+#define REG_PORT_1_CTRL_9		0xB1
+#define REG_PORT_2_CTRL_9		0xC1
+#define REG_PORT_3_CTRL_9		0xD1
+#define REG_PORT_4_CTRL_9		0xE1
+#define REG_PORT_5_CTRL_9		0xF1
+
+#define PORT_QUEUE_SPLIT_H		(1 << 1)
+#define PORT_QUEUE_SPLIT_1		0
+#define PORT_QUEUE_SPLIT_2		1
+#define PORT_QUEUE_SPLIT_4		2
+#define PORT_DROP_TAG			(1 << 0)
+
+#define REG_PORT_1_CTRL_10		0xB2
+#define REG_PORT_2_CTRL_10		0xC2
+#define REG_PORT_3_CTRL_10		0xD2
+#define REG_PORT_4_CTRL_10		0xE2
+#define REG_PORT_5_CTRL_10		0xF2
+#define REG_PORT_1_CTRL_11		0xB3
+#define REG_PORT_2_CTRL_11		0xC3
+#define REG_PORT_3_CTRL_11		0xD3
+#define REG_PORT_4_CTRL_11		0xE3
+#define REG_PORT_5_CTRL_11		0xF3
+#define REG_PORT_1_CTRL_12		0xB4
+#define REG_PORT_2_CTRL_12		0xC4
+#define REG_PORT_3_CTRL_12		0xD4
+#define REG_PORT_4_CTRL_12		0xE4
+#define REG_PORT_5_CTRL_12		0xF4
+#define REG_PORT_1_CTRL_13		0xB5
+#define REG_PORT_2_CTRL_13		0xC5
+#define REG_PORT_3_CTRL_13		0xD5
+#define REG_PORT_4_CTRL_13		0xE5
+#define REG_PORT_5_CTRL_13		0xF5
+
+#define REG_PORT_1_RATE_CTRL_3		0xB2
+#define REG_PORT_1_RATE_CTRL_2		0xB3
+#define REG_PORT_1_RATE_CTRL_1		0xB4
+#define REG_PORT_1_RATE_CTRL_0		0xB5
+#define REG_PORT_2_RATE_CTRL_3		0xC2
+#define REG_PORT_2_RATE_CTRL_2		0xC3
+#define REG_PORT_2_RATE_CTRL_1		0xC4
+#define REG_PORT_2_RATE_CTRL_0		0xC5
+#define REG_PORT_3_RATE_CTRL_3		0xD2
+#define REG_PORT_3_RATE_CTRL_2		0xD3
+#define REG_PORT_3_RATE_CTRL_1		0xD4
+#define REG_PORT_3_RATE_CTRL_0		0xD5
+#define REG_PORT_4_RATE_CTRL_3		0xE2
+#define REG_PORT_4_RATE_CTRL_2		0xE3
+#define REG_PORT_4_RATE_CTRL_1		0xE4
+#define REG_PORT_4_RATE_CTRL_0		0xE5
+#define REG_PORT_5_RATE_CTRL_3		0xF2
+#define REG_PORT_5_RATE_CTRL_2		0xF3
+#define REG_PORT_5_RATE_CTRL_1		0xF4
+#define REG_PORT_5_RATE_CTRL_0		0xF5
+
+#define RATE_CTRL_ENABLE		(1 << 7)
+#define RATE_RATIO_M			((1 << 7) - 1)
+
+#define REG_PORT_1_RATE_LIMIT		0xB6
+#define REG_PORT_2_RATE_LIMIT		0xC6
+#define REG_PORT_3_RATE_LIMIT		0xD6
+#define REG_PORT_4_RATE_LIMIT		0xE6
+#define REG_PORT_5_RATE_LIMIT		0xF6
+
+#define PORT_IN_FLOW_CTRL_S		4
+#define PORT_IN_LIMIT_MODE_M		0x3
+#define PORT_IN_LIMIT_MODE_S		2
+#define PORT_COUNT_IFG_S		1
+#define PORT_COUNT_PREAMBLE_S		0
+#define PORT_IN_FLOW_CTRL		(1 << PORT_IN_FLOW_CTRL_S)
+#define PORT_IN_ALL			0
+#define PORT_IN_UNICAST			1
+#define PORT_IN_MULTICAST		2
+#define PORT_IN_BROADCAST		3
+#define PORT_COUNT_IFG			(1 << PORT_COUNT_IFG_S)
+#define PORT_COUNT_PREAMBLE		(1 << PORT_COUNT_PREAMBLE_S)
+
+#define REG_PORT_1_IN_RATE_0		0xB7
+#define REG_PORT_2_IN_RATE_0		0xC7
+#define REG_PORT_3_IN_RATE_0		0xD7
+#define REG_PORT_4_IN_RATE_0		0xE7
+#define REG_PORT_5_IN_RATE_0		0xF7
+#define REG_PORT_1_IN_RATE_1		0xB8
+#define REG_PORT_2_IN_RATE_1		0xC8
+#define REG_PORT_3_IN_RATE_1		0xD8
+#define REG_PORT_4_IN_RATE_1		0xE8
+#define REG_PORT_5_IN_RATE_1		0xF8
+#define REG_PORT_1_IN_RATE_2		0xB9
+#define REG_PORT_2_IN_RATE_2		0xC9
+#define REG_PORT_3_IN_RATE_2		0xD9
+#define REG_PORT_4_IN_RATE_2		0xE9
+#define REG_PORT_5_IN_RATE_2		0xF9
+#define REG_PORT_1_IN_RATE_3		0xBA
+#define REG_PORT_2_IN_RATE_3		0xCA
+#define REG_PORT_3_IN_RATE_3		0xDA
+#define REG_PORT_4_IN_RATE_3		0xEA
+#define REG_PORT_5_IN_RATE_3		0xFA
+
+#define PORT_RATE_LIMIT_M		((1 << 7) - 1)
+
+#define REG_PORT_1_OUT_RATE_0		0xBB
+#define REG_PORT_2_OUT_RATE_0		0xCB
+#define REG_PORT_3_OUT_RATE_0		0xDB
+#define REG_PORT_4_OUT_RATE_0		0xEB
+#define REG_PORT_5_OUT_RATE_0		0xFB
+#define REG_PORT_1_OUT_RATE_1		0xBC
+#define REG_PORT_2_OUT_RATE_1		0xCC
+#define REG_PORT_3_OUT_RATE_1		0xDC
+#define REG_PORT_4_OUT_RATE_1		0xEC
+#define REG_PORT_5_OUT_RATE_1		0xFC
+#define REG_PORT_1_OUT_RATE_2		0xBD
+#define REG_PORT_2_OUT_RATE_2		0xCD
+#define REG_PORT_3_OUT_RATE_2		0xDD
+#define REG_PORT_4_OUT_RATE_2		0xED
+#define REG_PORT_5_OUT_RATE_2		0xFD
+#define REG_PORT_1_OUT_RATE_3		0xBE
+#define REG_PORT_2_OUT_RATE_3		0xCE
+#define REG_PORT_3_OUT_RATE_3		0xDE
+#define REG_PORT_4_OUT_RATE_3		0xEE
+#define REG_PORT_5_OUT_RATE_3		0xFE
+
+
+#define REG_SW_CFG			0xEF
+
+#define SW_PORT_3_FIBER			(1 << 7)
+
+/* KSZ8864 */
+
+#define REG_PHY_PORT_CTRL_1		0xCF
+
+#define PORT_HALF_DUPLEX		(1 << 7)
+#define PORT_FLOW_CTRL			(1 << 6)
+#define PORT_10_MBIT			(1 << 5)
+
+#define REG_PHY_PORT_CTRL_2		0xDF
+
+#define PORT_MII_MAC_MODE		(1 << 6)
+
+#define REG_KSZ8864_CHIP_ID		0xFE
+
+#define SW_KSZ8864			(1 << 7)
+
+
+#ifndef PHY_REG_CTRL
+#define PHY_REG_CTRL			0
+
+#define PHY_RESET			(1 << 15)
+#define PHY_LOOPBACK			(1 << 14)
+#define PHY_SPEED_100MBIT		(1 << 13)
+#define PHY_AUTO_NEG_ENABLE		(1 << 12)
+#define PHY_POWER_DOWN			(1 << 11)
+#define PHY_MII_DISABLE			(1 << 10)
+#define PHY_AUTO_NEG_RESTART		(1 << 9)
+#define PHY_FULL_DUPLEX			(1 << 8)
+#define PHY_COLLISION_TEST_NOT		(1 << 7)
+#define PHY_HP_MDIX			(1 << 5)
+#define PHY_FORCE_MDIX			(1 << 4)
+#define PHY_AUTO_MDIX_DISABLE		(1 << 3)
+#define PHY_REMOTE_FAULT_DISABLE	(1 << 2)
+#define PHY_TRANSMIT_DISABLE		(1 << 1)
+#define PHY_LED_DISABLE			(1 << 0)
+
+#define PHY_REG_STATUS			1
+
+#define PHY_100BT4_CAPABLE		(1 << 15)
+#define PHY_100BTX_FD_CAPABLE		(1 << 14)
+#define PHY_100BTX_CAPABLE		(1 << 13)
+#define PHY_10BT_FD_CAPABLE		(1 << 12)
+#define PHY_10BT_CAPABLE		(1 << 11)
+#define PHY_MII_SUPPRESS_CAPABLE_NOT	(1 << 6)
+#define PHY_AUTO_NEG_ACKNOWLEDGE	(1 << 5)
+#define PHY_REMOTE_FAULT		(1 << 4)
+#define PHY_AUTO_NEG_CAPABLE		(1 << 3)
+#define PHY_LINK_STATUS			(1 << 2)
+#define PHY_JABBER_DETECT_NOT		(1 << 1)
+#define PHY_EXTENDED_CAPABILITY		(1 << 0)
+
+#define PHY_REG_ID_1			2
+#define PHY_REG_ID_2			3
+
+#define KSZ8895_ID_HI			0x0022
+#define KSZ8895_ID_LO			0x1450
+
+#define PHY_REG_AUTO_NEGOTIATION	4
+
+#define PHY_AUTO_NEG_NEXT_PAGE_NOT	(1 << 15)
+#define PHY_AUTO_NEG_REMOTE_FAULT_NOT	(1 << 13)
+#define PHY_AUTO_NEG_SYM_PAUSE		(1 << 10)
+#define PHY_AUTO_NEG_100BT4		(1 << 9)
+#define PHY_AUTO_NEG_100BTX_FD		(1 << 8)
+#define PHY_AUTO_NEG_100BTX		(1 << 7)
+#define PHY_AUTO_NEG_10BT_FD		(1 << 6)
+#define PHY_AUTO_NEG_10BT		(1 << 5)
+#define PHY_AUTO_NEG_SELECTOR		0x001F
+#define PHY_AUTO_NEG_802_3		0x0001
+
+#define PHY_REG_REMOTE_CAPABILITY	5
+
+#define PHY_REMOTE_NEXT_PAGE_NOT	(1 << 15)
+#define PHY_REMOTE_ACKNOWLEDGE_NOT	(1 << 14)
+#define PHY_REMOTE_REMOTE_FAULT_NOT	(1 << 13)
+#define PHY_REMOTE_SYM_PAUSE		(1 << 10)
+#define PHY_REMOTE_100BTX_FD		(1 << 8)
+#define PHY_REMOTE_100BTX		(1 << 7)
+#define PHY_REMOTE_10BT_FD		(1 << 6)
+#define PHY_REMOTE_10BT			(1 << 5)
+
+#define PHY_REG_LINK_MD			0x1D
+
+#define PHY_START_CABLE_DIAG		(1 << 15)
+#define PHY_CABLE_DIAG_RESULT		0x6000
+#define PHY_CABLE_STAT_NORMAL		0x0000
+#define PHY_CABLE_STAT_OPEN		0x2000
+#define PHY_CABLE_STAT_SHORT		0x4000
+#define PHY_CABLE_STAT_FAILED		0x6000
+#define PHY_CABLE_10M_SHORT		(1 << 12)
+#define PHY_CABLE_FAULT_COUNTER		0x01FF
+
+#define PHY_REG_PHY_CTRL		0x1F
+
+#define PHY_MODE_M			0x7
+#define PHY_MODE_S			8
+#define PHY_STAT_REVERSED_POLARITY	(1 << 5)
+#define PHY_STAT_MDIX			(1 << 4)
+#define PHY_FORCE_LINK			(1 << 3)
+#define PHY_POWER_SAVING_ENABLE		(1 << 2)
+#define PHY_REMOTE_LOOPBACK		(1 << 1)
+#endif
+
+
+/* Default values are used in ksz_sw.h if these are not defined. */
+#define PRIO_QUEUES			4
+
+#define KS_PRIO_IN_REG			4
+
+#define SWITCH_PORT_NUM			4
+
+#define SW_D				u8
+#define SW_R(sw, addr)			(sw)->reg->r8(sw, addr)
+#define SW_W(sw, addr, val)		(sw)->reg->w8(sw, addr, val)
+#define SW_SIZE				(1)
+#define SW_SIZE_STR			"%02x"
+
+
+#define P_BCAST_STORM_CTRL		REG_PORT_CTRL_0
+#define P_PRIO_CTRL			REG_PORT_CTRL_0
+#define P_TAG_CTRL			REG_PORT_CTRL_0
+#define P_MIRROR_CTRL			REG_PORT_CTRL_1
+#define P_802_1P_CTRL			REG_PORT_CTRL_2
+#define P_STP_CTRL			REG_PORT_CTRL_2
+#define P_LOCAL_CTRL			REG_PORT_CTRL_5
+#define P_REMOTE_STATUS			REG_PORT_STATUS_1
+#define P_FORCE_CTRL			REG_PORT_CTRL_5
+#define P_NEG_RESTART_CTRL		REG_PORT_CTRL_6
+#define P_SPEED_STATUS			REG_PORT_STATUS_0
+#define P_LINK_STATUS			REG_PORT_STATUS_1
+#define P_INS_SRC_PVID_CTRL		REG_PORT_CTRL_8
+#define P_DROP_TAG_CTRL			REG_PORT_CTRL_9
+#define P_RATE_LIMIT_CTRL		REG_PORT_RATE_LIMIT
+
+#define S_FLUSH_TABLE_CTRL		REG_SW_CTRL_0
+#define S_LINK_AGING_CTRL		REG_SW_CTRL_0
+#define S_HUGE_PACKET_CTRL		REG_SW_CTRL_2
+#define S_MIRROR_CTRL			REG_SW_CTRL_3
+#define S_REPLACE_VID_CTRL		REG_SW_CTRL_4
+#define S_PASS_PAUSE_CTRL		REG_SW_CTRL_10
+#define S_TAIL_TAG_CTRL			REG_SW_CTRL_10
+#define S_802_1P_PRIO_CTRL		REG_SW_CTRL_12
+#define S_TOS_PRIO_CTRL			REG_TOS_PRIO_CTRL_0
+#define S_IPV6_MLD_CTRL			REG_SW_CTRL_21
+
+#define IND_ACC_TABLE(table)		((table) << 8)
+
+#define TAIL_TAG_OVERRIDE		(1 << 6)
+#define TAIL_TAG_LOOKUP			(1 << 7)
+
+#endif /* KSZ9477_REGS_H */
diff --git a/drivers/net/dsa/microchip/ksz_8895_spi.c b/drivers/net/dsa/microchip/ksz_8895_spi.c
new file mode 100644
index 000000000000..b1c9571c8e99
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz_8895_spi.c
@@ -0,0 +1,275 @@
+/*
+ * Microchip KSZ series register access through SPI
+ *
+ * Copyright (C) 2017 Woojung Huh <Woojung.Huh@microchip.com>
+ * Copyright (C) 2017 Pavel Machek <pavel@denx.de>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <asm/unaligned.h>
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+
+#include "ksz_8895_reg.h"
+#include "ksz_priv.h"
+
+/* SPI frame opcodes */
+#define KS_SPIOP_RD			3
+#define KS_SPIOP_WR			2
+
+static int ksz_spi_read_reg(struct spi_device *spi, u32 reg, u8 *val,
+			    unsigned int len)
+{
+	int ret;
+
+	u8 buf[2];
+
+	buf[0] = KS_SPIOP_RD;
+	buf[1] = reg;
+
+	ret = spi_write_then_read(spi, buf, 2, val, len);
+	return ret;
+}
+
+static int ksz_spi_read(struct ksz_device *dev, u32 reg, u8 *data,
+			unsigned int len)
+{
+	struct spi_device *spi = dev->priv;
+
+	return ksz_spi_read_reg(spi, reg, data, len);
+}
+
+static int ksz_spi_read8(struct ksz_device *dev, u32 reg, u8 *val)
+{
+	return ksz_spi_read(dev, reg, val, 1);
+}
+
+static int ksz_spi_read16(struct ksz_device *dev, u32 reg, u16 *val)
+{
+	int ret = ksz_spi_read(dev, reg, (u8 *)val, 2);
+
+	if (!ret)
+		*val = be16_to_cpu(*val);
+
+	return ret;
+}
+
+static int ksz_spi_read24(struct ksz_device *dev, u32 reg, u32 *val)
+{
+	int ret;
+
+	*val = 0;
+	ret = ksz_spi_read(dev, reg, (u8 *)val, 3);
+	if (!ret) {
+		*val = be32_to_cpu(*val);
+		/* convert to 24bit */
+		*val >>= 8;
+	}
+
+	return ret;
+}
+
+static int ksz_spi_read32(struct ksz_device *dev, u32 reg, u32 *val)
+{
+	int ret = ksz_spi_read(dev, reg, (u8 *)val, 4);
+
+	if (!ret)
+		*val = be32_to_cpu(*val);
+
+	return ret;
+}
+
+static int ksz_spi_write_reg(struct spi_device *spi, u32 reg, u8 *val,
+			     unsigned int len)
+{
+	u8 data[12];
+
+	int i;
+	
+	data[0] = KS_SPIOP_WR;
+	data[1] = reg;
+	for (i = 0; i < len; i++)
+		data[i + 2] = val[i];
+
+	return spi_write(spi, &data, 2 + len);
+}
+
+static int ksz_spi_write8(struct ksz_device *dev, u32 reg, u8 value)
+{
+	struct spi_device *spi = dev->priv;
+
+	return ksz_spi_write_reg(spi, reg, &value, 1);
+}
+
+static int ksz_spi_write16(struct ksz_device *dev, u32 reg, u16 value)
+{
+	struct spi_device *spi = dev->priv;
+
+	value = cpu_to_be16(value);
+	return ksz_spi_write_reg(spi, reg, (u8 *)&value, 2);
+}
+
+static int ksz_spi_write24(struct ksz_device *dev, u32 reg, u32 value)
+{
+	struct spi_device *spi = dev->priv;
+
+	/* make it to big endian 24bit from MSB */
+	value <<= 8;
+	value = cpu_to_be32(value);
+	return ksz_spi_write_reg(spi, reg, (u8 *)&value, 3);
+}
+
+static int ksz_spi_write32(struct ksz_device *dev, u32 reg, u32 value)
+{
+	struct spi_device *spi = dev->priv;
+
+	value = cpu_to_be32(value);
+	return ksz_spi_write_reg(spi, reg, (u8 *)&value, 4);
+}
+
+static const struct ksz_io_ops ksz_spi_ops = {
+	.read8 = ksz_spi_read8,
+	.read16 = ksz_spi_read16,
+	.read24 = ksz_spi_read24,
+	.read32 = ksz_spi_read32,
+	.write8 = ksz_spi_write8,
+	.write16 = ksz_spi_write16,
+	.write24 = ksz_spi_write24,
+	.write32 = ksz_spi_write32,
+};
+
+static int ksz_spi_sysfs_read(struct ksz_device *dev, char *buf,
+		 unsigned offset, size_t count)
+{
+	int err = 0;
+	int i;
+
+	for (i = 0; i < count; i++) {
+		ksz_read8(dev, i+offset, buf+i+offset);
+	}
+
+	return err ? err : count;
+}
+
+static int ksz_spi_sysfs_write(struct ksz_device *dev, char *buf,
+		 unsigned offset, size_t count)
+{
+	int err = -EINVAL;
+
+	return err ? err : count;
+}
+
+static ssize_t ksz_spi_registers_read(struct file *filp, struct kobject *kobj,
+	struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
+{
+	struct device *dev;
+	struct ksz_device *ks;
+
+	dev = container_of(kobj, struct device, kobj);
+	ks = dev_get_drvdata(dev);
+
+	return ksz_spi_sysfs_read(ks, buf, off, count);
+}
+
+static ssize_t ksz_spi_registers_write(struct file *filp, struct kobject *kobj,
+	struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
+{
+	struct device *dev;
+	struct ksz_device *ks;
+
+	dev = container_of(kobj, struct device, kobj);
+	ks = dev_get_drvdata(dev);
+
+	return ksz_spi_sysfs_write(ks, buf, off, count);
+}
+
+static const struct bin_attribute ksz_spi_registers_attr = {
+	.attr = {
+		.name   = "registers",
+		.mode   = S_IRUSR | S_IWUSR,
+	},
+	.size   = 0x100,
+	.read   = ksz_spi_registers_read,
+	.write  = ksz_spi_registers_write,
+};
+
+static int ksz_spi_probe(struct spi_device *spi)
+{
+	struct ksz_device *dev;
+	int ret;
+
+	dev = ksz_switch_alloc(&spi->dev, &ksz_spi_ops, spi);
+	if (!dev)
+		return -ENOMEM;
+
+	if (spi->dev.platform_data)
+		dev->pdata = spi->dev.platform_data;
+
+	ret = ksz_switch_register(dev);
+	if (ret)
+		return ret;
+
+	memcpy(&dev->regs_attr, &ksz_spi_registers_attr, sizeof(dev->regs_attr));
+        dev->regs_attr.size = 0x100;
+
+        sysfs_attr_init(&dev->regs_attr.attr);
+        ret = sysfs_create_bin_file(&spi->dev.kobj, &dev->regs_attr);
+
+        if (ret) {
+                dev_err(&spi->dev, "unable to create sysfs file, err=%d\n",
+                                    ret);
+                return ret;
+        }
+	
+	spi_set_drvdata(spi, dev);
+
+	return 0;
+}
+
+static int ksz_spi_remove(struct spi_device *spi)
+{
+	struct ksz_device *dev = spi_get_drvdata(spi);
+
+	if (dev)
+		ksz_switch_remove(dev);
+
+	sysfs_remove_bin_file(&spi->dev.kobj, &dev->regs_attr);
+	
+	return 0;
+}
+
+static const struct of_device_id ksz_dt_ids[] = {
+	{ .compatible = "microchip,ksz8895" },	
+	{},
+};
+MODULE_DEVICE_TABLE(of, ksz_dt_ids);
+
+static struct spi_driver ksz_spi_driver = {
+	.driver = {
+		.name	= "ksz8895-switch",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(ksz_dt_ids),
+	},
+	.probe	= ksz_spi_probe,
+	.remove	= ksz_spi_remove,
+};
+
+module_spi_driver(ksz_spi_driver);
+
+MODULE_AUTHOR("Pavel Machek <pavel@denx.de>");
+MODULE_DESCRIPTION("Microchip KSZ Series Switch SPI access Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/microchip/ksz_9477_reg.h b/drivers/net/dsa/microchip/ksz_9477_reg.h
index 6aa6752035a1..af4d29c2ba4f 100644
--- a/drivers/net/dsa/microchip/ksz_9477_reg.h
+++ b/drivers/net/dsa/microchip/ksz_9477_reg.h
@@ -16,6 +16,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#error This is not switch we have
 #ifndef __KSZ9477_REGS_H
 #define __KSZ9477_REGS_H
 
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index b313ecdf2919..6741d05d0ac4 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -28,6 +28,7 @@
 #include <net/dsa.h>
 #include <net/switchdev.h>
 
+#include "ksz_9477_reg.h"
 #include "ksz_priv.h"
 
 static const struct {
diff --git a/drivers/net/dsa/microchip/ksz_mdio_emulation.c b/drivers/net/dsa/microchip/ksz_mdio_emulation.c
new file mode 100644
index 000000000000..a4e24506bed8
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz_mdio_emulation.c
@@ -0,0 +1,286 @@
+/**
+ * Micrel KSZ8895 SPI driver
+ *
+ * Copyright (c) 2015 Micrel, Inc.
+ *
+ * GPLv2
+ */
+
+#define PHY_ID_KSZ8895		((KSZ8895_ID_HI << 16) | KSZ8895_ID_LO)
+
+/**
+ * sw_r_phy - read data from PHY register
+ * @sw:		The switch instance.
+ * @phy:	PHY address to read.
+ * @reg:	PHY register to read.
+ * @val:	Buffer to store the read data.
+ *
+ * This routine reads data from the PHY register.
+ */
+static void sw_r_phy(struct ksz_device *sw, u16 phy, u16 reg, u16 *val)
+{
+	u8 ctrl;
+	u8 restart;
+	u8 link;
+	u8 speed;
+	u8 force;
+	u8 p = phy;
+	u16 data = 0;
+
+	switch (reg) {
+	case PHY_REG_CTRL:
+		ksz_pread8(sw, p, P_LOCAL_CTRL, &ctrl);
+		ksz_pread8(sw, p, P_NEG_RESTART_CTRL, &restart);
+		ksz_pread8(sw, p, P_SPEED_STATUS, &speed);
+		ksz_pread8(sw, p, P_FORCE_CTRL, &force);
+		if (restart & PORT_PHY_LOOPBACK)
+			data |= PHY_LOOPBACK;
+		if (force & PORT_FORCE_100_MBIT)
+			data |= PHY_SPEED_100MBIT;
+		if (!(force & PORT_AUTO_NEG_DISABLE))
+			data |= PHY_AUTO_NEG_ENABLE;
+		if (restart & PORT_POWER_DOWN)
+			data |= PHY_POWER_DOWN;
+		if (restart & PORT_AUTO_NEG_RESTART)
+			data |= PHY_AUTO_NEG_RESTART;
+		if (force & PORT_FORCE_FULL_DUPLEX)
+			data |= PHY_FULL_DUPLEX;
+		if (speed & PORT_HP_MDIX)
+			data |= PHY_HP_MDIX;
+		if (restart & PORT_FORCE_MDIX)
+			data |= PHY_FORCE_MDIX;
+		if (restart & PORT_AUTO_MDIX_DISABLE)
+			data |= PHY_AUTO_MDIX_DISABLE;
+		if (restart & PORT_TX_DISABLE)
+			data |= PHY_TRANSMIT_DISABLE;
+		if (restart & PORT_LED_OFF)
+			data |= PHY_LED_DISABLE;
+		break;
+	case PHY_REG_STATUS:
+		ksz_pread8(sw, p, P_LINK_STATUS, &link);
+		ksz_pread8(sw, p, P_SPEED_STATUS, &speed);
+		data = PHY_100BTX_FD_CAPABLE |
+			PHY_100BTX_CAPABLE |
+			PHY_10BT_FD_CAPABLE |
+			PHY_10BT_CAPABLE |
+			PHY_AUTO_NEG_CAPABLE;
+		if (link & PORT_AUTO_NEG_COMPLETE)
+			data |= PHY_AUTO_NEG_ACKNOWLEDGE;
+		if (link & PORT_STAT_LINK_GOOD)
+			data |= PHY_LINK_STATUS;
+		break;
+	case PHY_REG_ID_1:
+		data = KSZ8895_ID_HI;
+		break;
+	case PHY_REG_ID_2:
+		data = KSZ8895_ID_LO;
+		break;
+	case PHY_REG_AUTO_NEGOTIATION:
+		ksz_pread8(sw, p, P_LOCAL_CTRL, &ctrl);
+		data = PHY_AUTO_NEG_802_3;
+		if (ctrl & PORT_AUTO_NEG_SYM_PAUSE)
+			data |= PHY_AUTO_NEG_SYM_PAUSE;
+		if (ctrl & PORT_AUTO_NEG_100BTX_FD)
+			data |= PHY_AUTO_NEG_100BTX_FD;
+		if (ctrl & PORT_AUTO_NEG_100BTX)
+			data |= PHY_AUTO_NEG_100BTX;
+		if (ctrl & PORT_AUTO_NEG_10BT_FD)
+			data |= PHY_AUTO_NEG_10BT_FD;
+		if (ctrl & PORT_AUTO_NEG_10BT)
+			data |= PHY_AUTO_NEG_10BT;
+		break;
+	case PHY_REG_REMOTE_CAPABILITY:
+		ksz_pread8(sw, p, P_REMOTE_STATUS, &link);
+		data = PHY_AUTO_NEG_802_3;
+		if (link & PORT_REMOTE_SYM_PAUSE)
+			data |= PHY_AUTO_NEG_SYM_PAUSE;
+		if (link & PORT_REMOTE_100BTX_FD)
+			data |= PHY_AUTO_NEG_100BTX_FD;
+		if (link & PORT_REMOTE_100BTX)
+			data |= PHY_AUTO_NEG_100BTX;
+		if (link & PORT_REMOTE_10BT_FD)
+			data |= PHY_AUTO_NEG_10BT_FD;
+		if (link & PORT_REMOTE_10BT)
+			data |= PHY_AUTO_NEG_10BT;
+		break;
+	default:
+		break;
+	}
+	*val = data;
+}  /* sw_r_phy */
+
+/**
+ * sw_w_phy - write data to PHY register
+ * @hw:		The switch instance.
+ * @phy:	PHY address to write.
+ * @reg:	PHY register to write.
+ * @val:	Word data to write.
+ *
+ * This routine writes data to the PHY register.
+ */
+static void sw_w_phy(struct ksz_device *sw, u16 phy, u16 reg, u16 val)
+{
+	u8 ctrl;
+	u8 restart;
+	u8 speed;
+	u8 data;
+	u8 p = phy;
+
+	switch (reg) {
+	case PHY_REG_CTRL:
+		ksz_pread8(sw, p, P_SPEED_STATUS, &speed);
+		data = speed;
+		if (val & PHY_HP_MDIX)
+			data |= PORT_HP_MDIX;
+		else
+			data &= ~PORT_HP_MDIX;
+		if (data != speed)
+			ksz_pwrite8(sw, p, P_SPEED_STATUS, data);
+		ksz_pread8(sw, p, P_FORCE_CTRL, &ctrl);
+		data = ctrl;
+		if (!(val & PHY_AUTO_NEG_ENABLE))
+			data |= PORT_AUTO_NEG_DISABLE;
+		else
+			data &= ~PORT_AUTO_NEG_DISABLE;
+		if (val & PHY_SPEED_100MBIT)
+			data |= PORT_FORCE_100_MBIT;
+		else
+			data &= ~PORT_FORCE_100_MBIT;
+		if (val & PHY_FULL_DUPLEX)
+			data |= PORT_FORCE_FULL_DUPLEX;
+		else
+			data &= ~PORT_FORCE_FULL_DUPLEX;
+		if (data != ctrl)
+			ksz_pwrite8(sw, p, P_FORCE_CTRL, data);
+		ksz_pread8(sw, p, P_NEG_RESTART_CTRL, &restart);
+		data = restart;
+		if (val & PHY_LED_DISABLE)
+			data |= PORT_LED_OFF;
+		else
+			data &= ~PORT_LED_OFF;
+		if (val & PHY_TRANSMIT_DISABLE)
+			data |= PORT_TX_DISABLE;
+		else
+			data &= ~PORT_TX_DISABLE;
+		if (val & PHY_AUTO_NEG_RESTART)
+			data |= PORT_AUTO_NEG_RESTART;
+		else
+			data &= ~(PORT_AUTO_NEG_RESTART);
+		if (val & PHY_POWER_DOWN)
+			data |= PORT_POWER_DOWN;
+		else
+			data &= ~PORT_POWER_DOWN;
+		if (val & PHY_AUTO_MDIX_DISABLE)
+			data |= PORT_AUTO_MDIX_DISABLE;
+		else
+			data &= ~PORT_AUTO_MDIX_DISABLE;
+		if (val & PHY_FORCE_MDIX)
+			data |= PORT_FORCE_MDIX;
+		else
+			data &= ~PORT_FORCE_MDIX;
+		if (val & PHY_LOOPBACK)
+			data |= PORT_PHY_LOOPBACK;
+		else
+			data &= ~PORT_PHY_LOOPBACK;
+		if (data != restart)
+			ksz_pwrite8(sw, p, P_NEG_RESTART_CTRL, data);
+		break;
+	case PHY_REG_AUTO_NEGOTIATION:
+		ksz_pread8(sw, p, P_LOCAL_CTRL, &ctrl);
+		data = ctrl;
+		data &= ~(PORT_AUTO_NEG_SYM_PAUSE |
+			PORT_AUTO_NEG_100BTX_FD |
+			PORT_AUTO_NEG_100BTX |
+			PORT_AUTO_NEG_10BT_FD |
+			PORT_AUTO_NEG_10BT);
+		if (val & PHY_AUTO_NEG_SYM_PAUSE)
+			data |= PORT_AUTO_NEG_SYM_PAUSE;
+		if (val & PHY_AUTO_NEG_100BTX_FD)
+			data |= PORT_AUTO_NEG_100BTX_FD;
+		if (val & PHY_AUTO_NEG_100BTX)
+			data |= PORT_AUTO_NEG_100BTX;
+		if (val & PHY_AUTO_NEG_10BT_FD)
+			data |= PORT_AUTO_NEG_10BT_FD;
+		if (val & PHY_AUTO_NEG_10BT)
+			data |= PORT_AUTO_NEG_10BT;
+		if (data != ctrl)
+			ksz_pwrite8(sw, p, P_LOCAL_CTRL, data);
+		break;
+	default:
+		break;
+	}
+}  /* sw_w_phy */
+
+static int ksz_mii_addr(int *reg, int *bank)
+{
+	int ret;
+
+	ret = (*reg & 0xC000) >> ADDR_SHIFT;
+	*bank = (*reg & 0x3000) >> BANK_SHIFT;
+	*reg &= 0x0FFF;
+	return ret;
+}
+
+static int ksz_phy_read16(struct dsa_switch *ds, int phy_id, int regnum)
+{
+	struct ksz_device *sw = ds->priv;
+	int addr;
+	int bank;
+	u16 data;
+	int ret = 0xffff;
+
+	if (phy_id > SWITCH_PORT_NUM + 1)
+		return 0xffff;
+
+	addr = ksz_mii_addr(&regnum, &bank);
+	BUG_ON(addr >= 6);
+
+	switch (addr) {
+	case ADDR_8:
+	case ADDR_16:
+	case ADDR_32:
+		BUG();
+
+	default:
+		if (regnum < 6) {
+			sw_r_phy(sw, phy_id, regnum, &data);
+			ret = data;
+		} else
+			ret = 0;
+	}
+
+	return ret;
+}  /* ksz_mii_read */
+
+static int ksz_phy_write16(struct dsa_switch *ds, int phy_id, int regnum, u16 val)
+{
+	struct ksz_device *sw = ds->priv;
+	int addr;
+	int bank;
+	int reg;
+
+	if (phy_id > SWITCH_PORT_NUM + 1)
+		return -EINVAL;
+
+	BUG_ON(regnum >= 6);
+	reg = regnum;
+	addr = ksz_mii_addr(&regnum, &bank);
+
+	switch (addr) {
+	case ADDR_8:
+	case ADDR_16:
+	case ADDR_32:
+		BUG();
+	default:
+		if (regnum < 6) {
+			/* PHY device driver resets or powers down the PHY. */
+			if (0 == regnum &&
+			    (val & (PHY_RESET | PHY_POWER_DOWN)))
+				break;
+			sw_w_phy(sw, phy_id, regnum, val);
+		}
+		break;
+	}
+
+	return 0;
+}  /* ksz_mii_write */
diff --git a/drivers/net/dsa/microchip/ksz_priv.h b/drivers/net/dsa/microchip/ksz_priv.h
index 2a98dbd51456..1c73cdb8bbca 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -25,8 +25,6 @@
 #include <linux/etherdevice.h>
 #include <net/dsa.h>
 
-#include "ksz_9477_reg.h"
-
 struct ksz_io_ops;
 
 struct vlan_table {
@@ -60,6 +58,8 @@ struct ksz_device {
 	struct vlan_table *vlan_cache;
 
 	u64 mib_value[TOTAL_SWITCH_COUNTER_NUM];
+	
+	struct bin_attribute regs_attr;
 };
 
 struct ksz_io_ops {
@@ -174,6 +174,7 @@ static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value)
 static inline void ksz_pread8(struct ksz_device *dev, int port, int offset,
 			      u8 *data)
 {
+	//printk("pread8 %d %d -> %d\n", port, offset, PORT_CTRL_ADDR(port, offset));
 	ksz_read8(dev, PORT_CTRL_ADDR(port, offset), data);
 }
 
diff --git a/drivers/net/dsa/microchip/ksz_spi.c b/drivers/net/dsa/microchip/ksz_spi.c
index c51946983bed..22ee313052dc 100644
--- a/drivers/net/dsa/microchip/ksz_spi.c
+++ b/drivers/net/dsa/microchip/ksz_spi.c
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/spi/spi.h>
 
+#include "ksz_9477_reg.h"
 #include "ksz_priv.h"
 
 /* SPI frame opcodes */
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index de66ca8e6201..6eb094d5bb02 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -29,7 +29,7 @@
  *	  (eg, 0x00=port1, 0x02=port3, 0x06=port7)
  */
 
-#define	KSZ_INGRESS_TAG_LEN	2
+#define	KSZ_INGRESS_TAG_LEN	1
 #define	KSZ_EGRESS_TAG_LEN	1
 
 static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -69,8 +69,7 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	tag = skb_put(nskb, KSZ_INGRESS_TAG_LEN);
-	tag[0] = 0;
-	tag[1] = 1 << p->dp->index; /* destination port */
+	tag[0] = 1 << p->dp->index; /* destination port */
 
 	return nskb;
 }

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply related

* Re: [PATCH 0/4] net: stmmac: revert the EMAC bindings
From: Chen-Yu Tsai @ 2017-08-27 12:42 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: arm-soc, David Miller, Chen-Yu Tsai, linux-arm-kernel, netdev,
	Florian Fainelli, LABBE Corentin, Andrew Lunn, linux-kernel
In-Reply-To: <20170825191217.10278-1-maxime.ripard@free-electrons.com>

On Sat, Aug 26, 2017 at 3:12 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> The bindings of the stmmac glue for the new Allwinner EMAC controller
> are still controversial and being discussed, even though they've been
> merged in 4.13.
>
> In order not to introduce any binding we do not really want to commit
> to in a stable release, especially since that would mean we would have
> to support both the right and old bindings, let's revert them.
>
> We will reintroduce them in due time, once the discussion has settled
> down.
>
> The first three patches should go through the arm-soc tree, the last
> one through the net tree. All of them must be treated as fixes.
>
> Thanks!
> Maxime
>
> Maxime Ripard (4):
>   dt-bindings: net: Revert sun8i dwmac binding
>   arm64: dts: allwinner: Revert EMAC changes
>   arm: dts: sunxi: Revert EMAC changes
>   net: stmmac: sun8i: Remove the compatibles
>
>  .../devicetree/bindings/net/dwmac-sun8i.txt        | 84 ----------------------
>  arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts  |  9 ---
>  arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts    | 19 -----
>  arch/arm/boot/dts/sun8i-h3-beelink-x2.dts          |  8 ---

I think this particular change is in -next, not v4.13-rc.

Otherwise, whole series is

Acked-by: Chen-Yu Tsai <wens@csie.org>

>  arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts          |  7 --
>  arch/arm/boot/dts/sun8i-h3-orangepi-2.dts          |  8 ---
>  arch/arm/boot/dts/sun8i-h3-orangepi-one.dts        |  8 ---
>  arch/arm/boot/dts/sun8i-h3-orangepi-pc-plus.dts    |  5 --
>  arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts         |  8 ---
>  arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts       | 22 ------
>  arch/arm/boot/dts/sun8i-h3-orangepi-plus2e.dts     | 16 -----
>  arch/arm/boot/dts/sunxi-h3-h5.dtsi                 | 26 -------
>  .../boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 17 -----
>  .../boot/dts/allwinner/sun50i-a64-pine64-plus.dts  | 15 ----
>  .../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 18 -----
>  .../dts/allwinner/sun50i-a64-sopine-baseboard.dts  | 17 -----
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi      | 20 ------
>  .../boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts   | 17 -----
>  .../boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts  | 17 -----
>  .../dts/allwinner/sun50i-h5-orangepi-prime.dts     | 17 -----
>  drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  |  8 ---
>  21 files changed, 366 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/net/dwmac-sun8i.txt
>
> --
> 2.13.5
>

^ permalink raw reply

* Re: Stable apply request [was: Bluetooth: bnep: fix possible might sleep error in bnep_session]
From: Greg KH @ 2017-08-27 13:10 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Jiri Slaby, Jeffy Chen, stable, LKML, open list:BLUETOOTH DRIVERS,
	rvaswani, Brian Norris, dmitry.torokhov, Douglas Anderson, acho,
	Johan Hedberg, Network Development, David S. Miller,
	Gustavo F. Padovan
In-Reply-To: <E0E7758A-9E4C-4179-8403-D8895424586B@holtmann.org>

On Wed, Aug 23, 2017 at 08:14:15PM +0200, Marcel Holtmann wrote:
> Hi Jiri,
> 
> >>> It looks like bnep_session has same pattern as the issue reported in
> >>> old rfcomm:
> >>> 
> >>> 	while (1) {
> >>> 		set_current_state(TASK_INTERRUPTIBLE);
> >>> 		if (condition)
> >>> 			break;
> >>> 		// may call might_sleep here
> >>> 		schedule();
> >>> 	}
> >>> 	__set_current_state(TASK_RUNNING);
> >>> 
> >>> Which fixed at:
> >>> 	dfb2fae Bluetooth: Fix nested sleeps
> >>> 
> >>> So let's fix it at the same way, also follow the suggestion of:
> >>> https://lwn.net/Articles/628628/
> > 
> > ...
> > 
> >> all 3 patches have been applied to bluetooth-next tree.
> > 
> > Hi,
> > 
> > given users are hitting it in at least 4.4 and 4.12, can we have all
> > three in all stables where this applies?
> > 
> > 5da8e47d849d Bluetooth: hidp: fix possible might sleep error in
> > hidp_session_thread
> > f06d977309d0 Bluetooth: cmtp: fix possible might sleep error in cmtp_session
> > 25717382c1dd Bluetooth: bnep: fix possible might sleep error in bnep_session
> > 
> > I am not sure: to stable directly or via net stable?
> 
> as Dave said, just email -stable directly and have Greg pick them up.

All now picked up :)

^ permalink raw reply

* [PATCH v4 0/7] Add RSS to DPAA 1.x Ethernet driver
From: Madalin Bucur @ 2017-08-27 13:13 UTC (permalink / raw)
  To: netdev, davem; +Cc: linuxppc-dev, linux-kernel

This patch set introduces Receive Side Scaling for the DPAA Ethernet
driver. Documentation is updated with details related to the new
feature and limitations that apply.
Added also a small fix.

v2: removed a C++ style comment
v3: move struct fman to header file to avoid exporting a function
v4: addressed compilation issues introduced in v3

Iordache Florinel-R70177 (1):
  fsl/fman: enable FMan Keygen

Madalin Bucur (6):
  fsl/fman: move struct fman to header file
  dpaa_eth: use multiple Rx frame queues
  dpaa_eth: enable Rx hashing control
  dpaa_eth: add NETIF_F_RXHASH
  Documentation: networking: add RSS information
  dpaa_eth: check allocation result

 Documentation/networking/dpaa.txt                  |  68 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c     |  76 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h     |   2 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   |   3 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 118 ++++
 drivers/net/ethernet/freescale/fman/Makefile       |   2 +-
 drivers/net/ethernet/freescale/fman/fman.c         |  88 +--
 drivers/net/ethernet/freescale/fman/fman.h         |  77 ++
 drivers/net/ethernet/freescale/fman/fman_keygen.c  | 783 +++++++++++++++++++++
 drivers/net/ethernet/freescale/fman/fman_keygen.h  |  46 ++
 drivers/net/ethernet/freescale/fman/fman_port.c    |  59 +-
 drivers/net/ethernet/freescale/fman/fman_port.h    |   7 +
 12 files changed, 1235 insertions(+), 94 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.h

-- 
2.1.0

^ permalink raw reply

* [PATCH v4 2/7] fsl/fman: enable FMan Keygen
From: Madalin Bucur @ 2017-08-27 13:13 UTC (permalink / raw)
  To: netdev, davem; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1503839623-3906-1-git-send-email-madalin.bucur@nxp.com>

From: Iordache Florinel-R70177 <florinel.iordache@nxp.com>

Add support for the FMan Keygen with a hardcoded scheme to spread
incoming traffic on a FQ range based on source and destination IPs
and ports.

Signed-off-by: Iordache Florinel <florinel.iordache@nxp.com>
Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
---
 drivers/net/ethernet/freescale/fman/Makefile      |   2 +-
 drivers/net/ethernet/freescale/fman/fman.c        |   8 +
 drivers/net/ethernet/freescale/fman/fman.h        |   2 +
 drivers/net/ethernet/freescale/fman/fman_keygen.c | 783 ++++++++++++++++++++++
 drivers/net/ethernet/freescale/fman/fman_keygen.h |  46 ++
 drivers/net/ethernet/freescale/fman/fman_port.c   |  40 +-
 drivers/net/ethernet/freescale/fman/fman_port.h   |   5 +
 7 files changed, 884 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.h

diff --git a/drivers/net/ethernet/freescale/fman/Makefile b/drivers/net/ethernet/freescale/fman/Makefile
index 6049177..2c38119 100644
--- a/drivers/net/ethernet/freescale/fman/Makefile
+++ b/drivers/net/ethernet/freescale/fman/Makefile
@@ -4,6 +4,6 @@ obj-$(CONFIG_FSL_FMAN) += fsl_fman.o
 obj-$(CONFIG_FSL_FMAN) += fsl_fman_port.o
 obj-$(CONFIG_FSL_FMAN) += fsl_mac.o
 
-fsl_fman-objs	:= fman_muram.o fman.o fman_sp.o
+fsl_fman-objs	:= fman_muram.o fman.o fman_sp.o fman_keygen.o
 fsl_fman_port-objs := fman_port.o
 fsl_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o
diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c
index 8179cc1..f420dac 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -45,6 +45,7 @@
 
 #include "fman.h"
 #include "fman_muram.h"
+#include "fman_keygen.h"
 
 /* General defines */
 #define FMAN_LIODN_TBL			64	/* size of LIODN table */
@@ -56,6 +57,7 @@
 /* Modules registers offsets */
 #define BMI_OFFSET		0x00080000
 #define QMI_OFFSET		0x00080400
+#define KG_OFFSET		0x000C1000
 #define DMA_OFFSET		0x000C2000
 #define FPM_OFFSET		0x000C3000
 #define IMEM_OFFSET		0x000C4000
@@ -1737,6 +1739,7 @@ static int fman_config(struct fman *fman)
 	fman->qmi_regs = base_addr + QMI_OFFSET;
 	fman->dma_regs = base_addr + DMA_OFFSET;
 	fman->hwp_regs = base_addr + HWP_OFFSET;
+	fman->kg_regs = base_addr + KG_OFFSET;
 	fman->base_addr = base_addr;
 
 	spin_lock_init(&fman->spinlock);
@@ -2009,6 +2012,11 @@ static int fman_init(struct fman *fman)
 	/* Init HW Parser */
 	hwp_init(fman->hwp_regs);
 
+	/* Init KeyGen */
+	fman->keygen = keygen_init(fman->kg_regs);
+	if (!fman->keygen)
+		return -EINVAL;
+
 	err = enable(fman, cfg);
 	if (err != 0)
 		return err;
diff --git a/drivers/net/ethernet/freescale/fman/fman.h b/drivers/net/ethernet/freescale/fman/fman.h
index 1015dac..bfa02e0 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -328,6 +328,7 @@ struct fman {
 	struct fman_qmi_regs __iomem *qmi_regs;
 	struct fman_dma_regs __iomem *dma_regs;
 	struct fman_hwp_regs __iomem *hwp_regs;
+	struct fman_kg_regs __iomem *kg_regs;
 	fman_exceptions_cb *exception_cb;
 	fman_bus_error_cb *bus_error_cb;
 	/* Spinlock for FMan use */
@@ -336,6 +337,7 @@ struct fman {
 
 	struct fman_cfg *cfg;
 	struct muram_info *muram;
+	struct fman_keygen *keygen;
 	/* cam section in muram */
 	unsigned long cam_offset;
 	size_t cam_size;
diff --git a/drivers/net/ethernet/freescale/fman/fman_keygen.c b/drivers/net/ethernet/freescale/fman/fman_keygen.c
new file mode 100644
index 0000000..f54da3c
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/fman_keygen.c
@@ -0,0 +1,783 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of NXP nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NXP ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NXP BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/slab.h>
+
+#include "fman_keygen.h"
+
+/* Maximum number of HW Ports */
+#define FMAN_MAX_NUM_OF_HW_PORTS		64
+
+/* Maximum number of KeyGen Schemes */
+#define FM_KG_MAX_NUM_OF_SCHEMES		32
+
+/* Number of generic KeyGen Generic Extract Command Registers */
+#define FM_KG_NUM_OF_GENERIC_REGS		8
+
+/* Dummy port ID */
+#define DUMMY_PORT_ID				0
+
+/* Select Scheme Value Register */
+#define KG_SCH_DEF_USE_KGSE_DV_0		2
+#define KG_SCH_DEF_USE_KGSE_DV_1		3
+
+/* Registers Shifting values */
+#define FM_KG_KGAR_NUM_SHIFT			16
+#define KG_SCH_DEF_L4_PORT_SHIFT		8
+#define KG_SCH_DEF_IP_ADDR_SHIFT		18
+#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT		24
+
+/* KeyGen Registers bit field masks: */
+
+/* Enable bit field mask for KeyGen General Configuration Register */
+#define FM_KG_KGGCR_EN				0x80000000
+
+/* KeyGen Global Registers bit field masks */
+#define FM_KG_KGAR_GO				0x80000000
+#define FM_KG_KGAR_READ				0x40000000
+#define FM_KG_KGAR_WRITE			0x00000000
+#define FM_KG_KGAR_SEL_SCHEME_ENTRY		0x00000000
+#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT		0x00008000
+
+#define FM_KG_KGAR_ERR				0x20000000
+#define FM_KG_KGAR_SEL_CLS_PLAN_ENTRY		0x01000000
+#define FM_KG_KGAR_SEL_PORT_ENTRY		0x02000000
+#define FM_KG_KGAR_SEL_PORT_WSEL_SP		0x00008000
+#define FM_KG_KGAR_SEL_PORT_WSEL_CPP		0x00004000
+
+/* Error events exceptions */
+#define FM_EX_KG_DOUBLE_ECC			0x80000000
+#define FM_EX_KG_KEYSIZE_OVERFLOW		0x40000000
+
+/* Scheme Registers bit field masks */
+#define KG_SCH_MODE_EN				0x80000000
+#define KG_SCH_VSP_NO_KSP_EN			0x80000000
+#define KG_SCH_HASH_CONFIG_SYM			0x40000000
+
+/* Known Protocol field codes */
+#define KG_SCH_KN_PORT_ID		0x80000000
+#define KG_SCH_KN_MACDST		0x40000000
+#define KG_SCH_KN_MACSRC		0x20000000
+#define KG_SCH_KN_TCI1			0x10000000
+#define KG_SCH_KN_TCI2			0x08000000
+#define KG_SCH_KN_ETYPE			0x04000000
+#define KG_SCH_KN_PPPSID		0x02000000
+#define KG_SCH_KN_PPPID			0x01000000
+#define KG_SCH_KN_MPLS1			0x00800000
+#define KG_SCH_KN_MPLS2			0x00400000
+#define KG_SCH_KN_MPLS_LAST		0x00200000
+#define KG_SCH_KN_IPSRC1		0x00100000
+#define KG_SCH_KN_IPDST1		0x00080000
+#define KG_SCH_KN_PTYPE1		0x00040000
+#define KG_SCH_KN_IPTOS_TC1		0x00020000
+#define KG_SCH_KN_IPV6FL1		0x00010000
+#define KG_SCH_KN_IPSRC2		0x00008000
+#define KG_SCH_KN_IPDST2		0x00004000
+#define KG_SCH_KN_PTYPE2		0x00002000
+#define KG_SCH_KN_IPTOS_TC2		0x00001000
+#define KG_SCH_KN_IPV6FL2		0x00000800
+#define KG_SCH_KN_GREPTYPE		0x00000400
+#define KG_SCH_KN_IPSEC_SPI		0x00000200
+#define KG_SCH_KN_IPSEC_NH		0x00000100
+#define KG_SCH_KN_IPPID			0x00000080
+#define KG_SCH_KN_L4PSRC		0x00000004
+#define KG_SCH_KN_L4PDST		0x00000002
+#define KG_SCH_KN_TFLG			0x00000001
+
+/* NIA values */
+#define NIA_ENG_BMI			0x00500000
+#define NIA_BMI_AC_ENQ_FRAME		0x00000002
+#define ENQUEUE_KG_DFLT_NIA		(NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)
+
+/* Hard-coded configuration:
+ * These values are used as hard-coded values for KeyGen configuration
+ * and they replace user selections for this hard-coded version
+ */
+
+/* Hash distribution shift */
+#define DEFAULT_HASH_DIST_FQID_SHIFT		0
+
+/* Hash shift */
+#define DEFAULT_HASH_SHIFT			0
+
+/* Symmetric hash usage:
+ * Warning:
+ * - the value for symmetric hash usage must be in accordance with hash
+ *	key defined below
+ * - according to tests performed, spreading is not working if symmetric
+ *	hash is set on true
+ * So ultimately symmetric hash functionality should be always disabled:
+ */
+#define DEFAULT_SYMMETRIC_HASH			false
+
+/* Hash Key extraction fields: */
+#define DEFAULT_HASH_KEY_EXTRACT_FIELDS		\
+	(KG_SCH_KN_IPSRC1 | KG_SCH_KN_IPDST1 | \
+	    KG_SCH_KN_L4PSRC | KG_SCH_KN_L4PDST)
+
+/* Default values to be used as hash key in case IPv4 or L4 (TCP, UDP)
+ * don't exist in the frame
+ */
+/* Default IPv4 address */
+#define DEFAULT_HASH_KEY_IPv4_ADDR		0x0A0A0A0A
+/* Default L4 port */
+#define DEFAULT_HASH_KEY_L4_PORT		0x0B0B0B0B
+
+/* KeyGen Memory Mapped Registers: */
+
+/* Scheme Configuration RAM Registers */
+struct fman_kg_scheme_regs {
+	u32 kgse_mode;		/* 0x100: MODE */
+	u32 kgse_ekfc;		/* 0x104: Extract Known Fields Command */
+	u32 kgse_ekdv;		/* 0x108: Extract Known Default Value */
+	u32 kgse_bmch;		/* 0x10C: Bit Mask Command High */
+	u32 kgse_bmcl;		/* 0x110: Bit Mask Command Low */
+	u32 kgse_fqb;		/* 0x114: Frame Queue Base */
+	u32 kgse_hc;		/* 0x118: Hash Command */
+	u32 kgse_ppc;		/* 0x11C: Policer Profile Command */
+	u32 kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
+			/* 0x120: Generic Extract Command */
+	u32 kgse_spc;
+		/* 0x140: KeyGen Scheme Entry Statistic Packet Counter */
+	u32 kgse_dv0;	/* 0x144: KeyGen Scheme Entry Default Value 0 */
+	u32 kgse_dv1;	/* 0x148: KeyGen Scheme Entry Default Value 1 */
+	u32 kgse_ccbs;
+		/* 0x14C: KeyGen Scheme Entry Coarse Classification Bit*/
+	u32 kgse_mv;	/* 0x150: KeyGen Scheme Entry Match vector */
+	u32 kgse_om;	/* 0x154: KeyGen Scheme Entry Operation Mode bits */
+	u32 kgse_vsp;
+		/* 0x158: KeyGen Scheme Entry Virtual Storage Profile */
+};
+
+/* Port Partition Configuration Registers */
+struct fman_kg_pe_regs {
+	u32 fmkg_pe_sp;		/* 0x100: KeyGen Port entry Scheme Partition */
+	u32 fmkg_pe_cpp;
+		/* 0x104: KeyGen Port Entry Classification Plan Partition */
+};
+
+/* General Configuration and Status Registers
+ * Global Statistic Counters
+ * KeyGen Global Registers
+ */
+struct fman_kg_regs {
+	u32 fmkg_gcr;	/* 0x000: KeyGen General Configuration Register */
+	u32 res004;	/* 0x004: Reserved */
+	u32 res008;	/* 0x008: Reserved */
+	u32 fmkg_eer;	/* 0x00C: KeyGen Error Event Register */
+	u32 fmkg_eeer;	/* 0x010: KeyGen Error Event Enable Register */
+	u32 res014;	/* 0x014: Reserved */
+	u32 res018;	/* 0x018: Reserved */
+	u32 fmkg_seer;	/* 0x01C: KeyGen Scheme Error Event Register */
+	u32 fmkg_seeer;	/* 0x020: KeyGen Scheme Error Event Enable Register */
+	u32 fmkg_gsr;	/* 0x024: KeyGen Global Status Register */
+	u32 fmkg_tpc;	/* 0x028: Total Packet Counter Register */
+	u32 fmkg_serc;	/* 0x02C: Soft Error Capture Register */
+	u32 res030[4];	/* 0x030: Reserved */
+	u32 fmkg_fdor;	/* 0x034: Frame Data Offset Register */
+	u32 fmkg_gdv0r;	/* 0x038: Global Default Value Register 0 */
+	u32 fmkg_gdv1r;	/* 0x03C: Global Default Value Register 1 */
+	u32 res04c[6];	/* 0x040: Reserved */
+	u32 fmkg_feer;	/* 0x044: Force Error Event Register */
+	u32 res068[38];	/* 0x048: Reserved */
+	union {
+		u32 fmkg_indirect[63];	/* 0x100: Indirect Access Registers */
+		struct fman_kg_scheme_regs fmkg_sch; /* Scheme Registers */
+		struct fman_kg_pe_regs fmkg_pe; /* Port Partition Registers */
+	};
+	u32 fmkg_ar;	/* 0x1FC: KeyGen Action Register */
+};
+
+/* KeyGen Scheme data */
+struct keygen_scheme {
+	bool used;	/* Specifies if this scheme is used */
+	u8 hw_port_id;
+		/* Hardware port ID
+		 * schemes sharing between multiple ports is not
+		 * currently supported
+		 * so we have only one port id bound to a scheme
+		 */
+	u32 base_fqid;
+		/* Base FQID:
+		 * Must be between 1 and 2^24-1
+		 * If hash is used and an even distribution is
+		 * expected according to hash_fqid_count,
+		 * base_fqid must be aligned to hash_fqid_count
+		 */
+	u32 hash_fqid_count;
+		/* FQ range for hash distribution:
+		 * Must be a power of 2
+		 * Represents the range of queues for spreading
+		 */
+	bool use_hashing;	/* Usage of Hashing and spreading over FQ */
+	bool symmetric_hash;	/* Symmetric Hash option usage */
+	u8 hashShift;
+		/* Hash result right shift.
+		 * Select the 24 bits out of the 64 hash result.
+		 * 0 means using the 24 LSB's, otherwise
+		 * use the 24 LSB's after shifting right
+		 */
+	u32 match_vector;	/* Match Vector */
+};
+
+/* KeyGen driver data */
+struct fman_keygen {
+	struct keygen_scheme schemes[FM_KG_MAX_NUM_OF_SCHEMES];
+				/* Array of schemes */
+	struct fman_kg_regs __iomem *keygen_regs;	/* KeyGen registers */
+};
+
+/* keygen_write_ar_wait
+ *
+ * Write Action Register with specified value, wait for GO bit field to be
+ * idle and then read the error
+ *
+ * regs: KeyGen registers
+ * fmkg_ar: Action Register value
+ *
+ * Return: Zero for success or error code in case of failure
+ */
+static int keygen_write_ar_wait(struct fman_kg_regs __iomem *regs, u32 fmkg_ar)
+{
+	iowrite32be(fmkg_ar, &regs->fmkg_ar);
+
+	/* Wait for GO bit field to be idle */
+	while (fmkg_ar & FM_KG_KGAR_GO)
+		fmkg_ar = ioread32be(&regs->fmkg_ar);
+
+	if (fmkg_ar & FM_KG_KGAR_ERR)
+		return -EINVAL;
+
+	return 0;
+}
+
+/* build_ar_scheme
+ *
+ * Build Action Register value for scheme settings
+ *
+ * scheme_id: Scheme ID
+ * update_counter: update scheme counter
+ * write: true for action to write the scheme or false for read action
+ *
+ * Return: AR value
+ */
+static u32 build_ar_scheme(u8 scheme_id, bool update_counter, bool write)
+{
+	u32 rw = (u32)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
+
+	return (u32)(FM_KG_KGAR_GO |
+			rw |
+			FM_KG_KGAR_SEL_SCHEME_ENTRY |
+			DUMMY_PORT_ID |
+			((u32)scheme_id << FM_KG_KGAR_NUM_SHIFT) |
+			(update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
+}
+
+/* build_ar_bind_scheme
+ *
+ * Build Action Register value for port binding to schemes
+ *
+ * hwport_id: HW Port ID
+ * write: true for action to write the bind or false for read action
+ *
+ * Return: AR value
+ */
+static u32 build_ar_bind_scheme(u8 hwport_id, bool write)
+{
+	u32 rw = write ? (u32)FM_KG_KGAR_WRITE : (u32)FM_KG_KGAR_READ;
+
+	return (u32)(FM_KG_KGAR_GO |
+			rw |
+			FM_KG_KGAR_SEL_PORT_ENTRY |
+			hwport_id |
+			FM_KG_KGAR_SEL_PORT_WSEL_SP);
+}
+
+/* keygen_write_sp
+ *
+ * Write Scheme Partition Register with specified value
+ *
+ * regs: KeyGen Registers
+ * sp: Scheme Partition register value
+ * add: true to add a scheme partition or false to clear
+ *
+ * Return: none
+ */
+static void keygen_write_sp(struct fman_kg_regs __iomem *regs, u32 sp, bool add)
+{
+	u32 tmp;
+
+	tmp = ioread32be(&regs->fmkg_pe.fmkg_pe_sp);
+
+	if (add)
+		tmp |= sp;
+	else
+		tmp &= ~sp;
+
+	iowrite32be(tmp, &regs->fmkg_pe.fmkg_pe_sp);
+}
+
+/* build_ar_bind_cls_plan
+ *
+ * Build Action Register value for Classification Plan
+ *
+ * hwport_id: HW Port ID
+ * write: true for action to write the CP or false for read action
+ *
+ * Return: AR value
+ */
+static u32 build_ar_bind_cls_plan(u8 hwport_id, bool write)
+{
+	u32 rw = write ? (u32)FM_KG_KGAR_WRITE : (u32)FM_KG_KGAR_READ;
+
+	return (u32)(FM_KG_KGAR_GO |
+			rw |
+			FM_KG_KGAR_SEL_PORT_ENTRY |
+			hwport_id |
+			FM_KG_KGAR_SEL_PORT_WSEL_CPP);
+}
+
+/* keygen_write_cpp
+ *
+ * Write Classification Plan Partition Register with specified value
+ *
+ * regs: KeyGen Registers
+ * cpp: CPP register value
+ *
+ * Return: none
+ */
+static void keygen_write_cpp(struct fman_kg_regs __iomem *regs, u32 cpp)
+{
+	iowrite32be(cpp, &regs->fmkg_pe.fmkg_pe_cpp);
+}
+
+/* keygen_write_scheme
+ *
+ * Write all Schemes Registers with specified values
+ *
+ * regs: KeyGen Registers
+ * scheme_id: Scheme ID
+ * scheme_regs: Scheme registers values desired to be written
+ * update_counter: update scheme counter
+ *
+ * Return: Zero for success or error code in case of failure
+ */
+static int keygen_write_scheme(struct fman_kg_regs __iomem *regs, u8 scheme_id,
+			       struct fman_kg_scheme_regs *scheme_regs,
+				bool update_counter)
+{
+	u32 ar_reg;
+	int err, i;
+
+	/* Write indirect scheme registers */
+	iowrite32be(scheme_regs->kgse_mode, &regs->fmkg_sch.kgse_mode);
+	iowrite32be(scheme_regs->kgse_ekfc, &regs->fmkg_sch.kgse_ekfc);
+	iowrite32be(scheme_regs->kgse_ekdv, &regs->fmkg_sch.kgse_ekdv);
+	iowrite32be(scheme_regs->kgse_bmch, &regs->fmkg_sch.kgse_bmch);
+	iowrite32be(scheme_regs->kgse_bmcl, &regs->fmkg_sch.kgse_bmcl);
+	iowrite32be(scheme_regs->kgse_fqb, &regs->fmkg_sch.kgse_fqb);
+	iowrite32be(scheme_regs->kgse_hc, &regs->fmkg_sch.kgse_hc);
+	iowrite32be(scheme_regs->kgse_ppc, &regs->fmkg_sch.kgse_ppc);
+	iowrite32be(scheme_regs->kgse_spc, &regs->fmkg_sch.kgse_spc);
+	iowrite32be(scheme_regs->kgse_dv0, &regs->fmkg_sch.kgse_dv0);
+	iowrite32be(scheme_regs->kgse_dv1, &regs->fmkg_sch.kgse_dv1);
+	iowrite32be(scheme_regs->kgse_ccbs, &regs->fmkg_sch.kgse_ccbs);
+	iowrite32be(scheme_regs->kgse_mv, &regs->fmkg_sch.kgse_mv);
+	iowrite32be(scheme_regs->kgse_om, &regs->fmkg_sch.kgse_om);
+	iowrite32be(scheme_regs->kgse_vsp, &regs->fmkg_sch.kgse_vsp);
+
+	for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
+		iowrite32be(scheme_regs->kgse_gec[i],
+			    &regs->fmkg_sch.kgse_gec[i]);
+
+	/* Write AR (Action register) */
+	ar_reg = build_ar_scheme(scheme_id, update_counter, true);
+	err = keygen_write_ar_wait(regs, ar_reg);
+	if (err != 0) {
+		pr_err("Writing Action Register failed\n");
+		return err;
+	}
+
+	return err;
+}
+
+/* get_free_scheme_id
+ *
+ * Find the first free scheme available to be used
+ *
+ * keygen: KeyGen handle
+ * scheme_id: pointer to scheme id
+ *
+ * Return: 0 on success, -EINVAL when the are no available free schemes
+ */
+static int get_free_scheme_id(struct fman_keygen *keygen, u8 *scheme_id)
+{
+	u8 i;
+
+	for (i = 0; i < FM_KG_MAX_NUM_OF_SCHEMES; i++)
+		if (!keygen->schemes[i].used) {
+			*scheme_id = i;
+			return 0;
+		}
+
+	return -EINVAL;
+}
+
+/* get_scheme
+ *
+ * Provides the scheme for specified ID
+ *
+ * keygen: KeyGen handle
+ * scheme_id: Scheme ID
+ *
+ * Return: handle to required scheme
+ */
+static struct keygen_scheme *get_scheme(struct fman_keygen *keygen,
+					u8 scheme_id)
+{
+	if (scheme_id >= FM_KG_MAX_NUM_OF_SCHEMES)
+		return NULL;
+	return &keygen->schemes[scheme_id];
+}
+
+/* keygen_bind_port_to_schemes
+ *
+ * Bind the port to schemes
+ *
+ * keygen: KeyGen handle
+ * scheme_id: id of the scheme to bind to
+ * bind: true to bind the port or false to unbind it
+ *
+ * Return: Zero for success or error code in case of failure
+ */
+static int keygen_bind_port_to_schemes(struct fman_keygen *keygen,
+				       u8 scheme_id,
+					bool bind)
+{
+	struct fman_kg_regs __iomem *keygen_regs = keygen->keygen_regs;
+	struct keygen_scheme *scheme;
+	u32 ar_reg;
+	u32 schemes_vector = 0;
+	int err;
+
+	scheme = get_scheme(keygen, scheme_id);
+	if (!scheme) {
+		pr_err("Requested Scheme does not exist\n");
+		return -EINVAL;
+	}
+	if (!scheme->used) {
+		pr_err("Cannot bind port to an invalid scheme\n");
+		return -EINVAL;
+	}
+
+	schemes_vector |= 1 << (31 - scheme_id);
+
+	ar_reg = build_ar_bind_scheme(scheme->hw_port_id, false);
+	err = keygen_write_ar_wait(keygen_regs, ar_reg);
+	if (err != 0) {
+		pr_err("Reading Action Register failed\n");
+		return err;
+	}
+
+	keygen_write_sp(keygen_regs, schemes_vector, bind);
+
+	ar_reg = build_ar_bind_scheme(scheme->hw_port_id, true);
+	err = keygen_write_ar_wait(keygen_regs, ar_reg);
+	if (err != 0) {
+		pr_err("Writing Action Register failed\n");
+		return err;
+	}
+
+	return 0;
+}
+
+/* keygen_scheme_setup
+ *
+ * Setup the scheme according to required configuration
+ *
+ * keygen: KeyGen handle
+ * scheme_id: scheme ID
+ * enable: true to enable scheme or false to disable it
+ *
+ * Return: Zero for success or error code in case of failure
+ */
+static int keygen_scheme_setup(struct fman_keygen *keygen, u8 scheme_id,
+			       bool enable)
+{
+	struct fman_kg_regs __iomem *keygen_regs = keygen->keygen_regs;
+	struct fman_kg_scheme_regs scheme_regs;
+	struct keygen_scheme *scheme;
+	u32 tmp_reg;
+	int err;
+
+	scheme = get_scheme(keygen, scheme_id);
+	if (!scheme) {
+		pr_err("Requested Scheme does not exist\n");
+		return -EINVAL;
+	}
+	if (enable && scheme->used) {
+		pr_err("The requested Scheme is already used\n");
+		return -EINVAL;
+	}
+
+	/* Clear scheme registers */
+	memset(&scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
+
+	/* Setup all scheme registers: */
+	tmp_reg = 0;
+
+	if (enable) {
+		/* Enable Scheme */
+		tmp_reg |= KG_SCH_MODE_EN;
+		/* Enqueue frame NIA */
+		tmp_reg |= ENQUEUE_KG_DFLT_NIA;
+	}
+
+	scheme_regs.kgse_mode = tmp_reg;
+
+	scheme_regs.kgse_mv = scheme->match_vector;
+
+	/* Scheme don't override StorageProfile:
+	 * valid only for DPAA_VERSION >= 11
+	 */
+	scheme_regs.kgse_vsp = KG_SCH_VSP_NO_KSP_EN;
+
+	/* Configure Hard-Coded Rx Hashing: */
+
+	if (scheme->use_hashing) {
+		/* configure kgse_ekfc */
+		scheme_regs.kgse_ekfc = DEFAULT_HASH_KEY_EXTRACT_FIELDS;
+
+		/* configure kgse_ekdv */
+		tmp_reg = 0;
+		tmp_reg |= (KG_SCH_DEF_USE_KGSE_DV_0 <<
+				KG_SCH_DEF_IP_ADDR_SHIFT);
+		tmp_reg |= (KG_SCH_DEF_USE_KGSE_DV_1 <<
+				KG_SCH_DEF_L4_PORT_SHIFT);
+		scheme_regs.kgse_ekdv = tmp_reg;
+
+		/* configure kgse_dv0 */
+		scheme_regs.kgse_dv0 = DEFAULT_HASH_KEY_IPv4_ADDR;
+		/* configure kgse_dv1 */
+		scheme_regs.kgse_dv1 = DEFAULT_HASH_KEY_L4_PORT;
+
+		/* configure kgse_hc  */
+		tmp_reg = 0;
+		tmp_reg |= ((scheme->hash_fqid_count - 1) <<
+				DEFAULT_HASH_DIST_FQID_SHIFT);
+		tmp_reg |= scheme->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
+
+		if (scheme->symmetric_hash) {
+			/* Normally extraction key should be verified if
+			 * complies with symmetric hash
+			 * But because extraction is hard-coded, we are sure
+			 * the key is symmetric
+			 */
+			tmp_reg |= KG_SCH_HASH_CONFIG_SYM;
+		}
+		scheme_regs.kgse_hc = tmp_reg;
+	} else {
+		scheme_regs.kgse_ekfc = 0;
+		scheme_regs.kgse_hc = 0;
+		scheme_regs.kgse_ekdv = 0;
+		scheme_regs.kgse_dv0 = 0;
+		scheme_regs.kgse_dv1 = 0;
+	}
+
+	/* configure kgse_fqb: Scheme FQID base */
+	tmp_reg = 0;
+	tmp_reg |= scheme->base_fqid;
+	scheme_regs.kgse_fqb = tmp_reg;
+
+	/* features not used by hard-coded configuration */
+	scheme_regs.kgse_bmch = 0;
+	scheme_regs.kgse_bmcl = 0;
+	scheme_regs.kgse_spc = 0;
+
+	/* Write scheme registers */
+	err = keygen_write_scheme(keygen_regs, scheme_id, &scheme_regs, true);
+	if (err != 0) {
+		pr_err("Writing scheme registers failed\n");
+		return err;
+	}
+
+	/* Update used field for Scheme */
+	scheme->used = enable;
+
+	return 0;
+}
+
+/* keygen_init
+ *
+ * KeyGen initialization:
+ * Initializes and enables KeyGen, allocate driver memory, setup registers,
+ * clear port bindings, invalidate all schemes
+ *
+ * keygen_regs: KeyGen registers base address
+ *
+ * Return: Handle to KeyGen driver
+ */
+struct fman_keygen *keygen_init(struct fman_kg_regs __iomem *keygen_regs)
+{
+	struct fman_keygen *keygen;
+	u32 ar;
+	int i;
+
+	/* Allocate memory for KeyGen driver */
+	keygen = kzalloc(sizeof(*keygen), GFP_KERNEL);
+	if (!keygen)
+		return NULL;
+
+	keygen->keygen_regs = keygen_regs;
+
+	/* KeyGen initialization (for Master partition):
+	 * Setup KeyGen registers
+	 */
+	iowrite32be(ENQUEUE_KG_DFLT_NIA, &keygen_regs->fmkg_gcr);
+
+	iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
+		    &keygen_regs->fmkg_eer);
+
+	iowrite32be(0, &keygen_regs->fmkg_fdor);
+	iowrite32be(0, &keygen_regs->fmkg_gdv0r);
+	iowrite32be(0, &keygen_regs->fmkg_gdv1r);
+
+	/* Clear binding between ports to schemes and classification plans
+	 * so that all ports are not bound to any scheme/classification plan
+	 */
+	for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
+		/* Clear all pe sp schemes registers */
+		keygen_write_sp(keygen_regs, 0xffffffff, false);
+		ar = build_ar_bind_scheme(i, true);
+		keygen_write_ar_wait(keygen_regs, ar);
+
+		/* Clear all pe cpp classification plans registers */
+		keygen_write_cpp(keygen_regs, 0);
+		ar = build_ar_bind_cls_plan(i, true);
+		keygen_write_ar_wait(keygen_regs, ar);
+	}
+
+	/* Enable all scheme interrupts */
+	iowrite32be(0xFFFFFFFF, &keygen_regs->fmkg_seer);
+	iowrite32be(0xFFFFFFFF, &keygen_regs->fmkg_seeer);
+
+	/* Enable KyeGen */
+	iowrite32be(ioread32be(&keygen_regs->fmkg_gcr) | FM_KG_KGGCR_EN,
+		    &keygen_regs->fmkg_gcr);
+
+	return keygen;
+}
+EXPORT_SYMBOL(keygen_init);
+
+/* keygen_port_hashing_init
+ *
+ * Initializes a port for Rx Hashing with specified configuration parameters
+ *
+ * keygen: KeyGen handle
+ * hw_port_id: HW Port ID
+ * hash_base_fqid: Hashing Base FQID used for spreading
+ * hash_size: Hashing size
+ *
+ * Return: Zero for success or error code in case of failure
+ */
+int keygen_port_hashing_init(struct fman_keygen *keygen, u8 hw_port_id,
+			     u32 hash_base_fqid, u32 hash_size)
+{
+	struct keygen_scheme *scheme;
+	u8 scheme_id;
+	int err;
+
+	/* Validate Scheme configuration parameters */
+	if (hash_base_fqid == 0 || (hash_base_fqid & ~0x00FFFFFF)) {
+		pr_err("Base FQID must be between 1 and 2^24-1\n");
+		return -EINVAL;
+	}
+	if (hash_size == 0 || (hash_size & (hash_size - 1)) != 0) {
+		pr_err("Hash size must be power of two\n");
+		return -EINVAL;
+	}
+
+	/* Find a free scheme */
+	err = get_free_scheme_id(keygen, &scheme_id);
+	if (err) {
+		pr_err("The maximum number of available Schemes has been exceeded\n");
+		return -EINVAL;
+	}
+
+	/* Create and configure Hard-Coded Scheme: */
+
+	scheme = get_scheme(keygen, scheme_id);
+	if (!scheme) {
+		pr_err("Requested Scheme does not exist\n");
+		return -EINVAL;
+	}
+	if (scheme->used) {
+		pr_err("The requested Scheme is already used\n");
+		return -EINVAL;
+	}
+
+	/* Clear all scheme fields because the scheme may have been
+	 * previously used
+	 */
+	memset(scheme, 0, sizeof(struct keygen_scheme));
+
+	/* Setup scheme: */
+	scheme->hw_port_id = hw_port_id;
+	scheme->use_hashing = true;
+	scheme->base_fqid = hash_base_fqid;
+	scheme->hash_fqid_count = hash_size;
+	scheme->symmetric_hash = DEFAULT_SYMMETRIC_HASH;
+	scheme->hashShift = DEFAULT_HASH_SHIFT;
+
+	/* All Schemes in hard-coded configuration
+	 * are Indirect Schemes
+	 */
+	scheme->match_vector = 0;
+
+	err = keygen_scheme_setup(keygen, scheme_id, true);
+	if (err != 0) {
+		pr_err("Scheme setup failed\n");
+		return err;
+	}
+
+	/* Bind Rx port to Scheme */
+	err = keygen_bind_port_to_schemes(keygen, scheme_id, true);
+	if (err != 0) {
+		pr_err("Binding port to schemes failed\n");
+		return err;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(keygen_port_hashing_init);
diff --git a/drivers/net/ethernet/freescale/fman/fman_keygen.h b/drivers/net/ethernet/freescale/fman/fman_keygen.h
new file mode 100644
index 0000000..c4640de
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/fman_keygen.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of NXP nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NXP ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NXP BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __KEYGEN_H
+#define __KEYGEN_H
+
+#include <linux/io.h>
+
+struct fman_keygen;
+struct fman_kg_regs;
+
+struct fman_keygen *keygen_init(struct fman_kg_regs __iomem *keygen_regs);
+
+int keygen_port_hashing_init(struct fman_keygen *keygen, u8 hw_port_id,
+			     u32 hash_base_fqid, u32 hash_size);
+
+#endif /* __KEYGEN_H */
diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c
index d51e6aa..f571b3c 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -44,6 +44,7 @@
 #include "fman.h"
 #include "fman_port.h"
 #include "fman_sp.h"
+#include "fman_keygen.h"
 
 /* Queue ID */
 #define DFLT_FQ_ID		0x00FFFFFF
@@ -184,6 +185,7 @@
 #define NIA_ENG_QMI_ENQ					0x00540000
 #define NIA_ENG_QMI_DEQ					0x00580000
 #define NIA_ENG_HWP					0x00440000
+#define NIA_ENG_HWK					0x00480000
 #define NIA_BMI_AC_ENQ_FRAME				0x00000002
 #define NIA_BMI_AC_TX_RELEASE				0x000002C0
 #define NIA_BMI_AC_RELEASE				0x000000C0
@@ -394,6 +396,8 @@ struct fman_port_bpools {
 struct fman_port_cfg {
 	u32 dflt_fqid;
 	u32 err_fqid;
+	u32 pcd_base_fqid;
+	u32 pcd_fqs_count;
 	u8 deq_sp;
 	bool deq_high_priority;
 	enum fman_port_deq_type deq_type;
@@ -1271,6 +1275,10 @@ static void set_rx_dflt_cfg(struct fman_port *port,
 		port_params->specific_params.rx_params.err_fqid;
 	port->cfg->dflt_fqid =
 		port_params->specific_params.rx_params.dflt_fqid;
+	port->cfg->pcd_base_fqid =
+		port_params->specific_params.rx_params.pcd_base_fqid;
+	port->cfg->pcd_fqs_count =
+		port_params->specific_params.rx_params.pcd_fqs_count;
 }
 
 static void set_tx_dflt_cfg(struct fman_port *port,
@@ -1398,6 +1406,24 @@ int fman_port_config(struct fman_port *port, struct fman_port_params *params)
 EXPORT_SYMBOL(fman_port_config);
 
 /**
+ * fman_port_use_kg_hash
+ * port:        A pointer to a FM Port module.
+ * Sets the HW KeyGen or the BMI as HW Parser next engine, enabling
+ * or bypassing the KeyGen hashing of Rx traffic
+ */
+void fman_port_use_kg_hash(struct fman_port *port, bool enable)
+{
+	if (enable)
+		/* After the Parser frames go to KeyGen */
+		iowrite32be(NIA_ENG_HWK, &port->bmi_regs->rx.fmbm_rfpne);
+	else
+		/* After the Parser frames go to BMI */
+		iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME,
+			    &port->bmi_regs->rx.fmbm_rfpne);
+}
+EXPORT_SYMBOL(fman_port_use_kg_hash);
+
+/**
  * fman_port_init
  * port:	A pointer to a FM Port module.
  * Initializes the FM PORT module by defining the software structure and
@@ -1407,9 +1433,10 @@ EXPORT_SYMBOL(fman_port_config);
  */
 int fman_port_init(struct fman_port *port)
 {
+	struct fman_port_init_params params;
+	struct fman_keygen *keygen;
 	struct fman_port_cfg *cfg;
 	int err;
-	struct fman_port_init_params params;
 
 	if (is_init_done(port->cfg))
 		return -EINVAL;
@@ -1472,6 +1499,17 @@ int fman_port_init(struct fman_port *port)
 	if (err)
 		return err;
 
+	if (port->cfg->pcd_fqs_count) {
+		keygen = port->dts_params.fman->keygen;
+		err = keygen_port_hashing_init(keygen, port->port_id,
+					       port->cfg->pcd_base_fqid,
+					       port->cfg->pcd_fqs_count);
+		if (err)
+			return err;
+
+		fman_port_use_kg_hash(port, true);
+	}
+
 	kfree(port->cfg);
 	port->cfg = NULL;
 
diff --git a/drivers/net/ethernet/freescale/fman/fman_port.h b/drivers/net/ethernet/freescale/fman/fman_port.h
index 8ba9017..5a99611 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.h
+++ b/drivers/net/ethernet/freescale/fman/fman_port.h
@@ -100,6 +100,9 @@ struct fman_port;
 struct fman_port_rx_params {
 	u32 err_fqid;			/* Error Queue Id. */
 	u32 dflt_fqid;			/* Default Queue Id. */
+	u32 pcd_base_fqid;		/* PCD base Queue Id. */
+	u32 pcd_fqs_count;		/* Number of PCD FQs. */
+
 	/* Which external buffer pools are used
 	 * (up to FMAN_PORT_MAX_EXT_POOLS_NUM), and their sizes.
 	 */
@@ -134,6 +137,8 @@ struct fman_port_params {
 
 int fman_port_config(struct fman_port *port, struct fman_port_params *params);
 
+void fman_port_use_kg_hash(struct fman_port *port, bool enable);
+
 int fman_port_init(struct fman_port *port);
 
 int fman_port_cfg_buf_prefix_content(struct fman_port *port,
-- 
2.1.0

^ permalink raw reply related

* [PATCH v4 3/7] dpaa_eth: use multiple Rx frame queues
From: Madalin Bucur @ 2017-08-27 13:13 UTC (permalink / raw)
  To: netdev, davem; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1503839623-3906-1-git-send-email-madalin.bucur@nxp.com>

Add a block of 128 Rx frame queues per port. The FMan hardware will
send traffic on one of these queues based on the FMan port Parse
Classify Distribute setup. The hash computed by the FMan Keygen
block will select the Rx FQ.

Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c     | 50 +++++++++++++++++++---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h     |  1 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   |  3 ++
 3 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index c7fa285..6d89e74 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -158,7 +158,7 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
 #define DPAA_RX_PRIV_DATA_SIZE	(u16)(DPAA_TX_PRIV_DATA_SIZE + \
 					dpaa_rx_extra_headroom)
 
-#define DPAA_ETH_RX_QUEUES	128
+#define DPAA_ETH_PCD_RXQ_NUM	128
 
 #define DPAA_ENQUEUE_RETRIES	100000
 
@@ -169,6 +169,7 @@ struct fm_port_fqs {
 	struct dpaa_fq *tx_errq;
 	struct dpaa_fq *rx_defq;
 	struct dpaa_fq *rx_errq;
+	struct dpaa_fq *rx_pcdq;
 };
 
 /* All the dpa bps in use at any moment */
@@ -628,6 +629,7 @@ static inline void dpaa_assign_wq(struct dpaa_fq *fq, int idx)
 		fq->wq = 5;
 		break;
 	case FQ_TYPE_RX_DEFAULT:
+	case FQ_TYPE_RX_PCD:
 		fq->wq = 6;
 		break;
 	case FQ_TYPE_TX:
@@ -688,6 +690,7 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct list_head *list,
 			      struct fm_port_fqs *port_fqs)
 {
 	struct dpaa_fq *dpaa_fq;
+	u32 fq_base, fq_base_aligned, i;
 
 	dpaa_fq = dpaa_fq_alloc(dev, 0, 1, list, FQ_TYPE_RX_ERROR);
 	if (!dpaa_fq)
@@ -701,6 +704,26 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct list_head *list,
 
 	port_fqs->rx_defq = &dpaa_fq[0];
 
+	/* the PCD FQIDs range needs to be aligned for correct operation */
+	if (qman_alloc_fqid_range(&fq_base, 2 * DPAA_ETH_PCD_RXQ_NUM))
+		goto fq_alloc_failed;
+
+	fq_base_aligned = ALIGN(fq_base, DPAA_ETH_PCD_RXQ_NUM);
+
+	for (i = fq_base; i < fq_base_aligned; i++)
+		qman_release_fqid(i);
+
+	for (i = fq_base_aligned + DPAA_ETH_PCD_RXQ_NUM;
+	     i < (fq_base + 2 * DPAA_ETH_PCD_RXQ_NUM); i++)
+		qman_release_fqid(i);
+
+	dpaa_fq = dpaa_fq_alloc(dev, fq_base_aligned, DPAA_ETH_PCD_RXQ_NUM,
+				list, FQ_TYPE_RX_PCD);
+	if (!dpaa_fq)
+		goto fq_alloc_failed;
+
+	port_fqs->rx_pcdq = &dpaa_fq[0];
+
 	if (!dpaa_fq_alloc(dev, 0, DPAA_ETH_TXQ_NUM, list, FQ_TYPE_TX_CONF_MQ))
 		goto fq_alloc_failed;
 
@@ -870,13 +893,14 @@ static void dpaa_fq_setup(struct dpaa_priv *priv,
 			  const struct dpaa_fq_cbs *fq_cbs,
 			  struct fman_port *tx_port)
 {
-	int egress_cnt = 0, conf_cnt = 0, num_portals = 0, cpu;
+	int egress_cnt = 0, conf_cnt = 0, num_portals = 0, portal_cnt = 0, cpu;
 	const cpumask_t *affine_cpus = qman_affine_cpus();
-	u16 portals[NR_CPUS];
+	u16 channels[NR_CPUS];
 	struct dpaa_fq *fq;
 
 	for_each_cpu(cpu, affine_cpus)
-		portals[num_portals++] = qman_affine_channel(cpu);
+		channels[num_portals++] = qman_affine_channel(cpu);
+
 	if (num_portals == 0)
 		dev_err(priv->net_dev->dev.parent,
 			"No Qman software (affine) channels found");
@@ -890,6 +914,12 @@ static void dpaa_fq_setup(struct dpaa_priv *priv,
 		case FQ_TYPE_RX_ERROR:
 			dpaa_setup_ingress(priv, fq, &fq_cbs->rx_errq);
 			break;
+		case FQ_TYPE_RX_PCD:
+			if (!num_portals)
+				continue;
+			dpaa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
+			fq->channel = channels[portal_cnt++ % num_portals];
+			break;
 		case FQ_TYPE_TX:
 			dpaa_setup_egress(priv, fq, tx_port,
 					  &fq_cbs->egress_ern);
@@ -1039,7 +1069,8 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool td_enable)
 		/* Put all the ingress queues in our "ingress CGR". */
 		if (priv->use_ingress_cgr &&
 		    (dpaa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
-		     dpaa_fq->fq_type == FQ_TYPE_RX_ERROR)) {
+		     dpaa_fq->fq_type == FQ_TYPE_RX_ERROR ||
+		     dpaa_fq->fq_type == FQ_TYPE_RX_PCD)) {
 			initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_CGID);
 			initfq.fqd.fq_ctrl |= cpu_to_be16(QM_FQCTRL_CGE);
 			initfq.fqd.cgid = (u8)priv->ingress_cgr.cgrid;
@@ -1170,7 +1201,7 @@ static int dpaa_eth_init_tx_port(struct fman_port *port, struct dpaa_fq *errq,
 
 static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps,
 				 size_t count, struct dpaa_fq *errq,
-				 struct dpaa_fq *defq,
+				 struct dpaa_fq *defq, struct dpaa_fq *pcdq,
 				 struct dpaa_buffer_layout *buf_layout)
 {
 	struct fman_buffer_prefix_content buf_prefix_content;
@@ -1190,6 +1221,10 @@ static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps,
 	rx_p = &params.specific_params.rx_params;
 	rx_p->err_fqid = errq->fqid;
 	rx_p->dflt_fqid = defq->fqid;
+	if (pcdq) {
+		rx_p->pcd_base_fqid = pcdq->fqid;
+		rx_p->pcd_fqs_count = DPAA_ETH_PCD_RXQ_NUM;
+	}
 
 	count = min(ARRAY_SIZE(rx_p->ext_buf_pools.ext_buf_pool), count);
 	rx_p->ext_buf_pools.num_of_pools_used = (u8)count;
@@ -1234,7 +1269,8 @@ static int dpaa_eth_init_ports(struct mac_device *mac_dev,
 		return err;
 
 	err = dpaa_eth_init_rx_port(rxport, bps, count, port_fqs->rx_errq,
-				    port_fqs->rx_defq, &buf_layout[RX]);
+				    port_fqs->rx_defq, port_fqs->rx_pcdq,
+				    &buf_layout[RX]);
 
 	return err;
 }
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index 9941a78..496a12c 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -52,6 +52,7 @@
 enum dpaa_fq_type {
 	FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */
 	FQ_TYPE_RX_ERROR,	/* Rx Error FQs */
+	FQ_TYPE_RX_PCD,		/* Rx Parse Classify Distribute FQs */
 	FQ_TYPE_TX,		/* "Real" Tx FQs */
 	FQ_TYPE_TX_CONFIRM,	/* Tx default Conf FQ (actually an Rx FQ) */
 	FQ_TYPE_TX_CONF_MQ,	/* Tx conf FQs (one for each Tx FQ) */
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c
index ec75d1c..0d9b185 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c
@@ -71,6 +71,9 @@ static ssize_t dpaa_eth_show_fqids(struct device *dev,
 		case FQ_TYPE_RX_ERROR:
 			str = "Rx error";
 			break;
+		case FQ_TYPE_RX_PCD:
+			str = "Rx PCD";
+			break;
 		case FQ_TYPE_TX_CONFIRM:
 			str = "Tx default confirmation";
 			break;
-- 
2.1.0

^ permalink raw reply related

* [PATCH v4 4/7] dpaa_eth: enable Rx hashing control
From: Madalin Bucur @ 2017-08-27 13:13 UTC (permalink / raw)
  To: netdev, davem; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1503839623-3906-1-git-send-email-madalin.bucur@nxp.com>

Allow ethtool control of the Rx flow hashing. By default RSS is
enabled, this allows to turn it off by bypassing the FMan Keygen
block and sending all traffic on the default Rx frame queue.

Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 113 +++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index aad825088..965f652 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -399,6 +399,117 @@ static void dpaa_get_strings(struct net_device *net_dev, u32 stringset,
 	memcpy(strings, dpaa_stats_global, size);
 }
 
+static int dpaa_get_hash_opts(struct net_device *dev,
+			      struct ethtool_rxnfc *cmd)
+{
+	cmd->data = 0;
+
+	switch (cmd->flow_type) {
+	case TCP_V4_FLOW:
+	case TCP_V6_FLOW:
+	case UDP_V4_FLOW:
+	case UDP_V6_FLOW:
+		cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		/* Fall through */
+	case IPV4_FLOW:
+	case IPV6_FLOW:
+	case SCTP_V4_FLOW:
+	case SCTP_V6_FLOW:
+	case AH_ESP_V4_FLOW:
+	case AH_ESP_V6_FLOW:
+	case AH_V4_FLOW:
+	case AH_V6_FLOW:
+	case ESP_V4_FLOW:
+	case ESP_V6_FLOW:
+		cmd->data |= RXH_IP_SRC | RXH_IP_DST;
+		break;
+	default:
+		cmd->data = 0;
+		break;
+	}
+
+	return 0;
+}
+
+static int dpaa_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+			  u32 *unused)
+{
+	int ret = -EOPNOTSUPP;
+
+	switch (cmd->cmd) {
+	case ETHTOOL_GRXFH:
+		ret = dpaa_get_hash_opts(dev, cmd);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static void dpaa_set_hash(struct net_device *net_dev, bool enable)
+{
+	struct mac_device *mac_dev;
+	struct fman_port *rxport;
+	struct dpaa_priv *priv;
+
+	priv = netdev_priv(net_dev);
+	mac_dev = priv->mac_dev;
+	rxport = mac_dev->port[0];
+
+	fman_port_use_kg_hash(rxport, enable);
+}
+
+static int dpaa_set_hash_opts(struct net_device *dev,
+			      struct ethtool_rxnfc *nfc)
+{
+	int ret = -EINVAL;
+
+	/* we support hashing on IPv4/v6 src/dest IP and L4 src/dest port */
+	if (nfc->data &
+	    ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3))
+		return -EINVAL;
+
+	switch (nfc->flow_type) {
+	case TCP_V4_FLOW:
+	case TCP_V6_FLOW:
+	case UDP_V4_FLOW:
+	case UDP_V6_FLOW:
+	case IPV4_FLOW:
+	case IPV6_FLOW:
+	case SCTP_V4_FLOW:
+	case SCTP_V6_FLOW:
+	case AH_ESP_V4_FLOW:
+	case AH_ESP_V6_FLOW:
+	case AH_V4_FLOW:
+	case AH_V6_FLOW:
+	case ESP_V4_FLOW:
+	case ESP_V6_FLOW:
+		dpaa_set_hash(dev, !!nfc->data);
+		ret = 0;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int dpaa_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+	int ret = -EOPNOTSUPP;
+
+	switch (cmd->cmd) {
+	case ETHTOOL_SRXFH:
+		ret = dpaa_set_hash_opts(dev, cmd);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
 const struct ethtool_ops dpaa_ethtool_ops = {
 	.get_drvinfo = dpaa_get_drvinfo,
 	.get_msglevel = dpaa_get_msglevel,
@@ -412,4 +523,6 @@ const struct ethtool_ops dpaa_ethtool_ops = {
 	.get_strings = dpaa_get_strings,
 	.get_link_ksettings = dpaa_get_link_ksettings,
 	.set_link_ksettings = dpaa_set_link_ksettings,
+	.get_rxnfc = dpaa_get_rxnfc,
+	.set_rxnfc = dpaa_set_rxnfc,
 };
-- 
2.1.0

^ permalink raw reply related

* [PATCH v4 6/7] Documentation: networking: add RSS information
From: Madalin Bucur @ 2017-08-27 13:13 UTC (permalink / raw)
  To: netdev, davem; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1503839623-3906-1-git-send-email-madalin.bucur@nxp.com>

Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
---
 Documentation/networking/dpaa.txt | 68 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/Documentation/networking/dpaa.txt b/Documentation/networking/dpaa.txt
index 76e016d..f88194f 100644
--- a/Documentation/networking/dpaa.txt
+++ b/Documentation/networking/dpaa.txt
@@ -13,6 +13,7 @@ Contents
 	- Configuring DPAA Ethernet in your kernel
 	- DPAA Ethernet Frame Processing
 	- DPAA Ethernet Features
+	- DPAA IRQ Affinity and Receive Side Scaling
 	- Debugging
 
 DPAA Ethernet Overview
@@ -147,7 +148,10 @@ gradually.
 
 The driver has Rx and Tx checksum offloading for UDP and TCP. Currently the Rx
 checksum offload feature is enabled by default and cannot be controlled through
-ethtool.
+ethtool. Also, rx-flow-hash and rx-hashing was added. The addition of RSS
+provides a big performance boost for the forwarding scenarios, allowing
+different traffic flows received by one interface to be processed by different
+CPUs in parallel.
 
 The driver has support for multiple prioritized Tx traffic classes. Priorities
 range from 0 (lowest) to 3 (highest). These are mapped to HW workqueues with
@@ -166,6 +170,68 @@ classes as follows:
 tc qdisc add dev <int> root handle 1: \
 	 mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 hw 1
 
+DPAA IRQ Affinity and Receive Side Scaling
+==========================================
+
+Traffic coming on the DPAA Rx queues or on the DPAA Tx confirmation
+queues is seen by the CPU as ingress traffic on a certain portal.
+The DPAA QMan portal interrupts are affined each to a certain CPU.
+The same portal interrupt services all the QMan portal consumers.
+
+By default the DPAA Ethernet driver enables RSS, making use of the
+DPAA FMan Parser and Keygen blocks to distribute traffic on 128
+hardware frame queues using a hash on IP v4/v6 source and destination
+and L4 source and destination ports, in present in the received frame.
+When RSS is disabled, all traffic received by a certain interface is
+received on the default Rx frame queue. The default DPAA Rx frame
+queues are configured to put the received traffic into a pool channel
+that allows any available CPU portal to dequeue the ingress traffic.
+The default frame queues have the HOLDACTIVE option set, ensuring that
+traffic bursts from a certain queue are serviced by the same CPU.
+This ensures a very low rate of frame reordering. A drawback of this
+is that only one CPU at a time can service the traffic received by a
+certain interface when RSS is not enabled.
+
+To implement RSS, the DPAA Ethernet driver allocates an extra set of
+128 Rx frame queues that are configured to dedicated channels, in a
+round-robin manner. The mapping of the frame queues to CPUs is now
+hardcoded, there is no indirection table to move traffic for a certain
+FQ (hash result) to another CPU. The ingress traffic arriving on one
+of these frame queues will arrive at the same portal and will always
+be processed by the same CPU. This ensures intra-flow order preservation
+and workload distribution for multiple traffic flows.
+
+RSS can be turned off for a certain interface using ethtool, i.e.
+
+	# ethtool -N fm1-mac9 rx-flow-hash tcp4 ""
+
+To turn it back on, one needs to set rx-flow-hash for tcp4/6 or udp4/6:
+
+	# ethtool -N fm1-mac9 rx-flow-hash udp4 sfdn
+
+There is no independent control for individual protocols, any command
+run for one of tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 is
+going to control the rx-flow-hashing for all protocols on that interface.
+
+Besides using the FMan Keygen computed hash for spreading traffic on the
+128 Rx FQs, the DPAA Ethernet driver also sets the skb hash value when
+the NETIF_F_RXHASH feature is on (active by default). This can be turned
+on or off through ethtool, i.e.:
+
+	# ethtool -K fm1-mac9 rx-hashing off
+	# ethtool -k fm1-mac9 | grep hash
+	receive-hashing: off
+	# ethtool -K fm1-mac9 rx-hashing on
+	Actual changes:
+	receive-hashing: on
+	# ethtool -k fm1-mac9 | grep hash
+	receive-hashing: on
+
+Please note that Rx hashing depends upon the rx-flow-hashing being on
+for that interface - turning off rx-flow-hashing will also disable the
+rx-hashing (without ethtool reporting it as off as that depends on the
+NETIF_F_RXHASH feature flag).
+
 Debugging
 =========
 
-- 
2.1.0

^ permalink raw reply related

* [PATCH v4 1/7] fsl/fman: move struct fman to header file
From: Madalin Bucur @ 2017-08-27 13:13 UTC (permalink / raw)
  To: netdev, davem; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1503839623-3906-1-git-send-email-madalin.bucur@nxp.com>

Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.c      | 80 +------------------------
 drivers/net/ethernet/freescale/fman/fman.h      | 75 +++++++++++++++++++++++
 drivers/net/ethernet/freescale/fman/fman_port.c |  8 +--
 3 files changed, 82 insertions(+), 81 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c
index e714b8f..8179cc1 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -32,9 +32,6 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include "fman.h"
-#include "fman_muram.h"
-
 #include <linux/fsl/guts.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -46,6 +43,9 @@
 #include <linux/interrupt.h>
 #include <linux/libfdt_env.h>
 
+#include "fman.h"
+#include "fman_muram.h"
+
 /* General defines */
 #define FMAN_LIODN_TBL			64	/* size of LIODN table */
 #define MAX_NUM_OF_MACS			10
@@ -564,80 +564,6 @@ struct fman_cfg {
 	u32 qmi_def_tnums_thresh;
 };
 
-/* Structure that holds information received from device tree */
-struct fman_dts_params {
-	void __iomem *base_addr;		/* FMan virtual address */
-	struct resource *res;			/* FMan memory resource */
-	u8 id;					/* FMan ID */
-
-	int err_irq;				/* FMan Error IRQ */
-
-	u16 clk_freq;				/* FMan clock freq (In Mhz) */
-
-	u32 qman_channel_base;			/* QMan channels base */
-	u32 num_of_qman_channels;		/* Number of QMan channels */
-
-	struct resource muram_res;		/* MURAM resource */
-};
-
-/** fman_exceptions_cb
- * fman		- Pointer to FMan
- * exception	- The exception.
- *
- * Exceptions user callback routine, will be called upon an exception
- * passing the exception identification.
- *
- * Return: irq status
- */
-typedef irqreturn_t (fman_exceptions_cb)(struct fman *fman,
-					 enum fman_exceptions exception);
-
-/** fman_bus_error_cb
- * fman		- Pointer to FMan
- * port_id	- Port id
- * addr		- Address that caused the error
- * tnum		- Owner of error
- * liodn	- Logical IO device number
- *
- * Bus error user callback routine, will be called upon bus error,
- * passing parameters describing the errors and the owner.
- *
- * Return: IRQ status
- */
-typedef irqreturn_t (fman_bus_error_cb)(struct fman *fman, u8 port_id,
-					u64 addr, u8 tnum, u16 liodn);
-
-struct fman {
-	struct device *dev;
-	void __iomem *base_addr;
-	struct fman_intr_src intr_mng[FMAN_EV_CNT];
-
-	struct fman_fpm_regs __iomem *fpm_regs;
-	struct fman_bmi_regs __iomem *bmi_regs;
-	struct fman_qmi_regs __iomem *qmi_regs;
-	struct fman_dma_regs __iomem *dma_regs;
-	struct fman_hwp_regs __iomem *hwp_regs;
-	fman_exceptions_cb *exception_cb;
-	fman_bus_error_cb *bus_error_cb;
-	/* Spinlock for FMan use */
-	spinlock_t spinlock;
-	struct fman_state_struct *state;
-
-	struct fman_cfg *cfg;
-	struct muram_info *muram;
-	/* cam section in muram */
-	unsigned long cam_offset;
-	size_t cam_size;
-	/* Fifo in MURAM */
-	unsigned long fifo_offset;
-	size_t fifo_size;
-
-	u32 liodn_base[64];
-	u32 liodn_offset[64];
-
-	struct fman_dts_params dts_params;
-};
-
 static irqreturn_t fman_exceptions(struct fman *fman,
 				   enum fman_exceptions exception)
 {
diff --git a/drivers/net/ethernet/freescale/fman/fman.h b/drivers/net/ethernet/freescale/fman/fman.h
index f53e147..1015dac 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -34,6 +34,8 @@
 #define __FM_H
 
 #include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/of_irq.h>
 
 /* FM Frame descriptor macros  */
 /* Frame queue Context Override */
@@ -274,6 +276,79 @@ struct fman_intr_src {
 	void *src_handle;
 };
 
+/** fman_exceptions_cb
+ * fman         - Pointer to FMan
+ * exception    - The exception.
+ *
+ * Exceptions user callback routine, will be called upon an exception
+ * passing the exception identification.
+ *
+ * Return: irq status
+ */
+typedef irqreturn_t (fman_exceptions_cb)(struct fman *fman,
+					 enum fman_exceptions exception);
+/** fman_bus_error_cb
+ * fman         - Pointer to FMan
+ * port_id      - Port id
+ * addr         - Address that caused the error
+ * tnum         - Owner of error
+ * liodn        - Logical IO device number
+ *
+ * Bus error user callback routine, will be called upon bus error,
+ * passing parameters describing the errors and the owner.
+ *
+ * Return: IRQ status
+ */
+typedef irqreturn_t (fman_bus_error_cb)(struct fman *fman, u8 port_id,
+					u64 addr, u8 tnum, u16 liodn);
+
+/* Structure that holds information received from device tree */
+struct fman_dts_params {
+	void __iomem *base_addr;                /* FMan virtual address */
+	struct resource *res;                   /* FMan memory resource */
+	u8 id;                                  /* FMan ID */
+
+	int err_irq;                            /* FMan Error IRQ */
+
+	u16 clk_freq;                           /* FMan clock freq (In Mhz) */
+
+	u32 qman_channel_base;                  /* QMan channels base */
+	u32 num_of_qman_channels;               /* Number of QMan channels */
+
+	struct resource muram_res;              /* MURAM resource */
+};
+
+struct fman {
+	struct device *dev;
+	void __iomem *base_addr;
+	struct fman_intr_src intr_mng[FMAN_EV_CNT];
+
+	struct fman_fpm_regs __iomem *fpm_regs;
+	struct fman_bmi_regs __iomem *bmi_regs;
+	struct fman_qmi_regs __iomem *qmi_regs;
+	struct fman_dma_regs __iomem *dma_regs;
+	struct fman_hwp_regs __iomem *hwp_regs;
+	fman_exceptions_cb *exception_cb;
+	fman_bus_error_cb *bus_error_cb;
+	/* Spinlock for FMan use */
+	spinlock_t spinlock;
+	struct fman_state_struct *state;
+
+	struct fman_cfg *cfg;
+	struct muram_info *muram;
+	/* cam section in muram */
+	unsigned long cam_offset;
+	size_t cam_size;
+	/* Fifo in MURAM */
+	unsigned long fifo_offset;
+	size_t fifo_size;
+
+	u32 liodn_base[64];
+	u32 liodn_offset[64];
+
+	struct fman_dts_params dts_params;
+};
+
 /* Structure for port-FM communication during fman_port_init. */
 struct fman_port_init_params {
 	u8 port_id;			/* port Id */
diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c
index 49bfa11..d51e6aa 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -32,10 +32,6 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include "fman_port.h"
-#include "fman.h"
-#include "fman_sp.h"
-
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -45,6 +41,10 @@
 #include <linux/delay.h>
 #include <linux/libfdt_env.h>
 
+#include "fman.h"
+#include "fman_port.h"
+#include "fman_sp.h"
+
 /* Queue ID */
 #define DFLT_FQ_ID		0x00FFFFFF
 
-- 
2.1.0

^ permalink raw reply related

* [PATCH v4 5/7] dpaa_eth: add NETIF_F_RXHASH
From: Madalin Bucur @ 2017-08-27 13:13 UTC (permalink / raw)
  To: netdev, davem; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1503839623-3906-1-git-send-email-madalin.bucur@nxp.com>

Set the skb hash when then FMan Keygen hash result is available.

Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c     | 23 +++++++++++++++++++---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h     |  1 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c |  9 +++++++--
 drivers/net/ethernet/freescale/fman/fman_port.c    | 11 +++++++++++
 drivers/net/ethernet/freescale/fman/fman_port.h    |  2 ++
 5 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 6d89e74..73ca8d7 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -236,7 +236,7 @@ static int dpaa_netdev_init(struct net_device *net_dev,
 	net_dev->max_mtu = dpaa_get_max_mtu();
 
 	net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-				 NETIF_F_LLTX);
+				 NETIF_F_LLTX | NETIF_F_RXHASH);
 
 	net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
 	/* The kernels enables GSO automatically, if we declare NETIF_F_SG.
@@ -2237,12 +2237,13 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
 	dma_addr_t addr = qm_fd_addr(fd);
 	enum qm_fd_format fd_format;
 	struct net_device *net_dev;
-	u32 fd_status;
+	u32 fd_status, hash_offset;
 	struct dpaa_bp *dpaa_bp;
 	struct dpaa_priv *priv;
 	unsigned int skb_len;
 	struct sk_buff *skb;
 	int *count_ptr;
+	void *vaddr;
 
 	fd_status = be32_to_cpu(fd->status);
 	fd_format = qm_fd_get_format(fd);
@@ -2288,7 +2289,8 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
 	dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE);
 
 	/* prefetch the first 64 bytes of the frame or the SGT start */
-	prefetch(phys_to_virt(addr) + qm_fd_get_offset(fd));
+	vaddr = phys_to_virt(addr);
+	prefetch(vaddr + qm_fd_get_offset(fd));
 
 	fd_format = qm_fd_get_format(fd);
 	/* The only FD types that we may receive are contig and S/G */
@@ -2309,6 +2311,18 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
 
 	skb->protocol = eth_type_trans(skb, net_dev);
 
+	if (net_dev->features & NETIF_F_RXHASH && priv->keygen_in_use &&
+	    !fman_port_get_hash_result_offset(priv->mac_dev->port[RX],
+					      &hash_offset)) {
+		enum pkt_hash_types type;
+
+		/* if L4 exists, it was used in the hash generation */
+		type = be32_to_cpu(fd->status) & FM_FD_STAT_L4CV ?
+			PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3;
+		skb_set_hash(skb, be32_to_cpu(*(u32 *)(vaddr + hash_offset)),
+			     type);
+	}
+
 	skb_len = skb->len;
 
 	if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
@@ -2774,6 +2788,9 @@ static int dpaa_eth_probe(struct platform_device *pdev)
 	if (err)
 		goto init_ports_failed;
 
+	/* Rx traffic distribution based on keygen hashing defaults to on */
+	priv->keygen_in_use = true;
+
 	priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
 	if (!priv->percpu_priv) {
 		dev_err(dev, "devm_alloc_percpu() failed\n");
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index 496a12c..bd94220 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -159,6 +159,7 @@ struct dpaa_priv {
 	struct list_head dpaa_fq_list;
 
 	u8 num_tc;
+	bool keygen_in_use;
 	u32 msg_enable;	/* net_device message level */
 
 	struct {
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index 965f652..faea674 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -402,6 +402,8 @@ static void dpaa_get_strings(struct net_device *net_dev, u32 stringset,
 static int dpaa_get_hash_opts(struct net_device *dev,
 			      struct ethtool_rxnfc *cmd)
 {
+	struct dpaa_priv *priv = netdev_priv(dev);
+
 	cmd->data = 0;
 
 	switch (cmd->flow_type) {
@@ -409,7 +411,8 @@ static int dpaa_get_hash_opts(struct net_device *dev,
 	case TCP_V6_FLOW:
 	case UDP_V4_FLOW:
 	case UDP_V6_FLOW:
-		cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		if (priv->keygen_in_use)
+			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
 		/* Fall through */
 	case IPV4_FLOW:
 	case IPV6_FLOW:
@@ -421,7 +424,8 @@ static int dpaa_get_hash_opts(struct net_device *dev,
 	case AH_V6_FLOW:
 	case ESP_V4_FLOW:
 	case ESP_V6_FLOW:
-		cmd->data |= RXH_IP_SRC | RXH_IP_DST;
+		if (priv->keygen_in_use)
+			cmd->data |= RXH_IP_SRC | RXH_IP_DST;
 		break;
 	default:
 		cmd->data = 0;
@@ -458,6 +462,7 @@ static void dpaa_set_hash(struct net_device *net_dev, bool enable)
 	rxport = mac_dev->port[0];
 
 	fman_port_use_kg_hash(rxport, enable);
+	priv->keygen_in_use = enable;
 }
 
 static int dpaa_set_hash_opts(struct net_device *dev,
diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c
index f571b3c..1789b20 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -1720,6 +1720,17 @@ u32 fman_port_get_qman_channel_id(struct fman_port *port)
 }
 EXPORT_SYMBOL(fman_port_get_qman_channel_id);
 
+int fman_port_get_hash_result_offset(struct fman_port *port, u32 *offset)
+{
+	if (port->buffer_offsets.hash_result_offset == ILLEGAL_BASE)
+		return -EINVAL;
+
+	*offset = port->buffer_offsets.hash_result_offset;
+
+	return 0;
+}
+EXPORT_SYMBOL(fman_port_get_hash_result_offset);
+
 static int fman_port_probe(struct platform_device *of_dev)
 {
 	struct fman_port *port;
diff --git a/drivers/net/ethernet/freescale/fman/fman_port.h b/drivers/net/ethernet/freescale/fman/fman_port.h
index 5a99611..e86ca6a 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.h
+++ b/drivers/net/ethernet/freescale/fman/fman_port.h
@@ -151,6 +151,8 @@ int fman_port_enable(struct fman_port *port);
 
 u32 fman_port_get_qman_channel_id(struct fman_port *port);
 
+int fman_port_get_hash_result_offset(struct fman_port *port, u32 *offset);
+
 struct fman_port *fman_port_bind(struct device *dev);
 
 #endif /* __FMAN_PORT_H */
-- 
2.1.0

^ permalink raw reply related

* [PATCH v4 7/7] dpaa_eth: check allocation result
From: Madalin Bucur @ 2017-08-27 13:13 UTC (permalink / raw)
  To: netdev, davem; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1503839623-3906-1-git-send-email-madalin.bucur@nxp.com>

Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 73ca8d7..4225806 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2561,6 +2561,9 @@ static struct dpaa_bp *dpaa_bp_alloc(struct device *dev)
 
 	dpaa_bp->bpid = FSL_DPAA_BPID_INV;
 	dpaa_bp->percpu_count = devm_alloc_percpu(dev, *dpaa_bp->percpu_count);
+	if (!dpaa_bp->percpu_count)
+		return ERR_PTR(-ENOMEM);
+
 	dpaa_bp->config_count = FSL_DPAA_ETH_MAX_BUF_COUNT;
 
 	dpaa_bp->seed_cb = dpaa_bp_seed;
-- 
2.1.0

^ permalink raw reply related

* Re: [PATCH net-next v7 05/10] landlock: Add LSM hooks related to filesystem
From: Mickaël Salaün @ 2017-08-27 13:31 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: linux-kernel, Alexei Starovoitov, Andy Lutomirski,
	Arnaldo Carvalho de Melo, Casey Schaufler, Daniel Borkmann,
	David Drysdale, David S . Miller, Eric W . Biederman,
	James Morris, Jann Horn, Jonathan Corbet, Matthew Garrett,
	Michael Kerrisk, Kees Cook, Paul Moore, Sargun Dhillon,
	Serge E . Hallyn, Shuah Khan, Tejun Heo, Thomas Graf
In-Reply-To: <20170826011614.iqya5dqii3n7dtdb@ast-mbp>


[-- Attachment #1.1: Type: text/plain, Size: 4034 bytes --]


On 26/08/2017 03:16, Alexei Starovoitov wrote:
> On Fri, Aug 25, 2017 at 10:16:39AM +0200, Mickaël Salaün wrote:

>>>
>>>> +/* a directory inode contains only one dentry */
>>>> +HOOK_NEW_FS(inode_create, 3,
>>>> +	struct inode *, dir,
>>>> +	struct dentry *, dentry,
>>>> +	umode_t, mode,
>>>> +	WRAP_ARG_INODE, dir,
>>>> +	WRAP_ARG_RAW, LANDLOCK_ACTION_FS_WRITE
>>>> +);
>>>
>>> more general question: why you're not wrapping all useful
>>> arguments? Like in the above dentry can be acted upon
>>> by the landlock rule and it's readily available...
>>
>> The context used for the FS event must have the exact same types for all
>> calls. This event is meant to be generic but we can add more specific
>> ones if needed, like I do with FS_IOCTL.
> 
> I see. So all FS events will have dentry as first argument
> regardless of how it is in LSM hook ?

All FS events will have a const struct bpf_handle_fs pointer as first
argument, which wrap either a struct file, a struct dentry, a struct
path or a struct inode. Having only one type (struct bpf_handle_fs) is
needed for the eBPF type checker to verify if a Landlock rule (tied to
an event) can access a context field and which operation is allowed
(with this pointer).

> I guess that will simplify the rules indeed.
> I suspect you're doing it to simplify the LSM->landlock shim layer as well, right?

That's right. This ABI is independent from the LSM API and much more
simpler to use.

> 
>> The idea is to enable people to write simple rules, while being able to
>> write fine grain rules for special cases (e.g. IOCTL) if needed.
>>
>>>
>>> The limitation of only 2 args looks odd.
>>> Is it a hard limitation ? how hard to extend?
>>
>> It's not a hard limit at all. Actually, the FS_FNCTL event should have
>> three arguments (I'll add them in the next series): FS handle, FCNTL
>> command and FCNTL argument. I made sure that it's really easy to add
>> more arguments to the context of an event.
> 
> The reason I'm asking, because I'm not completely convinced that
> adding another argument to existing event will be backwards compatible.
> It looks like you're expecting only two args for all FS events, right?

There is four events right now: FS, FS_IOCTL, FS_LOCK and FS_FCNTL. Each
of them are independent. Their context fields can be of the same or
different eBPF type (e.g. scalar, file handle) and numbers. Actually,
these four events have the same arg1 field (file handle) and the same
arg2 eBPF type (scalar), even if arg2 does not have the same semantic
(i.e. abstract FS action, IOCTL command…).

For example, if we want to extend the FS_FCNTL's context in the future,
we will just have to add an arg3. The check is performed in
landlock_is_valid_access() and landlock_decide(). If a field is not used
by an event, then this field will have a NOT_INIT type and accessing it
will be denied.

> How can you add 3rd argument? All FS events would have to get it,
> but in some LSM hooks such argument will be meaningless, whereas
> in other places it will carry useful info that rule can operate on.
> Would that mean that we'll have FS_3 event type and only few LSM
> hooks will be converted to it. That works, but then we'll lose
> compatiblity with old rules written for FS event and that given hook.
> Otherwise we'd need to have fancy logic to accept old FS event
> into FS_3 LSM hook.

If we want to add a third argument to the FS event, then it will become
accessible because its type will be different than NOT_INIT. This keep
the compatibility with old rules because this new field was then denied.

If we want to add a new argument but only for a subset of the hooks used
by the FS event, then we need to create a new event, like FS_FCNTL. For
example, we may want to add a FS_RENAME event to be able to tie the
source file and the destination file of a rename call.

Anyway, I added the subtype/ABI version as a safeguard in case of
unexpected future evolution.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH net-next 4/8] net: ethernet: add the Alpine Ethernet driver
From: Chocron, Jonathan @ 2017-08-27 13:47 UTC (permalink / raw)
  To: Andrew Lunn, Antoine Tenart
  Cc: netdev@vger.kernel.org, davem@davemloft.net,
	linux-arm-kernel@lists.infradead.org,
	thomas.petazzoni@free-electrons.com, arnd@arndb.de
In-Reply-To: <20170203205823.GA22572@lunn.ch>

This is a fixed version of my previous response (using proper indentation and leaving only the specific questions responded to).

> > +/* MDIO */
> > +#define AL_ETH_MDIO_C45_DEV_MASK     0x1f0000
> > +#define AL_ETH_MDIO_C45_DEV_SHIFT    16
> > +#define AL_ETH_MDIO_C45_REG_MASK     0xffff
> > +
> > +static int al_mdio_read(struct mii_bus *bp, int mii_id, int reg)
> > +{
> > +     struct al_eth_adapter *adapter = bp->priv;
> > +     u16 value = 0;
> > +     int rc;
> > +     int timeout = MDIO_TIMEOUT_MSEC;
> > +
> > +     while (timeout > 0) {
> > +             if (reg & MII_ADDR_C45) {
> > +                     netdev_dbg(adapter->netdev, "[c45]: dev %x reg %x val %x\n",
> > +                                ((reg & AL_ETH_MDIO_C45_DEV_MASK) >> AL_ETH_MDIO_C45_DEV_SHIFT),
> > +                                (reg & AL_ETH_MDIO_C45_REG_MASK), value);
> > +                     rc = al_eth_mdio_read(&adapter->hw_adapter, adapter->phy_addr,
> > +                             ((reg & AL_ETH_MDIO_C45_DEV_MASK) >> AL_ETH_MDIO_C45_DEV_SHIFT),
> > +                             (reg & AL_ETH_MDIO_C45_REG_MASK), &value);
> > +             } else {
> > +                     rc = al_eth_mdio_read(&adapter->hw_adapter, adapter->phy_addr,
> > +                                           MDIO_DEVAD_NONE, reg, &value);
> > +             }
> > +
> > +             if (rc == 0)
> > +                     return value;
> > +
> > +             netdev_dbg(adapter->netdev,
> > +                        "mdio read failed. try again in 10 msec\n");
> > +
> > +             timeout -= 10;
> > +             msleep(10);
> > +     }
> 
> This is rather unusual, retrying MDIO operations. Are you working
> around a hardware bug? I suspect this also opens up race conditions,
> in particular with PHY interrupts, which can be clear on read.

The MDIO bus is shared between the ethernet units. There is a HW lock used to arbitrate between different interfaces trying to access the bus, 
therefore there is a retry loop. The reg isn't accessed before obtaining the lock, so there shouldn't be any clear on read issues.

> > +/* al_eth_mdiobus_setup - initialize mdiobus and register to kernel */
> > +static int al_eth_mdiobus_setup(struct al_eth_adapter *adapter)
> > +{
> > +     struct phy_device *phydev;
> > +     int i;
> > +     int ret = 0;
> > +
> > +     adapter->mdio_bus = mdiobus_alloc();
> > +     if (!adapter->mdio_bus)
> > +             return -ENOMEM;
> > +
> > +     adapter->mdio_bus->name     = "al mdio bus";
> > +     snprintf(adapter->mdio_bus->id, MII_BUS_ID_SIZE, "%x",
> > +              (adapter->pdev->bus->number << 8) | adapter->pdev->devfn);
> > +     adapter->mdio_bus->priv     = adapter;
> > +     adapter->mdio_bus->parent   = &adapter->pdev->dev;
> > +     adapter->mdio_bus->read     = &al_mdio_read;
> > +     adapter->mdio_bus->write    = &al_mdio_write;
> > +     adapter->mdio_bus->phy_mask = ~BIT(adapter->phy_addr);
>
> Why do this?

Since the MDIO bus is shared, we want each interface to probe only for the PHY associated with it.

> > + * acquire mdio interface ownership
> > + * when mdio interface shared between multiple eth controllers, this function waits until the ownership granted for this controller.
> > + * this function does nothing when the mdio interface is used only by this controller.
> > + *
> > + * @param adapter
> > + * @return 0 on success, -ETIMEDOUT  on timeout.
> > + */
> > +static int al_eth_mdio_lock(struct al_hw_eth_adapter *adapter)
> > +{
> > +     int count = 0;
> > +     u32 mdio_ctrl_1;
> > +
> > +     if (!adapter->shared_mdio_if)
> > +             return 0; /* nothing to do when interface is not shared */
> > +
> > +     do {
> > +             mdio_ctrl_1 = readl(&adapter->mac_regs_base->gen.mdio_ctrl_1);
> > +             if (mdio_ctrl_1 & BIT(0)) {
> > +                     if (count > 0)
> > +                             netdev_dbg(adapter->netdev,
> > +                                        "eth %s mdio interface still busy!\n",
> > +                                        adapter->name);
> > +             } else {
> > +                     return 0;
> > +             }
> > +             udelay(AL_ETH_MDIO_DELAY_PERIOD);
> > +     } while (count++ < (AL_ETH_MDIO_DELAY_COUNT * 4));
>
> This needs explaining. How can a read alone perform a lock? How is
> this race free?

This is how this HW lock works: when the bit is 0 this means the lock is free. When a read transaction arrives
to the lock, it changes its value to 1 but sends 0 as the response, basically taking ownership.
When the owner is done, it writes  a 0 which essentially "frees" the lock.

> > +             if (adapter->mdio_type == AL_ETH_MDIO_TYPE_CLAUSE_22)
> > +                     rc = al_eth_mdio_10g_mac_type22(adapter, 1, phy_addr,
> > +                                                     reg, val);
> > +             else
> > +                     rc = al_eth_mdio_10g_mac_type45(adapter, 1, phy_addr,
> > +                                                     device, reg, val);
> 
> This seems odd. My understanding is that the device on the MDIO bus,
> the PHY, is either c22 or c45. The PHY driver will tell you this, not
> the adaptor.
 
The current implementation sets mdio_type according to information which is originally deduced from the
DeviceTree (the bootloader parses the ethernet node of the DeviceTree and saves this data to HW registers, which are then read by this driver).
How can this information be obtained by the PHY driver?

>    Andrew

Jonathan

^ permalink raw reply

* Re: [PATCH] DSA support for Micrel KSZ8895
From: Andrew Lunn @ 2017-08-27 13:59 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Woojung.Huh, nathan.leigh.conrad, vivien.didelot, f.fainelli,
	netdev, linux-kernel, Tristram.Ha
In-Reply-To: <20170827123658.GA727@amd>

On Sun, Aug 27, 2017 at 02:36:58PM +0200, Pavel Machek wrote:
> Hi!
> 
> So I fought with the driver a bit more, and now I have something that
> kind-of-works.


Thanks for keeping on working on this.
 
> "great great hack" belows worries me.
> 
> Yeah, disabled code needs to be removed before merge.
> 
> No, tag_ksz part probably is not acceptable. Do you see solution
> better than just copying it into tag_ksz1 file?
> 
> Any more comments, etc?

It would help with review if you split this up into multiple patches.
The change to the tagger should be one patch. The mdio emulation would
make a reasonable standalone patch etc.

I will do a more detailed review later.

  Andrew

^ permalink raw reply

* Re: [PATCH v2 net-next 1/8] bpf: Add support for recursively running cgroup sock filters
From: David Ahern @ 2017-08-27 14:22 UTC (permalink / raw)
  To: Daniel Borkmann, netdev, ast, tj, davem
In-Reply-To: <59A0D62F.3030806@iogearbox.net>

On 8/25/17 8:00 PM, Daniel Borkmann wrote:
> Can you elaborate on the semantical changes for the programs
> setting the new flag which are not using below cgroup_bpf_run_filter_sk()
> helper to walk back to root?

You mean other cgroup based programs -- BPF_CGROUP_* ? If so, any reason
not to allow the recursion model on those too?

^ permalink raw reply

* Re: [PATCH v2 net-next 1/8] bpf: Add support for recursively running cgroup sock filters
From: David Ahern @ 2017-08-27 14:49 UTC (permalink / raw)
  To: Alexei Starovoitov; +Cc: netdev, daniel, ast, tj, davem, David Ahern (gmail)
In-Reply-To: <20170826024957.m5ita6usxihywmdd@ast-mbp>

On 8/25/17 8:49 PM, Alexei Starovoitov wrote:
> 
>> +	if (prog && curr_recursive && !new_recursive)
>> +		/* if a parent has recursive prog attached, only
>> +		 * allow recursive programs in descendent cgroup
>> +		 */
>> +		return -EINVAL;
>> +
>>  	old_prog = cgrp->bpf.prog[type];
> 
> ... I'm struggling to completely understand how it interacts
> with BPF_F_ALLOW_OVERRIDE.

The 2 flags are completely independent. The existing override logic is
unchanged. If a program can not be overridden, then the new recursive
flag is irrelevant.

> By default we shouldn't allow overriding, so if default prog attached
> to a root, what happens if we try to attach F_RECURSIVE to a descendent?
> If I'm reading the code correctly it will not succeed, which is good.
> Could you add such scenario as test to test_cgrp2_attach2.c ?

Patch 7 adds test cases to cover scenarios. I will add more tests per
comments below and rename to convey it tests the recursive flag.

> 
> Now say we attach overridable and !recursive to a root, another
> recursive prog will not be attached to a descedent, which is correct.

yes

> 
> But if we attach !overridable + recursive to a root we cannot attach
> anything to a descendent right? Then why allow such combination at all?

Sure, we can not allow that combination to prevent the inefficiency of
recursively running through cgroups to run the base program.

> So only overridable + recursive combination makes sense, right?
> 
> I think all these combinations must be documented and tests must be
> added. Sooner or later people will build security sensitive environment
> with it and we have to meticulous now.

Intentions below. I'll add more test cases to verify intentions agree
with code.

> 
> Do you think it would make sense to split this patch out and
> push patches 2 and 3 with few tests in parallel, while we're review
> this change?

I thought about that but decided no. The 'ip vrf exec' use case would
break right of the gate if the other settings were used.

> 
> Tejun needs to take a deep look into this patch as well.
> 

This is the intended behavior:

The override flag is independent of the recursive flag. If the override
flag does not allow an override, the attempt to add a new program fails.
The recursive flag brings an additional constraint: once a cgroup has a
program with the recursive flag set it is inherited by all descendant
groups. Attempts to insert a program that changes that flag fails EINVAL.

Start with the root group at $MNT. No program is attached. By default
override is allowed and recursive is not set.

1. Group $MNT/a is created.

i. Default settings from $MNT are inherited; 'a' has override enabled
and recursive disabled.

ii. Program is attached. Override flag is set, recursive flag is not set.

iii. Process in 'a' opens a socket, program attached to 'a' is run.


2. $MNT/a/b is created

i. 'b' inherits the program and settings of 'a' (override enabled,
recursive disabled).

ii. Process in 'b' opens a socket. Program inherited from 'a' is run.

iii. Non-interesting case for this patch set: attaching a non-recursive
program to 'b' overrides the inherited one. process opens a socket only
the 'b' program is run.

iv. Program is attached to 'b', override flag set, recursive flag set.

v. Process in 'b' opens a socket. Program attached to 'b' is run and
then program from 'a' is run. Recursion stops here since 'a' does not
have the recursion flag set.


3. $MNT/a/b/c is created

i. 'c' inherits the settings of 'b' (override is allowed, recursive flag
is set)

ii. Process in 'c' opens a socket. No program from 'c' exists, so
nothing is run. Recursion flag is set, so program from 'b' is run, then
program from 'a' is run. Stop (recursive flag not set on 'a').

iii. Attaching a non-recursive program to 'c' fails because it inherited
the recursive flag from 'b' and that can not be reset by a descendant.

iv. Recursive program is attached to 'c'

v. Process in 'c' opens a socket. Program attached to 'c' is run, then
the program from 'b' and the program from 'a'. Stop.

etc.

To consider what happens on doubling back and changing programs in the
hierarchy, start with $MNT/a/b/c from 3 above (non-recursive on 'a',
recursive on 'b' and recursive on 'c') for each of the following cases:

1. Program attached to 'b' is detached, recursive flag is reset in the
request. Attempt fails EINVAL because the recursion flag has to be set.


2. Program attached to 'b' is detached, recursive flag is set. Allowed.

Process in 'b' opens a socket. No program attached to 'b' so no program
is run. Recursive flag is set to program from 'a' is run. Stop.

We should allow the recursive flag to be reset if the parent is not
recursive allowing an unwind of settings applied. I'll add that change.

^ permalink raw reply

* [PATCH 0/4] irda: move it to drivers/staging so we can delete it
From: Greg Kroah-Hartman @ 2017-08-27 15:03 UTC (permalink / raw)
  To: davem, samuel; +Cc: netdev, linux-kernel, devel, Greg Kroah-Hartman

The IRDA code has long been obsolete and broken.  So, to keep people
from trying to use it, and to prevent people from having to maintain it,
let's move it to drivers/staging/ so that we can delete it entirely from
the kernel in a few releases.


Greg Kroah-Hartman (4):
  irda: move net/irda/ to drivers/staging/irda/net/
  irda: move drivers/net/irda to drivers/staging/irda/drivers
  irda: move include/net/irda into staging subdirectory
  staging: irda: add a TODO file.

 drivers/net/Makefile                                              | 1 -
 drivers/staging/Kconfig                                           | 2 ++
 drivers/staging/Makefile                                          | 2 ++
 drivers/staging/irda/TODO                                         | 4 ++++
 drivers/{net/irda => staging/irda/drivers}/Kconfig                | 0
 drivers/{net/irda => staging/irda/drivers}/Makefile               | 2 ++
 drivers/{net/irda => staging/irda/drivers}/act200l-sir.c          | 0
 drivers/{net/irda => staging/irda/drivers}/actisys-sir.c          | 0
 drivers/{net/irda => staging/irda/drivers}/ali-ircc.c             | 0
 drivers/{net/irda => staging/irda/drivers}/ali-ircc.h             | 0
 drivers/{net/irda => staging/irda/drivers}/au1k_ir.c              | 0
 drivers/{net/irda => staging/irda/drivers}/bfin_sir.c             | 0
 drivers/{net/irda => staging/irda/drivers}/bfin_sir.h             | 0
 drivers/{net/irda => staging/irda/drivers}/donauboe.c             | 0
 drivers/{net/irda => staging/irda/drivers}/donauboe.h             | 0
 drivers/{net/irda => staging/irda/drivers}/esi-sir.c              | 0
 drivers/{net/irda => staging/irda/drivers}/girbil-sir.c           | 0
 drivers/{net/irda => staging/irda/drivers}/irda-usb.c             | 0
 drivers/{net/irda => staging/irda/drivers}/irda-usb.h             | 0
 drivers/{net/irda => staging/irda/drivers}/irtty-sir.c            | 0
 drivers/{net/irda => staging/irda/drivers}/irtty-sir.h            | 0
 drivers/{net/irda => staging/irda/drivers}/kingsun-sir.c          | 0
 drivers/{net/irda => staging/irda/drivers}/ks959-sir.c            | 0
 drivers/{net/irda => staging/irda/drivers}/ksdazzle-sir.c         | 0
 drivers/{net/irda => staging/irda/drivers}/litelink-sir.c         | 0
 drivers/{net/irda => staging/irda/drivers}/ma600-sir.c            | 0
 drivers/{net/irda => staging/irda/drivers}/mcp2120-sir.c          | 0
 drivers/{net/irda => staging/irda/drivers}/mcs7780.c              | 0
 drivers/{net/irda => staging/irda/drivers}/mcs7780.h              | 0
 drivers/{net/irda => staging/irda/drivers}/nsc-ircc.c             | 0
 drivers/{net/irda => staging/irda/drivers}/nsc-ircc.h             | 0
 drivers/{net/irda => staging/irda/drivers}/old_belkin-sir.c       | 0
 drivers/{net/irda => staging/irda/drivers}/pxaficp_ir.c           | 0
 drivers/{net/irda => staging/irda/drivers}/sa1100_ir.c            | 0
 drivers/{net/irda => staging/irda/drivers}/sh_sir.c               | 0
 drivers/{net/irda => staging/irda/drivers}/sir-dev.h              | 0
 drivers/{net/irda => staging/irda/drivers}/sir_dev.c              | 0
 drivers/{net/irda => staging/irda/drivers}/sir_dongle.c           | 0
 drivers/{net/irda => staging/irda/drivers}/smsc-ircc2.c           | 0
 drivers/{net/irda => staging/irda/drivers}/smsc-ircc2.h           | 0
 drivers/{net/irda => staging/irda/drivers}/smsc-sio.h             | 0
 drivers/{net/irda => staging/irda/drivers}/stir4200.c             | 0
 drivers/{net/irda => staging/irda/drivers}/tekram-sir.c           | 0
 drivers/{net/irda => staging/irda/drivers}/toim3232-sir.c         | 0
 drivers/{net/irda => staging/irda/drivers}/via-ircc.c             | 0
 drivers/{net/irda => staging/irda/drivers}/via-ircc.h             | 0
 drivers/{net/irda => staging/irda/drivers}/vlsi_ir.c              | 0
 drivers/{net/irda => staging/irda/drivers}/vlsi_ir.h              | 0
 drivers/{net/irda => staging/irda/drivers}/w83977af.h             | 0
 drivers/{net/irda => staging/irda/drivers}/w83977af_ir.c          | 0
 drivers/{net/irda => staging/irda/drivers}/w83977af_ir.h          | 0
 {include => drivers/staging/irda/include}/net/irda/af_irda.h      | 0
 {include => drivers/staging/irda/include}/net/irda/crc.h          | 0
 {include => drivers/staging/irda/include}/net/irda/discovery.h    | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_core.h  | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_event.h | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_lmp.h   | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_param.h | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_ttp.h   | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_tty.h   | 0
 .../staging/irda/include}/net/irda/ircomm_tty_attach.h            | 0
 {include => drivers/staging/irda/include}/net/irda/irda.h         | 0
 {include => drivers/staging/irda/include}/net/irda/irda_device.h  | 0
 {include => drivers/staging/irda/include}/net/irda/iriap.h        | 0
 {include => drivers/staging/irda/include}/net/irda/iriap_event.h  | 0
 {include => drivers/staging/irda/include}/net/irda/irias_object.h | 0
 {include => drivers/staging/irda/include}/net/irda/irlan_client.h | 0
 {include => drivers/staging/irda/include}/net/irda/irlan_common.h | 0
 {include => drivers/staging/irda/include}/net/irda/irlan_eth.h    | 0
 {include => drivers/staging/irda/include}/net/irda/irlan_event.h  | 0
 {include => drivers/staging/irda/include}/net/irda/irlan_filter.h | 0
 .../staging/irda/include}/net/irda/irlan_provider.h               | 0
 {include => drivers/staging/irda/include}/net/irda/irlap.h        | 0
 {include => drivers/staging/irda/include}/net/irda/irlap_event.h  | 0
 {include => drivers/staging/irda/include}/net/irda/irlap_frame.h  | 0
 {include => drivers/staging/irda/include}/net/irda/irlmp.h        | 0
 {include => drivers/staging/irda/include}/net/irda/irlmp_event.h  | 0
 {include => drivers/staging/irda/include}/net/irda/irlmp_frame.h  | 0
 {include => drivers/staging/irda/include}/net/irda/irmod.h        | 0
 {include => drivers/staging/irda/include}/net/irda/irqueue.h      | 0
 {include => drivers/staging/irda/include}/net/irda/irttp.h        | 0
 {include => drivers/staging/irda/include}/net/irda/parameters.h   | 0
 {include => drivers/staging/irda/include}/net/irda/qos.h          | 0
 {include => drivers/staging/irda/include}/net/irda/timer.h        | 0
 {include => drivers/staging/irda/include}/net/irda/wrapper.h      | 0
 {net/irda => drivers/staging/irda/net}/Kconfig                    | 8 ++++----
 {net/irda => drivers/staging/irda/net}/Makefile                   | 2 ++
 {net/irda => drivers/staging/irda/net}/af_irda.c                  | 0
 {net/irda => drivers/staging/irda/net}/discovery.c                | 0
 {net/irda => drivers/staging/irda/net}/ircomm/Kconfig             | 0
 {net/irda => drivers/staging/irda/net}/ircomm/Makefile            | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_core.c       | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_event.c      | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_lmp.c        | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_param.c      | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_ttp.c        | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty.c        | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty_attach.c | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty_ioctl.c  | 0
 {net/irda => drivers/staging/irda/net}/irda_device.c              | 0
 {net/irda => drivers/staging/irda/net}/iriap.c                    | 0
 {net/irda => drivers/staging/irda/net}/iriap_event.c              | 0
 {net/irda => drivers/staging/irda/net}/irias_object.c             | 0
 {net/irda => drivers/staging/irda/net}/irlan/Kconfig              | 0
 {net/irda => drivers/staging/irda/net}/irlan/Makefile             | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_client.c       | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_client_event.c | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_common.c       | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_eth.c          | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_event.c        | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_filter.c       | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_provider.c     | 0
 .../staging/irda/net}/irlan/irlan_provider_event.c                | 0
 {net/irda => drivers/staging/irda/net}/irlap.c                    | 0
 {net/irda => drivers/staging/irda/net}/irlap_event.c              | 0
 {net/irda => drivers/staging/irda/net}/irlap_frame.c              | 0
 {net/irda => drivers/staging/irda/net}/irlmp.c                    | 0
 {net/irda => drivers/staging/irda/net}/irlmp_event.c              | 0
 {net/irda => drivers/staging/irda/net}/irlmp_frame.c              | 0
 {net/irda => drivers/staging/irda/net}/irmod.c                    | 0
 {net/irda => drivers/staging/irda/net}/irnet/Kconfig              | 0
 {net/irda => drivers/staging/irda/net}/irnet/Makefile             | 0
 {net/irda => drivers/staging/irda/net}/irnet/irnet.h              | 0
 {net/irda => drivers/staging/irda/net}/irnet/irnet_irda.c         | 0
 {net/irda => drivers/staging/irda/net}/irnet/irnet_irda.h         | 0
 {net/irda => drivers/staging/irda/net}/irnet/irnet_ppp.c          | 0
 {net/irda => drivers/staging/irda/net}/irnet/irnet_ppp.h          | 0
 {net/irda => drivers/staging/irda/net}/irnetlink.c                | 0
 {net/irda => drivers/staging/irda/net}/irproc.c                   | 0
 {net/irda => drivers/staging/irda/net}/irqueue.c                  | 0
 {net/irda => drivers/staging/irda/net}/irsysctl.c                 | 0
 {net/irda => drivers/staging/irda/net}/irttp.c                    | 0
 {net/irda => drivers/staging/irda/net}/parameters.c               | 0
 {net/irda => drivers/staging/irda/net}/qos.c                      | 0
 {net/irda => drivers/staging/irda/net}/timer.c                    | 0
 {net/irda => drivers/staging/irda/net}/wrapper.c                  | 0
 net/Kconfig                                                       | 1 -
 net/Makefile                                                      | 1 -
 138 files changed, 16 insertions(+), 7 deletions(-)
 create mode 100644 drivers/staging/irda/TODO
 rename drivers/{net/irda => staging/irda/drivers}/Kconfig (100%)
 rename drivers/{net/irda => staging/irda/drivers}/Makefile (96%)
 rename drivers/{net/irda => staging/irda/drivers}/act200l-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/actisys-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/ali-ircc.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/ali-ircc.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/au1k_ir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/bfin_sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/bfin_sir.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/donauboe.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/donauboe.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/esi-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/girbil-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/irda-usb.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/irda-usb.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/irtty-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/irtty-sir.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/kingsun-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/ks959-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/ksdazzle-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/litelink-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/ma600-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/mcp2120-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/mcs7780.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/mcs7780.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/nsc-ircc.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/nsc-ircc.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/old_belkin-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/pxaficp_ir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/sa1100_ir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/sh_sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/sir-dev.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/sir_dev.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/sir_dongle.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/smsc-ircc2.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/smsc-ircc2.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/smsc-sio.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/stir4200.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/tekram-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/toim3232-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/via-ircc.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/via-ircc.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/vlsi_ir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/vlsi_ir.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/w83977af.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/w83977af_ir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/w83977af_ir.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/af_irda.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/crc.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/discovery.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_core.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_event.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_lmp.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_param.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_ttp.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_tty.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_tty_attach.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irda.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irda_device.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/iriap.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/iriap_event.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irias_object.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_client.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_common.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_eth.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_event.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_filter.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_provider.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlap.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlap_event.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlap_frame.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlmp.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlmp_event.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlmp_frame.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irmod.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irqueue.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irttp.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/parameters.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/qos.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/timer.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/wrapper.h (100%)
 rename {net/irda => drivers/staging/irda/net}/Kconfig (94%)
 rename {net/irda => drivers/staging/irda/net}/Makefile (88%)
 rename {net/irda => drivers/staging/irda/net}/af_irda.c (100%)
 rename {net/irda => drivers/staging/irda/net}/discovery.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/Kconfig (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/Makefile (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_core.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_lmp.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_param.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_ttp.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty_attach.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty_ioctl.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irda_device.c (100%)
 rename {net/irda => drivers/staging/irda/net}/iriap.c (100%)
 rename {net/irda => drivers/staging/irda/net}/iriap_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irias_object.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/Kconfig (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/Makefile (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_client.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_client_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_common.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_eth.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_filter.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_provider.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_provider_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlap.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlap_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlap_frame.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlmp.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlmp_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlmp_frame.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irmod.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/Kconfig (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/Makefile (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/irnet.h (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/irnet_irda.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/irnet_irda.h (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/irnet_ppp.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/irnet_ppp.h (100%)
 rename {net/irda => drivers/staging/irda/net}/irnetlink.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irproc.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irqueue.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irsysctl.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irttp.c (100%)
 rename {net/irda => drivers/staging/irda/net}/parameters.c (100%)
 rename {net/irda => drivers/staging/irda/net}/qos.c (100%)
 rename {net/irda => drivers/staging/irda/net}/timer.c (100%)
 rename {net/irda => drivers/staging/irda/net}/wrapper.c (100%)

-- 
2.14.1

^ permalink raw reply

* [PATCH 1/4] irda: move net/irda/ to drivers/staging/irda/net/
From: Greg Kroah-Hartman @ 2017-08-27 15:03 UTC (permalink / raw)
  To: davem, samuel; +Cc: devel, netdev, linux-kernel, Greg Kroah-Hartman
In-Reply-To: <20170827150334.32495-1-gregkh@linuxfoundation.org>

It's time to get rid of IRDA.  It's long been broken, and no one seems
to use it anymore.  So move it to staging and after a while, we can
delete it from there.

To start, move the network irda core from net/irda to
drivers/staging/irda/net/

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/staging/Kconfig                                             | 2 ++
 drivers/staging/Makefile                                            | 1 +
 {net/irda => drivers/staging/irda/net}/Kconfig                      | 6 +++---
 {net/irda => drivers/staging/irda/net}/Makefile                     | 0
 {net/irda => drivers/staging/irda/net}/af_irda.c                    | 0
 {net/irda => drivers/staging/irda/net}/discovery.c                  | 0
 {net/irda => drivers/staging/irda/net}/ircomm/Kconfig               | 0
 {net/irda => drivers/staging/irda/net}/ircomm/Makefile              | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_core.c         | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_event.c        | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_lmp.c          | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_param.c        | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_ttp.c          | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty.c          | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty_attach.c   | 0
 {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty_ioctl.c    | 0
 {net/irda => drivers/staging/irda/net}/irda_device.c                | 0
 {net/irda => drivers/staging/irda/net}/iriap.c                      | 0
 {net/irda => drivers/staging/irda/net}/iriap_event.c                | 0
 {net/irda => drivers/staging/irda/net}/irias_object.c               | 0
 {net/irda => drivers/staging/irda/net}/irlan/Kconfig                | 0
 {net/irda => drivers/staging/irda/net}/irlan/Makefile               | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_client.c         | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_client_event.c   | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_common.c         | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_eth.c            | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_event.c          | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_filter.c         | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_provider.c       | 0
 {net/irda => drivers/staging/irda/net}/irlan/irlan_provider_event.c | 0
 {net/irda => drivers/staging/irda/net}/irlap.c                      | 0
 {net/irda => drivers/staging/irda/net}/irlap_event.c                | 0
 {net/irda => drivers/staging/irda/net}/irlap_frame.c                | 0
 {net/irda => drivers/staging/irda/net}/irlmp.c                      | 0
 {net/irda => drivers/staging/irda/net}/irlmp_event.c                | 0
 {net/irda => drivers/staging/irda/net}/irlmp_frame.c                | 0
 {net/irda => drivers/staging/irda/net}/irmod.c                      | 0
 {net/irda => drivers/staging/irda/net}/irnet/Kconfig                | 0
 {net/irda => drivers/staging/irda/net}/irnet/Makefile               | 0
 {net/irda => drivers/staging/irda/net}/irnet/irnet.h                | 0
 {net/irda => drivers/staging/irda/net}/irnet/irnet_irda.c           | 0
 {net/irda => drivers/staging/irda/net}/irnet/irnet_irda.h           | 0
 {net/irda => drivers/staging/irda/net}/irnet/irnet_ppp.c            | 0
 {net/irda => drivers/staging/irda/net}/irnet/irnet_ppp.h            | 0
 {net/irda => drivers/staging/irda/net}/irnetlink.c                  | 0
 {net/irda => drivers/staging/irda/net}/irproc.c                     | 0
 {net/irda => drivers/staging/irda/net}/irqueue.c                    | 0
 {net/irda => drivers/staging/irda/net}/irsysctl.c                   | 0
 {net/irda => drivers/staging/irda/net}/irttp.c                      | 0
 {net/irda => drivers/staging/irda/net}/parameters.c                 | 0
 {net/irda => drivers/staging/irda/net}/qos.c                        | 0
 {net/irda => drivers/staging/irda/net}/timer.c                      | 0
 {net/irda => drivers/staging/irda/net}/wrapper.c                    | 0
 net/Kconfig                                                         | 1 -
 net/Makefile                                                        | 1 -
 55 files changed, 6 insertions(+), 5 deletions(-)
 rename {net/irda => drivers/staging/irda/net}/Kconfig (95%)
 rename {net/irda => drivers/staging/irda/net}/Makefile (100%)
 rename {net/irda => drivers/staging/irda/net}/af_irda.c (100%)
 rename {net/irda => drivers/staging/irda/net}/discovery.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/Kconfig (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/Makefile (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_core.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_lmp.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_param.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_ttp.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty_attach.c (100%)
 rename {net/irda => drivers/staging/irda/net}/ircomm/ircomm_tty_ioctl.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irda_device.c (100%)
 rename {net/irda => drivers/staging/irda/net}/iriap.c (100%)
 rename {net/irda => drivers/staging/irda/net}/iriap_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irias_object.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/Kconfig (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/Makefile (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_client.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_client_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_common.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_eth.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_filter.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_provider.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlan/irlan_provider_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlap.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlap_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlap_frame.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlmp.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlmp_event.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irlmp_frame.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irmod.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/Kconfig (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/Makefile (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/irnet.h (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/irnet_irda.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/irnet_irda.h (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/irnet_ppp.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irnet/irnet_ppp.h (100%)
 rename {net/irda => drivers/staging/irda/net}/irnetlink.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irproc.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irqueue.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irsysctl.c (100%)
 rename {net/irda => drivers/staging/irda/net}/irttp.c (100%)
 rename {net/irda => drivers/staging/irda/net}/parameters.c (100%)
 rename {net/irda => drivers/staging/irda/net}/qos.c (100%)
 rename {net/irda => drivers/staging/irda/net}/timer.c (100%)
 rename {net/irda => drivers/staging/irda/net}/wrapper.c (100%)

diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index ef28a1cb64ae..0c5086d878c6 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -24,6 +24,8 @@ menuconfig STAGING
 
 if STAGING
 
+source "drivers/staging/irda/net/Kconfig"
+
 source "drivers/staging/wlan-ng/Kconfig"
 
 source "drivers/staging/comedi/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 2918580bdb9e..509fbacf9a7e 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -2,6 +2,7 @@
 
 obj-y				+= media/
 obj-y				+= typec/
+obj-$(CONFIG_IRDA)		+= irda/net/
 obj-$(CONFIG_PRISM2_USB)	+= wlan-ng/
 obj-$(CONFIG_COMEDI)		+= comedi/
 obj-$(CONFIG_FB_OLPC_DCON)	+= olpc_dcon/
diff --git a/net/irda/Kconfig b/drivers/staging/irda/net/Kconfig
similarity index 95%
rename from net/irda/Kconfig
rename to drivers/staging/irda/net/Kconfig
index c8671a7ffb3c..cd775e1ea0e9 100644
--- a/net/irda/Kconfig
+++ b/drivers/staging/irda/net/Kconfig
@@ -27,11 +27,11 @@ menuconfig IRDA
 comment "IrDA protocols"
 	depends on IRDA
 
-source "net/irda/irlan/Kconfig"
+source "drivers/staging/irda/net/irlan/Kconfig"
 
-source "net/irda/irnet/Kconfig"
+source "drivers/staging/irda/net/irnet/Kconfig"
 
-source "net/irda/ircomm/Kconfig"
+source "drivers/staging/irda/net/ircomm/Kconfig"
 
 config IRDA_ULTRA
 	bool "Ultra (connectionless) protocol"
diff --git a/net/irda/Makefile b/drivers/staging/irda/net/Makefile
similarity index 100%
rename from net/irda/Makefile
rename to drivers/staging/irda/net/Makefile
diff --git a/net/irda/af_irda.c b/drivers/staging/irda/net/af_irda.c
similarity index 100%
rename from net/irda/af_irda.c
rename to drivers/staging/irda/net/af_irda.c
diff --git a/net/irda/discovery.c b/drivers/staging/irda/net/discovery.c
similarity index 100%
rename from net/irda/discovery.c
rename to drivers/staging/irda/net/discovery.c
diff --git a/net/irda/ircomm/Kconfig b/drivers/staging/irda/net/ircomm/Kconfig
similarity index 100%
rename from net/irda/ircomm/Kconfig
rename to drivers/staging/irda/net/ircomm/Kconfig
diff --git a/net/irda/ircomm/Makefile b/drivers/staging/irda/net/ircomm/Makefile
similarity index 100%
rename from net/irda/ircomm/Makefile
rename to drivers/staging/irda/net/ircomm/Makefile
diff --git a/net/irda/ircomm/ircomm_core.c b/drivers/staging/irda/net/ircomm/ircomm_core.c
similarity index 100%
rename from net/irda/ircomm/ircomm_core.c
rename to drivers/staging/irda/net/ircomm/ircomm_core.c
diff --git a/net/irda/ircomm/ircomm_event.c b/drivers/staging/irda/net/ircomm/ircomm_event.c
similarity index 100%
rename from net/irda/ircomm/ircomm_event.c
rename to drivers/staging/irda/net/ircomm/ircomm_event.c
diff --git a/net/irda/ircomm/ircomm_lmp.c b/drivers/staging/irda/net/ircomm/ircomm_lmp.c
similarity index 100%
rename from net/irda/ircomm/ircomm_lmp.c
rename to drivers/staging/irda/net/ircomm/ircomm_lmp.c
diff --git a/net/irda/ircomm/ircomm_param.c b/drivers/staging/irda/net/ircomm/ircomm_param.c
similarity index 100%
rename from net/irda/ircomm/ircomm_param.c
rename to drivers/staging/irda/net/ircomm/ircomm_param.c
diff --git a/net/irda/ircomm/ircomm_ttp.c b/drivers/staging/irda/net/ircomm/ircomm_ttp.c
similarity index 100%
rename from net/irda/ircomm/ircomm_ttp.c
rename to drivers/staging/irda/net/ircomm/ircomm_ttp.c
diff --git a/net/irda/ircomm/ircomm_tty.c b/drivers/staging/irda/net/ircomm/ircomm_tty.c
similarity index 100%
rename from net/irda/ircomm/ircomm_tty.c
rename to drivers/staging/irda/net/ircomm/ircomm_tty.c
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/drivers/staging/irda/net/ircomm/ircomm_tty_attach.c
similarity index 100%
rename from net/irda/ircomm/ircomm_tty_attach.c
rename to drivers/staging/irda/net/ircomm/ircomm_tty_attach.c
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/drivers/staging/irda/net/ircomm/ircomm_tty_ioctl.c
similarity index 100%
rename from net/irda/ircomm/ircomm_tty_ioctl.c
rename to drivers/staging/irda/net/ircomm/ircomm_tty_ioctl.c
diff --git a/net/irda/irda_device.c b/drivers/staging/irda/net/irda_device.c
similarity index 100%
rename from net/irda/irda_device.c
rename to drivers/staging/irda/net/irda_device.c
diff --git a/net/irda/iriap.c b/drivers/staging/irda/net/iriap.c
similarity index 100%
rename from net/irda/iriap.c
rename to drivers/staging/irda/net/iriap.c
diff --git a/net/irda/iriap_event.c b/drivers/staging/irda/net/iriap_event.c
similarity index 100%
rename from net/irda/iriap_event.c
rename to drivers/staging/irda/net/iriap_event.c
diff --git a/net/irda/irias_object.c b/drivers/staging/irda/net/irias_object.c
similarity index 100%
rename from net/irda/irias_object.c
rename to drivers/staging/irda/net/irias_object.c
diff --git a/net/irda/irlan/Kconfig b/drivers/staging/irda/net/irlan/Kconfig
similarity index 100%
rename from net/irda/irlan/Kconfig
rename to drivers/staging/irda/net/irlan/Kconfig
diff --git a/net/irda/irlan/Makefile b/drivers/staging/irda/net/irlan/Makefile
similarity index 100%
rename from net/irda/irlan/Makefile
rename to drivers/staging/irda/net/irlan/Makefile
diff --git a/net/irda/irlan/irlan_client.c b/drivers/staging/irda/net/irlan/irlan_client.c
similarity index 100%
rename from net/irda/irlan/irlan_client.c
rename to drivers/staging/irda/net/irlan/irlan_client.c
diff --git a/net/irda/irlan/irlan_client_event.c b/drivers/staging/irda/net/irlan/irlan_client_event.c
similarity index 100%
rename from net/irda/irlan/irlan_client_event.c
rename to drivers/staging/irda/net/irlan/irlan_client_event.c
diff --git a/net/irda/irlan/irlan_common.c b/drivers/staging/irda/net/irlan/irlan_common.c
similarity index 100%
rename from net/irda/irlan/irlan_common.c
rename to drivers/staging/irda/net/irlan/irlan_common.c
diff --git a/net/irda/irlan/irlan_eth.c b/drivers/staging/irda/net/irlan/irlan_eth.c
similarity index 100%
rename from net/irda/irlan/irlan_eth.c
rename to drivers/staging/irda/net/irlan/irlan_eth.c
diff --git a/net/irda/irlan/irlan_event.c b/drivers/staging/irda/net/irlan/irlan_event.c
similarity index 100%
rename from net/irda/irlan/irlan_event.c
rename to drivers/staging/irda/net/irlan/irlan_event.c
diff --git a/net/irda/irlan/irlan_filter.c b/drivers/staging/irda/net/irlan/irlan_filter.c
similarity index 100%
rename from net/irda/irlan/irlan_filter.c
rename to drivers/staging/irda/net/irlan/irlan_filter.c
diff --git a/net/irda/irlan/irlan_provider.c b/drivers/staging/irda/net/irlan/irlan_provider.c
similarity index 100%
rename from net/irda/irlan/irlan_provider.c
rename to drivers/staging/irda/net/irlan/irlan_provider.c
diff --git a/net/irda/irlan/irlan_provider_event.c b/drivers/staging/irda/net/irlan/irlan_provider_event.c
similarity index 100%
rename from net/irda/irlan/irlan_provider_event.c
rename to drivers/staging/irda/net/irlan/irlan_provider_event.c
diff --git a/net/irda/irlap.c b/drivers/staging/irda/net/irlap.c
similarity index 100%
rename from net/irda/irlap.c
rename to drivers/staging/irda/net/irlap.c
diff --git a/net/irda/irlap_event.c b/drivers/staging/irda/net/irlap_event.c
similarity index 100%
rename from net/irda/irlap_event.c
rename to drivers/staging/irda/net/irlap_event.c
diff --git a/net/irda/irlap_frame.c b/drivers/staging/irda/net/irlap_frame.c
similarity index 100%
rename from net/irda/irlap_frame.c
rename to drivers/staging/irda/net/irlap_frame.c
diff --git a/net/irda/irlmp.c b/drivers/staging/irda/net/irlmp.c
similarity index 100%
rename from net/irda/irlmp.c
rename to drivers/staging/irda/net/irlmp.c
diff --git a/net/irda/irlmp_event.c b/drivers/staging/irda/net/irlmp_event.c
similarity index 100%
rename from net/irda/irlmp_event.c
rename to drivers/staging/irda/net/irlmp_event.c
diff --git a/net/irda/irlmp_frame.c b/drivers/staging/irda/net/irlmp_frame.c
similarity index 100%
rename from net/irda/irlmp_frame.c
rename to drivers/staging/irda/net/irlmp_frame.c
diff --git a/net/irda/irmod.c b/drivers/staging/irda/net/irmod.c
similarity index 100%
rename from net/irda/irmod.c
rename to drivers/staging/irda/net/irmod.c
diff --git a/net/irda/irnet/Kconfig b/drivers/staging/irda/net/irnet/Kconfig
similarity index 100%
rename from net/irda/irnet/Kconfig
rename to drivers/staging/irda/net/irnet/Kconfig
diff --git a/net/irda/irnet/Makefile b/drivers/staging/irda/net/irnet/Makefile
similarity index 100%
rename from net/irda/irnet/Makefile
rename to drivers/staging/irda/net/irnet/Makefile
diff --git a/net/irda/irnet/irnet.h b/drivers/staging/irda/net/irnet/irnet.h
similarity index 100%
rename from net/irda/irnet/irnet.h
rename to drivers/staging/irda/net/irnet/irnet.h
diff --git a/net/irda/irnet/irnet_irda.c b/drivers/staging/irda/net/irnet/irnet_irda.c
similarity index 100%
rename from net/irda/irnet/irnet_irda.c
rename to drivers/staging/irda/net/irnet/irnet_irda.c
diff --git a/net/irda/irnet/irnet_irda.h b/drivers/staging/irda/net/irnet/irnet_irda.h
similarity index 100%
rename from net/irda/irnet/irnet_irda.h
rename to drivers/staging/irda/net/irnet/irnet_irda.h
diff --git a/net/irda/irnet/irnet_ppp.c b/drivers/staging/irda/net/irnet/irnet_ppp.c
similarity index 100%
rename from net/irda/irnet/irnet_ppp.c
rename to drivers/staging/irda/net/irnet/irnet_ppp.c
diff --git a/net/irda/irnet/irnet_ppp.h b/drivers/staging/irda/net/irnet/irnet_ppp.h
similarity index 100%
rename from net/irda/irnet/irnet_ppp.h
rename to drivers/staging/irda/net/irnet/irnet_ppp.h
diff --git a/net/irda/irnetlink.c b/drivers/staging/irda/net/irnetlink.c
similarity index 100%
rename from net/irda/irnetlink.c
rename to drivers/staging/irda/net/irnetlink.c
diff --git a/net/irda/irproc.c b/drivers/staging/irda/net/irproc.c
similarity index 100%
rename from net/irda/irproc.c
rename to drivers/staging/irda/net/irproc.c
diff --git a/net/irda/irqueue.c b/drivers/staging/irda/net/irqueue.c
similarity index 100%
rename from net/irda/irqueue.c
rename to drivers/staging/irda/net/irqueue.c
diff --git a/net/irda/irsysctl.c b/drivers/staging/irda/net/irsysctl.c
similarity index 100%
rename from net/irda/irsysctl.c
rename to drivers/staging/irda/net/irsysctl.c
diff --git a/net/irda/irttp.c b/drivers/staging/irda/net/irttp.c
similarity index 100%
rename from net/irda/irttp.c
rename to drivers/staging/irda/net/irttp.c
diff --git a/net/irda/parameters.c b/drivers/staging/irda/net/parameters.c
similarity index 100%
rename from net/irda/parameters.c
rename to drivers/staging/irda/net/parameters.c
diff --git a/net/irda/qos.c b/drivers/staging/irda/net/qos.c
similarity index 100%
rename from net/irda/qos.c
rename to drivers/staging/irda/net/qos.c
diff --git a/net/irda/timer.c b/drivers/staging/irda/net/timer.c
similarity index 100%
rename from net/irda/timer.c
rename to drivers/staging/irda/net/timer.c
diff --git a/net/irda/wrapper.c b/drivers/staging/irda/net/wrapper.c
similarity index 100%
rename from net/irda/wrapper.c
rename to drivers/staging/irda/net/wrapper.c
diff --git a/net/Kconfig b/net/Kconfig
index 7d57ef34b79c..992a5b8f72d7 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -364,7 +364,6 @@ endmenu
 
 source "net/ax25/Kconfig"
 source "net/can/Kconfig"
-source "net/irda/Kconfig"
 source "net/bluetooth/Kconfig"
 source "net/rxrpc/Kconfig"
 source "net/kcm/Kconfig"
diff --git a/net/Makefile b/net/Makefile
index bed80fa398b7..3d3feff3643b 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -31,7 +31,6 @@ obj-$(CONFIG_NETROM)		+= netrom/
 obj-$(CONFIG_ROSE)		+= rose/
 obj-$(CONFIG_AX25)		+= ax25/
 obj-$(CONFIG_CAN)		+= can/
-obj-$(CONFIG_IRDA)		+= irda/
 obj-$(CONFIG_BT)		+= bluetooth/
 obj-$(CONFIG_SUNRPC)		+= sunrpc/
 obj-$(CONFIG_AF_RXRPC)		+= rxrpc/
-- 
2.14.1

^ permalink raw reply related

* [PATCH 2/4] irda: move drivers/net/irda to drivers/staging/irda/drivers
From: Greg Kroah-Hartman @ 2017-08-27 15:03 UTC (permalink / raw)
  To: davem, samuel; +Cc: netdev, linux-kernel, devel, Greg Kroah-Hartman
In-Reply-To: <20170827150334.32495-1-gregkh@linuxfoundation.org>

Move the irda drivers from drivers/net/irda/ to
drivers/staging/irda/drivers as they will be deleted in a future kernel
release.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/Makefile                                        | 1 -
 drivers/staging/Makefile                                    | 1 +
 drivers/{net/irda => staging/irda/drivers}/Kconfig          | 0
 drivers/{net/irda => staging/irda/drivers}/Makefile         | 0
 drivers/{net/irda => staging/irda/drivers}/act200l-sir.c    | 0
 drivers/{net/irda => staging/irda/drivers}/actisys-sir.c    | 0
 drivers/{net/irda => staging/irda/drivers}/ali-ircc.c       | 0
 drivers/{net/irda => staging/irda/drivers}/ali-ircc.h       | 0
 drivers/{net/irda => staging/irda/drivers}/au1k_ir.c        | 0
 drivers/{net/irda => staging/irda/drivers}/bfin_sir.c       | 0
 drivers/{net/irda => staging/irda/drivers}/bfin_sir.h       | 0
 drivers/{net/irda => staging/irda/drivers}/donauboe.c       | 0
 drivers/{net/irda => staging/irda/drivers}/donauboe.h       | 0
 drivers/{net/irda => staging/irda/drivers}/esi-sir.c        | 0
 drivers/{net/irda => staging/irda/drivers}/girbil-sir.c     | 0
 drivers/{net/irda => staging/irda/drivers}/irda-usb.c       | 0
 drivers/{net/irda => staging/irda/drivers}/irda-usb.h       | 0
 drivers/{net/irda => staging/irda/drivers}/irtty-sir.c      | 0
 drivers/{net/irda => staging/irda/drivers}/irtty-sir.h      | 0
 drivers/{net/irda => staging/irda/drivers}/kingsun-sir.c    | 0
 drivers/{net/irda => staging/irda/drivers}/ks959-sir.c      | 0
 drivers/{net/irda => staging/irda/drivers}/ksdazzle-sir.c   | 0
 drivers/{net/irda => staging/irda/drivers}/litelink-sir.c   | 0
 drivers/{net/irda => staging/irda/drivers}/ma600-sir.c      | 0
 drivers/{net/irda => staging/irda/drivers}/mcp2120-sir.c    | 0
 drivers/{net/irda => staging/irda/drivers}/mcs7780.c        | 0
 drivers/{net/irda => staging/irda/drivers}/mcs7780.h        | 0
 drivers/{net/irda => staging/irda/drivers}/nsc-ircc.c       | 0
 drivers/{net/irda => staging/irda/drivers}/nsc-ircc.h       | 0
 drivers/{net/irda => staging/irda/drivers}/old_belkin-sir.c | 0
 drivers/{net/irda => staging/irda/drivers}/pxaficp_ir.c     | 0
 drivers/{net/irda => staging/irda/drivers}/sa1100_ir.c      | 0
 drivers/{net/irda => staging/irda/drivers}/sh_sir.c         | 0
 drivers/{net/irda => staging/irda/drivers}/sir-dev.h        | 0
 drivers/{net/irda => staging/irda/drivers}/sir_dev.c        | 0
 drivers/{net/irda => staging/irda/drivers}/sir_dongle.c     | 0
 drivers/{net/irda => staging/irda/drivers}/smsc-ircc2.c     | 0
 drivers/{net/irda => staging/irda/drivers}/smsc-ircc2.h     | 0
 drivers/{net/irda => staging/irda/drivers}/smsc-sio.h       | 0
 drivers/{net/irda => staging/irda/drivers}/stir4200.c       | 0
 drivers/{net/irda => staging/irda/drivers}/tekram-sir.c     | 0
 drivers/{net/irda => staging/irda/drivers}/toim3232-sir.c   | 0
 drivers/{net/irda => staging/irda/drivers}/via-ircc.c       | 0
 drivers/{net/irda => staging/irda/drivers}/via-ircc.h       | 0
 drivers/{net/irda => staging/irda/drivers}/vlsi_ir.c        | 0
 drivers/{net/irda => staging/irda/drivers}/vlsi_ir.h        | 0
 drivers/{net/irda => staging/irda/drivers}/w83977af.h       | 0
 drivers/{net/irda => staging/irda/drivers}/w83977af_ir.c    | 0
 drivers/{net/irda => staging/irda/drivers}/w83977af_ir.h    | 0
 drivers/staging/irda/net/Kconfig                            | 2 +-
 50 files changed, 2 insertions(+), 2 deletions(-)
 rename drivers/{net/irda => staging/irda/drivers}/Kconfig (100%)
 rename drivers/{net/irda => staging/irda/drivers}/Makefile (100%)
 rename drivers/{net/irda => staging/irda/drivers}/act200l-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/actisys-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/ali-ircc.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/ali-ircc.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/au1k_ir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/bfin_sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/bfin_sir.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/donauboe.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/donauboe.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/esi-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/girbil-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/irda-usb.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/irda-usb.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/irtty-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/irtty-sir.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/kingsun-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/ks959-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/ksdazzle-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/litelink-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/ma600-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/mcp2120-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/mcs7780.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/mcs7780.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/nsc-ircc.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/nsc-ircc.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/old_belkin-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/pxaficp_ir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/sa1100_ir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/sh_sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/sir-dev.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/sir_dev.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/sir_dongle.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/smsc-ircc2.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/smsc-ircc2.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/smsc-sio.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/stir4200.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/tekram-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/toim3232-sir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/via-ircc.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/via-ircc.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/vlsi_ir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/vlsi_ir.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/w83977af.h (100%)
 rename drivers/{net/irda => staging/irda/drivers}/w83977af_ir.c (100%)
 rename drivers/{net/irda => staging/irda/drivers}/w83977af_ir.h (100%)

diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index b2f6556d8848..8dff900085d6 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -45,7 +45,6 @@ obj-$(CONFIG_ETHERNET) += ethernet/
 obj-$(CONFIG_FDDI) += fddi/
 obj-$(CONFIG_HIPPI) += hippi/
 obj-$(CONFIG_HAMRADIO) += hamradio/
-obj-$(CONFIG_IRDA) += irda/
 obj-$(CONFIG_PLIP) += plip/
 obj-$(CONFIG_PPP) += ppp/
 obj-$(CONFIG_PPP_ASYNC) += ppp/
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 509fbacf9a7e..fced929a0e67 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -3,6 +3,7 @@
 obj-y				+= media/
 obj-y				+= typec/
 obj-$(CONFIG_IRDA)		+= irda/net/
+obj-$(CONFIG_IRDA)		+= irda/drivers/
 obj-$(CONFIG_PRISM2_USB)	+= wlan-ng/
 obj-$(CONFIG_COMEDI)		+= comedi/
 obj-$(CONFIG_FB_OLPC_DCON)	+= olpc_dcon/
diff --git a/drivers/net/irda/Kconfig b/drivers/staging/irda/drivers/Kconfig
similarity index 100%
rename from drivers/net/irda/Kconfig
rename to drivers/staging/irda/drivers/Kconfig
diff --git a/drivers/net/irda/Makefile b/drivers/staging/irda/drivers/Makefile
similarity index 100%
rename from drivers/net/irda/Makefile
rename to drivers/staging/irda/drivers/Makefile
diff --git a/drivers/net/irda/act200l-sir.c b/drivers/staging/irda/drivers/act200l-sir.c
similarity index 100%
rename from drivers/net/irda/act200l-sir.c
rename to drivers/staging/irda/drivers/act200l-sir.c
diff --git a/drivers/net/irda/actisys-sir.c b/drivers/staging/irda/drivers/actisys-sir.c
similarity index 100%
rename from drivers/net/irda/actisys-sir.c
rename to drivers/staging/irda/drivers/actisys-sir.c
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/staging/irda/drivers/ali-ircc.c
similarity index 100%
rename from drivers/net/irda/ali-ircc.c
rename to drivers/staging/irda/drivers/ali-ircc.c
diff --git a/drivers/net/irda/ali-ircc.h b/drivers/staging/irda/drivers/ali-ircc.h
similarity index 100%
rename from drivers/net/irda/ali-ircc.h
rename to drivers/staging/irda/drivers/ali-ircc.h
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/staging/irda/drivers/au1k_ir.c
similarity index 100%
rename from drivers/net/irda/au1k_ir.c
rename to drivers/staging/irda/drivers/au1k_ir.c
diff --git a/drivers/net/irda/bfin_sir.c b/drivers/staging/irda/drivers/bfin_sir.c
similarity index 100%
rename from drivers/net/irda/bfin_sir.c
rename to drivers/staging/irda/drivers/bfin_sir.c
diff --git a/drivers/net/irda/bfin_sir.h b/drivers/staging/irda/drivers/bfin_sir.h
similarity index 100%
rename from drivers/net/irda/bfin_sir.h
rename to drivers/staging/irda/drivers/bfin_sir.h
diff --git a/drivers/net/irda/donauboe.c b/drivers/staging/irda/drivers/donauboe.c
similarity index 100%
rename from drivers/net/irda/donauboe.c
rename to drivers/staging/irda/drivers/donauboe.c
diff --git a/drivers/net/irda/donauboe.h b/drivers/staging/irda/drivers/donauboe.h
similarity index 100%
rename from drivers/net/irda/donauboe.h
rename to drivers/staging/irda/drivers/donauboe.h
diff --git a/drivers/net/irda/esi-sir.c b/drivers/staging/irda/drivers/esi-sir.c
similarity index 100%
rename from drivers/net/irda/esi-sir.c
rename to drivers/staging/irda/drivers/esi-sir.c
diff --git a/drivers/net/irda/girbil-sir.c b/drivers/staging/irda/drivers/girbil-sir.c
similarity index 100%
rename from drivers/net/irda/girbil-sir.c
rename to drivers/staging/irda/drivers/girbil-sir.c
diff --git a/drivers/net/irda/irda-usb.c b/drivers/staging/irda/drivers/irda-usb.c
similarity index 100%
rename from drivers/net/irda/irda-usb.c
rename to drivers/staging/irda/drivers/irda-usb.c
diff --git a/drivers/net/irda/irda-usb.h b/drivers/staging/irda/drivers/irda-usb.h
similarity index 100%
rename from drivers/net/irda/irda-usb.h
rename to drivers/staging/irda/drivers/irda-usb.h
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/staging/irda/drivers/irtty-sir.c
similarity index 100%
rename from drivers/net/irda/irtty-sir.c
rename to drivers/staging/irda/drivers/irtty-sir.c
diff --git a/drivers/net/irda/irtty-sir.h b/drivers/staging/irda/drivers/irtty-sir.h
similarity index 100%
rename from drivers/net/irda/irtty-sir.h
rename to drivers/staging/irda/drivers/irtty-sir.h
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/staging/irda/drivers/kingsun-sir.c
similarity index 100%
rename from drivers/net/irda/kingsun-sir.c
rename to drivers/staging/irda/drivers/kingsun-sir.c
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/staging/irda/drivers/ks959-sir.c
similarity index 100%
rename from drivers/net/irda/ks959-sir.c
rename to drivers/staging/irda/drivers/ks959-sir.c
diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/staging/irda/drivers/ksdazzle-sir.c
similarity index 100%
rename from drivers/net/irda/ksdazzle-sir.c
rename to drivers/staging/irda/drivers/ksdazzle-sir.c
diff --git a/drivers/net/irda/litelink-sir.c b/drivers/staging/irda/drivers/litelink-sir.c
similarity index 100%
rename from drivers/net/irda/litelink-sir.c
rename to drivers/staging/irda/drivers/litelink-sir.c
diff --git a/drivers/net/irda/ma600-sir.c b/drivers/staging/irda/drivers/ma600-sir.c
similarity index 100%
rename from drivers/net/irda/ma600-sir.c
rename to drivers/staging/irda/drivers/ma600-sir.c
diff --git a/drivers/net/irda/mcp2120-sir.c b/drivers/staging/irda/drivers/mcp2120-sir.c
similarity index 100%
rename from drivers/net/irda/mcp2120-sir.c
rename to drivers/staging/irda/drivers/mcp2120-sir.c
diff --git a/drivers/net/irda/mcs7780.c b/drivers/staging/irda/drivers/mcs7780.c
similarity index 100%
rename from drivers/net/irda/mcs7780.c
rename to drivers/staging/irda/drivers/mcs7780.c
diff --git a/drivers/net/irda/mcs7780.h b/drivers/staging/irda/drivers/mcs7780.h
similarity index 100%
rename from drivers/net/irda/mcs7780.h
rename to drivers/staging/irda/drivers/mcs7780.h
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/staging/irda/drivers/nsc-ircc.c
similarity index 100%
rename from drivers/net/irda/nsc-ircc.c
rename to drivers/staging/irda/drivers/nsc-ircc.c
diff --git a/drivers/net/irda/nsc-ircc.h b/drivers/staging/irda/drivers/nsc-ircc.h
similarity index 100%
rename from drivers/net/irda/nsc-ircc.h
rename to drivers/staging/irda/drivers/nsc-ircc.h
diff --git a/drivers/net/irda/old_belkin-sir.c b/drivers/staging/irda/drivers/old_belkin-sir.c
similarity index 100%
rename from drivers/net/irda/old_belkin-sir.c
rename to drivers/staging/irda/drivers/old_belkin-sir.c
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/staging/irda/drivers/pxaficp_ir.c
similarity index 100%
rename from drivers/net/irda/pxaficp_ir.c
rename to drivers/staging/irda/drivers/pxaficp_ir.c
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/staging/irda/drivers/sa1100_ir.c
similarity index 100%
rename from drivers/net/irda/sa1100_ir.c
rename to drivers/staging/irda/drivers/sa1100_ir.c
diff --git a/drivers/net/irda/sh_sir.c b/drivers/staging/irda/drivers/sh_sir.c
similarity index 100%
rename from drivers/net/irda/sh_sir.c
rename to drivers/staging/irda/drivers/sh_sir.c
diff --git a/drivers/net/irda/sir-dev.h b/drivers/staging/irda/drivers/sir-dev.h
similarity index 100%
rename from drivers/net/irda/sir-dev.h
rename to drivers/staging/irda/drivers/sir-dev.h
diff --git a/drivers/net/irda/sir_dev.c b/drivers/staging/irda/drivers/sir_dev.c
similarity index 100%
rename from drivers/net/irda/sir_dev.c
rename to drivers/staging/irda/drivers/sir_dev.c
diff --git a/drivers/net/irda/sir_dongle.c b/drivers/staging/irda/drivers/sir_dongle.c
similarity index 100%
rename from drivers/net/irda/sir_dongle.c
rename to drivers/staging/irda/drivers/sir_dongle.c
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/staging/irda/drivers/smsc-ircc2.c
similarity index 100%
rename from drivers/net/irda/smsc-ircc2.c
rename to drivers/staging/irda/drivers/smsc-ircc2.c
diff --git a/drivers/net/irda/smsc-ircc2.h b/drivers/staging/irda/drivers/smsc-ircc2.h
similarity index 100%
rename from drivers/net/irda/smsc-ircc2.h
rename to drivers/staging/irda/drivers/smsc-ircc2.h
diff --git a/drivers/net/irda/smsc-sio.h b/drivers/staging/irda/drivers/smsc-sio.h
similarity index 100%
rename from drivers/net/irda/smsc-sio.h
rename to drivers/staging/irda/drivers/smsc-sio.h
diff --git a/drivers/net/irda/stir4200.c b/drivers/staging/irda/drivers/stir4200.c
similarity index 100%
rename from drivers/net/irda/stir4200.c
rename to drivers/staging/irda/drivers/stir4200.c
diff --git a/drivers/net/irda/tekram-sir.c b/drivers/staging/irda/drivers/tekram-sir.c
similarity index 100%
rename from drivers/net/irda/tekram-sir.c
rename to drivers/staging/irda/drivers/tekram-sir.c
diff --git a/drivers/net/irda/toim3232-sir.c b/drivers/staging/irda/drivers/toim3232-sir.c
similarity index 100%
rename from drivers/net/irda/toim3232-sir.c
rename to drivers/staging/irda/drivers/toim3232-sir.c
diff --git a/drivers/net/irda/via-ircc.c b/drivers/staging/irda/drivers/via-ircc.c
similarity index 100%
rename from drivers/net/irda/via-ircc.c
rename to drivers/staging/irda/drivers/via-ircc.c
diff --git a/drivers/net/irda/via-ircc.h b/drivers/staging/irda/drivers/via-ircc.h
similarity index 100%
rename from drivers/net/irda/via-ircc.h
rename to drivers/staging/irda/drivers/via-ircc.h
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/staging/irda/drivers/vlsi_ir.c
similarity index 100%
rename from drivers/net/irda/vlsi_ir.c
rename to drivers/staging/irda/drivers/vlsi_ir.c
diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/staging/irda/drivers/vlsi_ir.h
similarity index 100%
rename from drivers/net/irda/vlsi_ir.h
rename to drivers/staging/irda/drivers/vlsi_ir.h
diff --git a/drivers/net/irda/w83977af.h b/drivers/staging/irda/drivers/w83977af.h
similarity index 100%
rename from drivers/net/irda/w83977af.h
rename to drivers/staging/irda/drivers/w83977af.h
diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/staging/irda/drivers/w83977af_ir.c
similarity index 100%
rename from drivers/net/irda/w83977af_ir.c
rename to drivers/staging/irda/drivers/w83977af_ir.c
diff --git a/drivers/net/irda/w83977af_ir.h b/drivers/staging/irda/drivers/w83977af_ir.h
similarity index 100%
rename from drivers/net/irda/w83977af_ir.h
rename to drivers/staging/irda/drivers/w83977af_ir.h
diff --git a/drivers/staging/irda/net/Kconfig b/drivers/staging/irda/net/Kconfig
index cd775e1ea0e9..6abeae6c666a 100644
--- a/drivers/staging/irda/net/Kconfig
+++ b/drivers/staging/irda/net/Kconfig
@@ -92,5 +92,5 @@ config IRDA_DEBUG
 
 	  If unsure, say Y (since it makes it easier to find the bugs).
 
-source "drivers/net/irda/Kconfig"
+source "drivers/staging/irda/drivers/Kconfig"
 
-- 
2.14.1

^ permalink raw reply related

* [PATCH 4/4] staging: irda: add a TODO file.
From: Greg Kroah-Hartman @ 2017-08-27 15:03 UTC (permalink / raw)
  To: davem, samuel; +Cc: netdev, linux-kernel, devel, Greg Kroah-Hartman
In-Reply-To: <20170827150334.32495-1-gregkh@linuxfoundation.org>

The irda code will be deleted in a future kernel release, so no need to
have anyone do any new work on it.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/staging/irda/TODO | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 drivers/staging/irda/TODO

diff --git a/drivers/staging/irda/TODO b/drivers/staging/irda/TODO
new file mode 100644
index 000000000000..7d98a5cffaff
--- /dev/null
+++ b/drivers/staging/irda/TODO
@@ -0,0 +1,4 @@
+The irda code will be removed soon from the kernel tree as it is old and
+obsolete and broken.
+
+Don't worry about fixing up anything here, it's not needed.
-- 
2.14.1

^ permalink raw reply related

* [PATCH 3/4] irda: move include/net/irda into staging subdirectory
From: Greg Kroah-Hartman @ 2017-08-27 15:03 UTC (permalink / raw)
  To: davem, samuel; +Cc: netdev, linux-kernel, devel, Greg Kroah-Hartman
In-Reply-To: <20170827150334.32495-1-gregkh@linuxfoundation.org>

And finally, move the irda include files into
drivers/staging/irda/include/net/irda.  Yes, it's a long path, but it
makes it easy for us to just add a Makefile directory path addition and
all of the net and drivers code "just works".

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/staging/irda/drivers/Makefile                                  | 2 ++
 {include => drivers/staging/irda/include}/net/irda/af_irda.h           | 0
 {include => drivers/staging/irda/include}/net/irda/crc.h               | 0
 {include => drivers/staging/irda/include}/net/irda/discovery.h         | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_core.h       | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_event.h      | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_lmp.h        | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_param.h      | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_ttp.h        | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_tty.h        | 0
 {include => drivers/staging/irda/include}/net/irda/ircomm_tty_attach.h | 0
 {include => drivers/staging/irda/include}/net/irda/irda.h              | 0
 {include => drivers/staging/irda/include}/net/irda/irda_device.h       | 0
 {include => drivers/staging/irda/include}/net/irda/iriap.h             | 0
 {include => drivers/staging/irda/include}/net/irda/iriap_event.h       | 0
 {include => drivers/staging/irda/include}/net/irda/irias_object.h      | 0
 {include => drivers/staging/irda/include}/net/irda/irlan_client.h      | 0
 {include => drivers/staging/irda/include}/net/irda/irlan_common.h      | 0
 {include => drivers/staging/irda/include}/net/irda/irlan_eth.h         | 0
 {include => drivers/staging/irda/include}/net/irda/irlan_event.h       | 0
 {include => drivers/staging/irda/include}/net/irda/irlan_filter.h      | 0
 {include => drivers/staging/irda/include}/net/irda/irlan_provider.h    | 0
 {include => drivers/staging/irda/include}/net/irda/irlap.h             | 0
 {include => drivers/staging/irda/include}/net/irda/irlap_event.h       | 0
 {include => drivers/staging/irda/include}/net/irda/irlap_frame.h       | 0
 {include => drivers/staging/irda/include}/net/irda/irlmp.h             | 0
 {include => drivers/staging/irda/include}/net/irda/irlmp_event.h       | 0
 {include => drivers/staging/irda/include}/net/irda/irlmp_frame.h       | 0
 {include => drivers/staging/irda/include}/net/irda/irmod.h             | 0
 {include => drivers/staging/irda/include}/net/irda/irqueue.h           | 0
 {include => drivers/staging/irda/include}/net/irda/irttp.h             | 0
 {include => drivers/staging/irda/include}/net/irda/parameters.h        | 0
 {include => drivers/staging/irda/include}/net/irda/qos.h               | 0
 {include => drivers/staging/irda/include}/net/irda/timer.h             | 0
 {include => drivers/staging/irda/include}/net/irda/wrapper.h           | 0
 drivers/staging/irda/net/Makefile                                      | 2 ++
 36 files changed, 4 insertions(+)
 rename {include => drivers/staging/irda/include}/net/irda/af_irda.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/crc.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/discovery.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_core.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_event.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_lmp.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_param.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_ttp.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_tty.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/ircomm_tty_attach.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irda.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irda_device.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/iriap.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/iriap_event.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irias_object.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_client.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_common.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_eth.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_event.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_filter.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlan_provider.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlap.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlap_event.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlap_frame.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlmp.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlmp_event.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irlmp_frame.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irmod.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irqueue.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/irttp.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/parameters.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/qos.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/timer.h (100%)
 rename {include => drivers/staging/irda/include}/net/irda/wrapper.h (100%)

diff --git a/drivers/staging/irda/drivers/Makefile b/drivers/staging/irda/drivers/Makefile
index 4c344433dae5..e2901b135528 100644
--- a/drivers/staging/irda/drivers/Makefile
+++ b/drivers/staging/irda/drivers/Makefile
@@ -5,6 +5,8 @@
 # Rewritten to use lists instead of if-statements.
 #
 
+subdir-ccflags-y += -I$(srctree)/drivers/staging/irda/include
+
 # FIR drivers
 obj-$(CONFIG_USB_IRDA)		+= irda-usb.o
 obj-$(CONFIG_SIGMATEL_FIR)	+= stir4200.o
diff --git a/include/net/irda/af_irda.h b/drivers/staging/irda/include/net/irda/af_irda.h
similarity index 100%
rename from include/net/irda/af_irda.h
rename to drivers/staging/irda/include/net/irda/af_irda.h
diff --git a/include/net/irda/crc.h b/drivers/staging/irda/include/net/irda/crc.h
similarity index 100%
rename from include/net/irda/crc.h
rename to drivers/staging/irda/include/net/irda/crc.h
diff --git a/include/net/irda/discovery.h b/drivers/staging/irda/include/net/irda/discovery.h
similarity index 100%
rename from include/net/irda/discovery.h
rename to drivers/staging/irda/include/net/irda/discovery.h
diff --git a/include/net/irda/ircomm_core.h b/drivers/staging/irda/include/net/irda/ircomm_core.h
similarity index 100%
rename from include/net/irda/ircomm_core.h
rename to drivers/staging/irda/include/net/irda/ircomm_core.h
diff --git a/include/net/irda/ircomm_event.h b/drivers/staging/irda/include/net/irda/ircomm_event.h
similarity index 100%
rename from include/net/irda/ircomm_event.h
rename to drivers/staging/irda/include/net/irda/ircomm_event.h
diff --git a/include/net/irda/ircomm_lmp.h b/drivers/staging/irda/include/net/irda/ircomm_lmp.h
similarity index 100%
rename from include/net/irda/ircomm_lmp.h
rename to drivers/staging/irda/include/net/irda/ircomm_lmp.h
diff --git a/include/net/irda/ircomm_param.h b/drivers/staging/irda/include/net/irda/ircomm_param.h
similarity index 100%
rename from include/net/irda/ircomm_param.h
rename to drivers/staging/irda/include/net/irda/ircomm_param.h
diff --git a/include/net/irda/ircomm_ttp.h b/drivers/staging/irda/include/net/irda/ircomm_ttp.h
similarity index 100%
rename from include/net/irda/ircomm_ttp.h
rename to drivers/staging/irda/include/net/irda/ircomm_ttp.h
diff --git a/include/net/irda/ircomm_tty.h b/drivers/staging/irda/include/net/irda/ircomm_tty.h
similarity index 100%
rename from include/net/irda/ircomm_tty.h
rename to drivers/staging/irda/include/net/irda/ircomm_tty.h
diff --git a/include/net/irda/ircomm_tty_attach.h b/drivers/staging/irda/include/net/irda/ircomm_tty_attach.h
similarity index 100%
rename from include/net/irda/ircomm_tty_attach.h
rename to drivers/staging/irda/include/net/irda/ircomm_tty_attach.h
diff --git a/include/net/irda/irda.h b/drivers/staging/irda/include/net/irda/irda.h
similarity index 100%
rename from include/net/irda/irda.h
rename to drivers/staging/irda/include/net/irda/irda.h
diff --git a/include/net/irda/irda_device.h b/drivers/staging/irda/include/net/irda/irda_device.h
similarity index 100%
rename from include/net/irda/irda_device.h
rename to drivers/staging/irda/include/net/irda/irda_device.h
diff --git a/include/net/irda/iriap.h b/drivers/staging/irda/include/net/irda/iriap.h
similarity index 100%
rename from include/net/irda/iriap.h
rename to drivers/staging/irda/include/net/irda/iriap.h
diff --git a/include/net/irda/iriap_event.h b/drivers/staging/irda/include/net/irda/iriap_event.h
similarity index 100%
rename from include/net/irda/iriap_event.h
rename to drivers/staging/irda/include/net/irda/iriap_event.h
diff --git a/include/net/irda/irias_object.h b/drivers/staging/irda/include/net/irda/irias_object.h
similarity index 100%
rename from include/net/irda/irias_object.h
rename to drivers/staging/irda/include/net/irda/irias_object.h
diff --git a/include/net/irda/irlan_client.h b/drivers/staging/irda/include/net/irda/irlan_client.h
similarity index 100%
rename from include/net/irda/irlan_client.h
rename to drivers/staging/irda/include/net/irda/irlan_client.h
diff --git a/include/net/irda/irlan_common.h b/drivers/staging/irda/include/net/irda/irlan_common.h
similarity index 100%
rename from include/net/irda/irlan_common.h
rename to drivers/staging/irda/include/net/irda/irlan_common.h
diff --git a/include/net/irda/irlan_eth.h b/drivers/staging/irda/include/net/irda/irlan_eth.h
similarity index 100%
rename from include/net/irda/irlan_eth.h
rename to drivers/staging/irda/include/net/irda/irlan_eth.h
diff --git a/include/net/irda/irlan_event.h b/drivers/staging/irda/include/net/irda/irlan_event.h
similarity index 100%
rename from include/net/irda/irlan_event.h
rename to drivers/staging/irda/include/net/irda/irlan_event.h
diff --git a/include/net/irda/irlan_filter.h b/drivers/staging/irda/include/net/irda/irlan_filter.h
similarity index 100%
rename from include/net/irda/irlan_filter.h
rename to drivers/staging/irda/include/net/irda/irlan_filter.h
diff --git a/include/net/irda/irlan_provider.h b/drivers/staging/irda/include/net/irda/irlan_provider.h
similarity index 100%
rename from include/net/irda/irlan_provider.h
rename to drivers/staging/irda/include/net/irda/irlan_provider.h
diff --git a/include/net/irda/irlap.h b/drivers/staging/irda/include/net/irda/irlap.h
similarity index 100%
rename from include/net/irda/irlap.h
rename to drivers/staging/irda/include/net/irda/irlap.h
diff --git a/include/net/irda/irlap_event.h b/drivers/staging/irda/include/net/irda/irlap_event.h
similarity index 100%
rename from include/net/irda/irlap_event.h
rename to drivers/staging/irda/include/net/irda/irlap_event.h
diff --git a/include/net/irda/irlap_frame.h b/drivers/staging/irda/include/net/irda/irlap_frame.h
similarity index 100%
rename from include/net/irda/irlap_frame.h
rename to drivers/staging/irda/include/net/irda/irlap_frame.h
diff --git a/include/net/irda/irlmp.h b/drivers/staging/irda/include/net/irda/irlmp.h
similarity index 100%
rename from include/net/irda/irlmp.h
rename to drivers/staging/irda/include/net/irda/irlmp.h
diff --git a/include/net/irda/irlmp_event.h b/drivers/staging/irda/include/net/irda/irlmp_event.h
similarity index 100%
rename from include/net/irda/irlmp_event.h
rename to drivers/staging/irda/include/net/irda/irlmp_event.h
diff --git a/include/net/irda/irlmp_frame.h b/drivers/staging/irda/include/net/irda/irlmp_frame.h
similarity index 100%
rename from include/net/irda/irlmp_frame.h
rename to drivers/staging/irda/include/net/irda/irlmp_frame.h
diff --git a/include/net/irda/irmod.h b/drivers/staging/irda/include/net/irda/irmod.h
similarity index 100%
rename from include/net/irda/irmod.h
rename to drivers/staging/irda/include/net/irda/irmod.h
diff --git a/include/net/irda/irqueue.h b/drivers/staging/irda/include/net/irda/irqueue.h
similarity index 100%
rename from include/net/irda/irqueue.h
rename to drivers/staging/irda/include/net/irda/irqueue.h
diff --git a/include/net/irda/irttp.h b/drivers/staging/irda/include/net/irda/irttp.h
similarity index 100%
rename from include/net/irda/irttp.h
rename to drivers/staging/irda/include/net/irda/irttp.h
diff --git a/include/net/irda/parameters.h b/drivers/staging/irda/include/net/irda/parameters.h
similarity index 100%
rename from include/net/irda/parameters.h
rename to drivers/staging/irda/include/net/irda/parameters.h
diff --git a/include/net/irda/qos.h b/drivers/staging/irda/include/net/irda/qos.h
similarity index 100%
rename from include/net/irda/qos.h
rename to drivers/staging/irda/include/net/irda/qos.h
diff --git a/include/net/irda/timer.h b/drivers/staging/irda/include/net/irda/timer.h
similarity index 100%
rename from include/net/irda/timer.h
rename to drivers/staging/irda/include/net/irda/timer.h
diff --git a/include/net/irda/wrapper.h b/drivers/staging/irda/include/net/irda/wrapper.h
similarity index 100%
rename from include/net/irda/wrapper.h
rename to drivers/staging/irda/include/net/irda/wrapper.h
diff --git a/drivers/staging/irda/net/Makefile b/drivers/staging/irda/net/Makefile
index 187f6c563a4b..bd1a635b88cf 100644
--- a/drivers/staging/irda/net/Makefile
+++ b/drivers/staging/irda/net/Makefile
@@ -2,6 +2,8 @@
 # Makefile for the Linux IrDA protocol layer.
 #
 
+subdir-ccflags-y += -I$(srctree)/drivers/staging/irda/include
+
 obj-$(CONFIG_IRDA) += irda.o
 obj-$(CONFIG_IRLAN) += irlan/
 obj-$(CONFIG_IRNET) += irnet/
-- 
2.14.1

^ permalink raw reply related

* Re: [PATCH 0/4] irda: move it to drivers/staging so we can delete it
From: Joe Perches @ 2017-08-27 15:35 UTC (permalink / raw)
  To: Greg Kroah-Hartman, davem, samuel; +Cc: netdev, linux-kernel, devel
In-Reply-To: <20170827150334.32495-1-gregkh@linuxfoundation.org>

On Sun, 2017-08-27 at 17:03 +0200, Greg Kroah-Hartman wrote:
> The IRDA code has long been obsolete and broken.  So, to keep people
> from trying to use it, and to prevent people from having to maintain it,
> let's move it to drivers/staging/ so that we can delete it entirely from
> the kernel in a few releases.

MAINTAINERS should be updated as well.

It'd probably be nice to try to get an email to
the irda mailing list too if it still works.

^ permalink raw reply

* Re: [PATCH 0/4] irda: move it to drivers/staging so we can delete it
From: Greg Kroah-Hartman @ 2017-08-27 16:13 UTC (permalink / raw)
  To: Joe Perches; +Cc: devel, netdev, samuel, davem, linux-kernel
In-Reply-To: <1503848143.12569.48.camel@perches.com>

On Sun, Aug 27, 2017 at 08:35:43AM -0700, Joe Perches wrote:
> On Sun, 2017-08-27 at 17:03 +0200, Greg Kroah-Hartman wrote:
> > The IRDA code has long been obsolete and broken.  So, to keep people
> > from trying to use it, and to prevent people from having to maintain it,
> > let's move it to drivers/staging/ so that we can delete it entirely from
> > the kernel in a few releases.
> 
> MAINTAINERS should be updated as well.
> 
> It'd probably be nice to try to get an email to
> the irda mailing list too if it still works.

As get_maintainer.pl didn't show it, odds are it doesn't...

^ permalink raw reply

* Re: [PATCH 0/4] irda: move it to drivers/staging so we can delete it
From: Joe Perches @ 2017-08-27 16:19 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: devel, netdev, samuel, davem, linux-kernel
In-Reply-To: <20170827161307.GA3528@kroah.com>

On Sun, 2017-08-27 at 18:13 +0200, Greg Kroah-Hartman wrote:
> On Sun, Aug 27, 2017 at 08:35:43AM -0700, Joe Perches wrote:
> > On Sun, 2017-08-27 at 17:03 +0200, Greg Kroah-Hartman wrote:
> > > The IRDA code has long been obsolete and broken.  So, to keep people
> > > from trying to use it, and to prevent people from having to maintain it,
> > > let's move it to drivers/staging/ so that we can delete it entirely from
> > > the kernel in a few releases.
> > 
> > 
> > MAINTAINERS should be updated as well.
> > 
> > It'd probably be nice to try to get an email to
> > the irda mailing list too if it still works.
> 
> As get_maintainer.pl didn't show it, odds are it doesn't...

get_maintainer doesn't show it because it's subscriber-only.
If you want get_maintainer to show it, add -s

$ ./scripts/get_maintainer.pl  -s -f net/irda/
Samuel Ortiz <samuel@sortiz.org> (maintainer:IRDA SUBSYSTEM)
"David S. Miller" <davem@davemloft.net> (maintainer:NETWORKING [GENERAL])
irda-users@lists.sourceforge.net (subscriber list:IRDA SUBSYSTEM)
netdev@vger.kernel.org (open list:IRDA SUBSYSTEM)
linux-kernel@vger.kernel.org (open list)

^ permalink raw reply

* Re: [PATCH] DSA support for Micrel KSZ8895
From: Andrew Lunn @ 2017-08-27 16:31 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Woojung.Huh, nathan.leigh.conrad, vivien.didelot, f.fainelli,
	netdev, linux-kernel, Tristram.Ha
In-Reply-To: <20170827123658.GA727@amd>

> +/**
> + * sw_r_phy - read data from PHY register
> + * @sw:		The switch instance.
> + * @phy:	PHY address to read.
> + * @reg:	PHY register to read.
> + * @val:	Buffer to store the read data.
> + *
> + * This routine reads data from the PHY register.
> + */
> +static void sw_r_phy(struct ksz_device *sw, u16 phy, u16 reg, u16 *val)
> +{
> +	u8 ctrl;
> +	u8 restart;
> +	u8 link;
> +	u8 speed;
> +	u8 force;
> +	u8 p = phy;
> +	u16 data = 0;
> +
> +	switch (reg) {
> +	case PHY_REG_CTRL:
> +		ksz_pread8(sw, p, P_LOCAL_CTRL, &ctrl);
> +		ksz_pread8(sw, p, P_NEG_RESTART_CTRL, &restart);
> +		ksz_pread8(sw, p, P_SPEED_STATUS, &speed);
> +		ksz_pread8(sw, p, P_FORCE_CTRL, &force);
> +		if (restart & PORT_PHY_LOOPBACK)
> +			data |= PHY_LOOPBACK;
> +		if (force & PORT_FORCE_100_MBIT)
> +			data |= PHY_SPEED_100MBIT;
> +		if (!(force & PORT_AUTO_NEG_DISABLE))
> +			data |= PHY_AUTO_NEG_ENABLE;
> +		if (restart & PORT_POWER_DOWN)
> +			data |= PHY_POWER_DOWN;
> +		if (restart & PORT_AUTO_NEG_RESTART)
> +			data |= PHY_AUTO_NEG_RESTART;
> +		if (force & PORT_FORCE_FULL_DUPLEX)
> +			data |= PHY_FULL_DUPLEX;
> +		if (speed & PORT_HP_MDIX)
> +			data |= PHY_HP_MDIX;
> +		if (restart & PORT_FORCE_MDIX)
> +			data |= PHY_FORCE_MDIX;
> +		if (restart & PORT_AUTO_MDIX_DISABLE)
> +			data |= PHY_AUTO_MDIX_DISABLE;
> +		if (restart & PORT_TX_DISABLE)
> +			data |= PHY_TRANSMIT_DISABLE;
> +		if (restart & PORT_LED_OFF)
> +			data |= PHY_LED_DISABLE;
> +		break;
> +	case PHY_REG_STATUS:
> +		ksz_pread8(sw, p, P_LINK_STATUS, &link);
> +		ksz_pread8(sw, p, P_SPEED_STATUS, &speed);
> +		data = PHY_100BTX_FD_CAPABLE |
> +			PHY_100BTX_CAPABLE |
> +			PHY_10BT_FD_CAPABLE |
> +			PHY_10BT_CAPABLE |
> +			PHY_AUTO_NEG_CAPABLE;
> +		if (link & PORT_AUTO_NEG_COMPLETE)
> +			data |= PHY_AUTO_NEG_ACKNOWLEDGE;
> +		if (link & PORT_STAT_LINK_GOOD)
> +			data |= PHY_LINK_STATUS;
> +		break;
> +	case PHY_REG_ID_1:
> +		data = KSZ8895_ID_HI;
> +		break;
> +	case PHY_REG_ID_2:
> +		data = KSZ8895_ID_LO;
> +		break;

According to the datasheet, the PHY has the normal ID registers,
which have the value 0x0022, 0x1450. So it should be possible to have
a standard PHY driver in drivers/net/phy.

In fact, the IDs suggest it is a micrel phy, and 1430, 1435 are
already supported. So it could be you only need minor modifications to
the micrel.c.

    Andrew

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox