[{"id":1777545,"web_url":"http://patchwork.ozlabs.org/comment/1777545/","msgid":"<DB5PR04MB12400025DF190790B4792B50EA7E0@DB5PR04MB1240.eurprd04.prod.outlook.com>","list_archive_url":null,"date":"2017-09-29T13:36:04","subject":"RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale DPAA2\n\tEthernet Switch driver","submitter":{"id":69012,"url":"http://patchwork.ozlabs.org/api/people/69012/","name":"Bogdan Purcareata","email":"bogdan.purcareata@nxp.com"},"content":"> Introduce the DPAA2 Ethernet Switch driver, which manages Datapath Switch\n> (DPSW) objects discovered on the MC bus.\n> \n> Suggested-by: Alexandru Marginean <alexandru.marginean@nxp.com>\n> Signed-off-by: Razvan Stefanescu <razvan.stefanescu@nxp.com>\n> ---\n>  drivers/staging/fsl-dpaa2/ethsw/Makefile |    2 +-\n>  drivers/staging/fsl-dpaa2/ethsw/ethsw.c  | 1523 ++++++++++++++++++++++++++++++\n>  drivers/staging/fsl-dpaa2/ethsw/ethsw.h  |   88 ++\n>  3 files changed, 1612 insertions(+), 1 deletion(-)\n>  create mode 100644 drivers/staging/fsl-dpaa2/ethsw/ethsw.c\n>  create mode 100644 drivers/staging/fsl-dpaa2/ethsw/ethsw.h\n> \n> diff --git a/drivers/staging/fsl-dpaa2/ethsw/Makefile b/drivers/staging/fsl-\n> dpaa2/ethsw/Makefile\n> index db137f7..a6d72d1 100644\n> --- a/drivers/staging/fsl-dpaa2/ethsw/Makefile\n> +++ b/drivers/staging/fsl-dpaa2/ethsw/Makefile\n> @@ -4,4 +4,4 @@\n> \n>  obj-$(CONFIG_FSL_DPAA2_ETHSW) += dpaa2-ethsw.o\n> \n> -dpaa2-ethsw-objs := dpsw.o\n> +dpaa2-ethsw-objs := ethsw.o dpsw.o\n> diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-\n> dpaa2/ethsw/ethsw.c\n> new file mode 100644\n> index 0000000..ae86078\n> --- /dev/null\n> +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c\n> @@ -0,0 +1,1523 @@\n> +/* Copyright 2014-2016 Freescale Semiconductor Inc.\n> + * Copyright 2017 NXP\n> + *\n> + * Redistribution and use in source and binary forms, with or without\n> + * modification, are permitted provided that the following conditions are met:\n> + *     * Redistributions of source code must retain the above copyright\n> + *\t notice, this list of conditions and the following disclaimer.\n> + *     * Redistributions in binary form must reproduce the above copyright\n> + *\t notice, this list of conditions and the following disclaimer in the\n> + *\t documentation and/or other materials provided with the distribution.\n> + *     * Neither the name of the above-listed copyright holders nor the\n> + *\t names of any contributors may be used to endorse or promote products\n> + *\t derived from this software without specific prior written permission.\n> + *\n> + *\n> + * ALTERNATIVELY, this software may be distributed under the terms of the\n> + * GNU General Public License (\"GPL\") as published by the Free Software\n> + * Foundation, either version 2 of that License or (at your option) any\n> + * later version.\n> + *\n> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE\n> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n> + * POSSIBILITY OF SUCH DAMAGE.\n> + */\n> +\n> +#include <linux/module.h>\n> +\n> +#include <linux/interrupt.h>\n> +#include <linux/msi.h>\n> +#include <linux/kthread.h>\n> +#include <linux/workqueue.h>\n> +\n> +#include \"../../fsl-mc/include/mc.h\"\n> +\n> +#include \"ethsw.h\"\n> +\n> +static struct workqueue_struct *ethsw_owq;\n> +\n> +/* Minimal supported DPSW version */\n> +#define DPSW_MIN_VER_MAJOR\t\t8\n> +#define DPSW_MIN_VER_MINOR\t\t0\n> +\n> +#define DEFAULT_VLAN_ID\t\t\t1\n> +\n> +static int ethsw_add_vlan(struct ethsw_core *ethsw, u16 vid)\n> +{\n> +\tint err;\n> +\n> +\tstruct dpsw_vlan_cfg\tvcfg = {\n> +\t\t.fdb_id = 0,\n> +\t};\n> +\n> +\tif (ethsw->vlans[vid]) {\n> +\t\tdev_err(ethsw->dev, \"VLAN already configured\\n\");\n> +\t\treturn -EEXIST;\n> +\t}\n> +\n> +\terr = dpsw_vlan_add(ethsw->mc_io, 0,\n> +\t\t\t    ethsw->dpsw_handle, vid, &vcfg);\n> +\tif (err) {\n> +\t\tdev_err(ethsw->dev, \"dpsw_vlan_add err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\tethsw->vlans[vid] = ETHSW_VLAN_MEMBER;/\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int ethsw_port_add_vlan(struct ethsw_port_priv *port_priv,\n> +\t\t\t       u16 vid, u16 flags)\n> +{\n> +\tstruct ethsw_core *ethsw = port_priv->ethsw_data;\n> +\tstruct net_device *netdev = port_priv->netdev;\n> +\tstruct dpsw_vlan_if_cfg vcfg;\n> +\tbool is_oper;\n> +\tint err, err2;\n\nMild suggestion - s/err2/ret/, just because it sounds better, at least to me (same for similar situations in the rest of the file).\n\n> +\n> +\tif (port_priv->vlans[vid]) {\n> +\t\tnetdev_warn(netdev, \"VLAN %d already configured\\n\", vid);\n> +\t\treturn -EEXIST;\n> +\t}\n> +\n> +\tvcfg.num_ifs = 1;\n> +\tvcfg.if_id[0] = port_priv->idx;\n> +\terr = dpsw_vlan_add_if(ethsw->mc_io, 0, ethsw->dpsw_handle, vid, &vcfg);\n> +\tif (err) {\n> +\t\tnetdev_err(netdev, \"dpsw_vlan_add_if err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\tport_priv->vlans[vid] = ETHSW_VLAN_MEMBER;\n> +\n> +\tif (flags & BRIDGE_VLAN_INFO_UNTAGGED) {\n> +\t\terr = dpsw_vlan_add_if_untagged(ethsw->mc_io, 0,\n> +\t\t\t\t\t\tethsw->dpsw_handle,\n> +\t\t\t\t\t\tvid, &vcfg);\n> +\t\tif (err) {\n> +\t\t\tnetdev_err(netdev,\n> +\t\t\t\t   \"dpsw_vlan_add_if_untagged err %d\\n\", err);\n> +\t\t\treturn err;\n> +\t\t}\n> +\t\tport_priv->vlans[vid] |= ETHSW_VLAN_UNTAGGED;\n> +\t}\n> +\n> +\tif (flags & BRIDGE_VLAN_INFO_PVID) {\n> +\t\tstruct dpsw_tci_cfg tci_cfg = {\n> +\t\t\t.pcp = 0,\n> +\t\t\t.dei = 0,\n> +\t\t\t.vlan_id = vid,\n> +\t\t};\n> +\n> +\t\t/* Interface needs to be down to change PVID */\n> +\t\tis_oper = netif_oper_up(netdev);\n> +\t\tif (is_oper) {\n> +\t\t\terr = dpsw_if_disable(ethsw->mc_io, 0,\n> +\t\t\t\t\t      ethsw->dpsw_handle,\n> +\t\t\t\t\t      port_priv->idx);\n> +\t\t\tif (err) {\n> +\t\t\t\tnetdev_err(netdev,\n> +\t\t\t\t\t   \"dpsw_if_disable err %d\\n\", err);\n> +\t\t\t\treturn err;\n> +\t\t\t}\n> +\t\t}\n> +\n> +\t\terr = dpsw_if_set_tci(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t\t      port_priv->idx, &tci_cfg);\n> +\t\tif (!err) {\n> +\t\t\t/* Delete previous PVID info and mark the new one */\n> +\t\t\tif (port_priv->pvid)\n> +\t\t\t\tport_priv->vlans[port_priv->pvid]\n> +\t\t\t\t\t\t ^= ETHSW_VLAN_PVID;\n\nCan it be \" &= ~ETHSW_VLAN_PVID\" ? Are there other implications?\n\n> +\n> +\t\t\tport_priv->vlans[vid] |= ETHSW_VLAN_PVID;\n> +\t\t\tport_priv->pvid = vid;\n> +\t\t} else {\n> +\t\t\tnetdev_err(netdev, \"dpsw_if_set_tci err %d\\n\", err);\n> +\t\t}\n> +\n> +\t\tif (is_oper) {\n> +\t\t\terr2 = dpsw_if_enable(ethsw->mc_io, 0,\n> +\t\t\t\t\t      ethsw->dpsw_handle,\n> +\t\t\t\t\t      port_priv->idx);\n> +\t\t\tif (err2) {\n> +\t\t\t\tnetdev_err(netdev,\n> +\t\t\t\t\t   \"dpsw_if_enable err %d\\n\", err2);\n> +\t\t\t\treturn err2;\n> +\t\t\t}\n> +\t\t}\n> +\t}\n> +\n> +\treturn err;\n> +}\n> +\n> +static int ethsw_set_learning(struct ethsw_core *ethsw, u8 flag)\n> +{\n> +\tenum dpsw_fdb_learning_mode learn_mode;\n> +\tint err;\n> +\n> +\tif (flag)\n> +\t\tlearn_mode = DPSW_FDB_LEARNING_MODE_HW;\n> +\telse\n> +\t\tlearn_mode = DPSW_FDB_LEARNING_MODE_DIS;\n> +\n> +\terr = dpsw_fdb_set_learning_mode(ethsw->mc_io, 0, ethsw->dpsw_handle, 0,\n> +\t\t\t\t\t learn_mode);\n> +\tif (err) {\n> +\t\tdev_err(ethsw->dev, \"dpsw_fdb_set_learning_mode err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\tethsw->learning = !!flag;\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int ethsw_port_set_flood(struct ethsw_port_priv *port_priv, u8 flag)\n> +{\n> +\tint err;\n> +\n> +\terr = dpsw_if_set_flooding(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t   port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t   port_priv->idx, (int)flag);\n\nWhy is this cast necessary? Can't the API be reworked to use u8 (or, better yet, bool) instead of int?\n\n> +\tif (err) {\n> +\t\tnetdev_err(port_priv->netdev,\n> +\t\t\t   \"dpsw_fdb_set_learning_mode err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\tport_priv->flood = !!flag;\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int ethsw_port_set_stp_state(struct ethsw_port_priv *port_priv, u8\n> state)\n> +{\n> +\tstruct dpsw_stp_cfg stp_cfg = {\n> +\t\t.vlan_id = DEFAULT_VLAN_ID,\n> +\t\t.state = state,\n> +\t};\n> +\tint err;\n> +\n> +\tif (!netif_oper_up(port_priv->netdev) || state == port_priv->stp_state)\n> +\t\treturn 0;\t/* Nothing to do */\n> +\n> +\terr = dpsw_if_set_stp(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t      port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t      port_priv->idx, &stp_cfg);\n> +\tif (err) {\n> +\t\tnetdev_err(port_priv->netdev,\n> +\t\t\t   \"dpsw_if_set_stp err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\tport_priv->stp_state = state;\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int ethsw_dellink_switch(struct ethsw_core *ethsw, u16 vid)\n> +{\n> +\tstruct ethsw_port_priv *ppriv_local = NULL;\n> +\tint i, err;\n> +\n> +\tif (!ethsw->vlans[vid])\n> +\t\treturn -ENOENT;\n> +\n> +\terr = dpsw_vlan_remove(ethsw->mc_io, 0, ethsw->dpsw_handle, vid);\n> +\tif (err) {\n> +\t\tdev_err(ethsw->dev, \"dpsw_vlan_remove err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\tethsw->vlans[vid] = 0;\n> +\n> +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> +\t\tppriv_local = ethsw->ports[i];\n> +\t\tppriv_local->vlans[vid] = 0;\n> +\t}\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int ethsw_port_fdb_add_uc(struct ethsw_port_priv *port_priv,\n> +\t\t\t\t const unsigned char *addr)\n> +{\n> +\tstruct dpsw_fdb_unicast_cfg entry = {0};\n> +\tint err;\n> +\n> +\tentry.if_egress = port_priv->idx;\n> +\tentry.type = DPSW_FDB_ENTRY_STATIC;\n> +\tether_addr_copy(entry.mac_addr, addr);\n> +\n> +\terr = dpsw_fdb_add_unicast(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t   port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t   0, &entry);\n> +\tif (err)\n> +\t\tnetdev_err(port_priv->netdev,\n> +\t\t\t   \"dpsw_fdb_add_unicast err %d\\n\", err);\n> +\treturn err;\n> +}\n> +\n> +static int ethsw_port_fdb_del_uc(struct ethsw_port_priv *port_priv,\n> +\t\t\t\t const unsigned char *addr)\n> +{\n> +\tstruct dpsw_fdb_unicast_cfg entry = {0};\n> +\tint err;\n> +\n> +\tentry.if_egress = port_priv->idx;\n> +\tentry.type = DPSW_FDB_ENTRY_STATIC;\n> +\tether_addr_copy(entry.mac_addr, addr);\n> +\n> +\terr = dpsw_fdb_remove_unicast(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t      port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t      0, &entry);\n> +\tif (err)\n> +\t\tnetdev_err(port_priv->netdev,\n> +\t\t\t   \"dpsw_fdb_remove_unicast err %d\\n\", err);\n> +\treturn err;\n> +}\n> +\n> +static int ethsw_port_fdb_add_mc(struct ethsw_port_priv *port_priv,\n> +\t\t\t\t const unsigned char *addr)\n> +{\n> +\tstruct dpsw_fdb_multicast_cfg entry = {0};\n> +\tint err;\n> +\n> +\tether_addr_copy(entry.mac_addr, addr);\n> +\tentry.type = DPSW_FDB_ENTRY_STATIC;\n> +\tentry.num_ifs = 1;\n> +\tentry.if_id[0] = port_priv->idx;\n> +\n> +\terr = dpsw_fdb_add_multicast(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t     port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t     0, &entry);\n> +\tif (err)\n> +\t\tnetdev_err(port_priv->netdev, \"dpsw_fdb_add_multicast err %d\\n\",\n> +\t\t\t   err);\n> +\treturn err;\n> +}\n> +\n> +static int ethsw_port_fdb_del_mc(struct ethsw_port_priv *port_priv,\n> +\t\t\t\t const unsigned char *addr)\n> +{\n> +\tstruct dpsw_fdb_multicast_cfg entry = {0};\n> +\tint err;\n> +\n> +\tether_addr_copy(entry.mac_addr, addr);\n> +\tentry.type = DPSW_FDB_ENTRY_STATIC;\n> +\tentry.num_ifs = 1;\n> +\tentry.if_id[0] = port_priv->idx;\n> +\n> +\terr = dpsw_fdb_remove_multicast(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t\tport_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t\t0, &entry);\n> +\tif (err)\n> +\t\tnetdev_err(port_priv->netdev,\n> +\t\t\t   \"dpsw_fdb_remove_multicast err %d\\n\", err);\n> +\treturn err;\n> +}\n> +\n> +static void port_get_stats(struct net_device *netdev,\n> +\t\t\t   struct rtnl_link_stats64 *stats)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\tu64 tmp;\n> +\tint err;\n> +\n> +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t  port_priv->idx,\n> +\t\t\t\t  DPSW_CNT_ING_FRAME, &stats->rx_packets);\n> +\tif (err)\n> +\t\tgoto error;\n> +\n> +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t  port_priv->idx,\n> +\t\t\t\t  DPSW_CNT_EGR_FRAME, &stats->tx_packets);\n> +\tif (err)\n> +\t\tgoto error;\n> +\n> +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t  port_priv->idx,\n> +\t\t\t\t  DPSW_CNT_ING_BYTE, &stats->rx_bytes);\n> +\tif (err)\n> +\t\tgoto error;\n> +\n> +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t  port_priv->idx,\n> +\t\t\t\t  DPSW_CNT_EGR_BYTE, &stats->tx_bytes);\n> +\tif (err)\n> +\t\tgoto error;\n> +\n> +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t  port_priv->idx,\n> +\t\t\t\t  DPSW_CNT_ING_FRAME_DISCARD,\n> +\t\t\t\t  &stats->rx_dropped);\n> +\tif (err)\n> +\t\tgoto error;\n> +\n> +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t  port_priv->idx,\n> +\t\t\t\t  DPSW_CNT_ING_FLTR_FRAME,\n> +\t\t\t\t  &tmp);\n> +\tif (err)\n> +\t\tgoto error;\n> +\tstats->rx_dropped += tmp;\n> +\n> +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t  port_priv->idx,\n> +\t\t\t\t  DPSW_CNT_EGR_FRAME_DISCARD,\n> +\t\t\t\t  &stats->tx_dropped);\n> +\tif (err)\n> +\t\tgoto error;\n> +\n> +\treturn;\n> +\n> +error:\n> +\tnetdev_err(netdev, \"dpsw_if_get_counter err %d\\n\", err);\n> +}\n> +\n> +static bool port_has_offload_stats(const struct net_device *netdev,\n> +\t\t\t\t   int attr_id)\n> +{\n> +\treturn (attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT);\n> +}\n> +\n> +static int port_get_offload_stats(int attr_id,\n> +\t\t\t\t  const struct net_device *netdev,\n> +\t\t\t\t  void *sp)\n> +{\n> +\tswitch (attr_id) {\n> +\tcase IFLA_OFFLOAD_XSTATS_CPU_HIT:\n> +\t\tport_get_stats((struct net_device *)netdev, sp);\n> +\t\treturn 0;\n> +\t}\n> +\n> +\treturn -EINVAL;\n> +}\n> +\n> +static int port_change_mtu(struct net_device *netdev, int mtu)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\tint err;\n> +\n> +\terr = dpsw_if_set_max_frame_length(port_priv->ethsw_data->mc_io,\n> +\t\t\t\t\t   0,\n> +\t\t\t\t\t   port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t\t   port_priv->idx,\n> +\t\t\t\t\t   (u16)ETHSW_L2_MAX_FRM(mtu));\n> +\tif (err) {\n> +\t\tnetdev_err(netdev,\n> +\t\t\t   \"dpsw_if_set_max_frame_length() err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\tnetdev->mtu = mtu;\n> +\treturn 0;\n> +}\n> +\n> +static int port_carrier_state_sync(struct net_device *netdev)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\tstruct dpsw_link_state state;\n> +\tint err;\n> +\n> +\terr = dpsw_if_get_link_state(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t\t     port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t\t     port_priv->idx, &state);\n> +\tif (err) {\n> +\t\tnetdev_err(netdev, \"dpsw_if_get_link_state() err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\tWARN_ONCE(state.up > 1, \"Garbage read into link_state\");\n> +\n> +\tif (state.up != port_priv->link_state) {\n> +\t\tif (state.up)\n> +\t\t\tnetif_carrier_on(netdev);\n> +\t\telse\n> +\t\t\tnetif_carrier_off(netdev);\n> +\t\tport_priv->link_state = state.up;\n> +\t}\n> +\treturn 0;\n> +}\n> +\n> +static int port_open(struct net_device *netdev)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\tint err;\n> +\n> +\t/* No need to allow Tx as control interface is disabled */\n> +\tnetif_tx_stop_all_queues(netdev);\n> +\n> +\terr = dpsw_if_enable(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t     port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t     port_priv->idx);\n> +\tif (err) {\n> +\t\tnetdev_err(netdev, \"dpsw_if_enable err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\t/* sync carrier state */\n> +\terr = port_carrier_state_sync(netdev);\n> +\tif (err) {\n> +\t\tnetdev_err(netdev,\n> +\t\t\t   \"port_carrier_state_sync err %d\\n\", err);\n> +\t\tgoto err_carrier_sync;\n> +\t}\n> +\n> +\treturn 0;\n> +\n> +err_carrier_sync:\n> +\tdpsw_if_disable(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\tport_priv->ethsw_data->dpsw_handle,\n> +\t\t\tport_priv->idx);\n> +\treturn err;\n> +}\n> +\n> +static int port_stop(struct net_device *netdev)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\tint err;\n> +\n> +\terr = dpsw_if_disable(port_priv->ethsw_data->mc_io, 0,\n> +\t\t\t      port_priv->ethsw_data->dpsw_handle,\n> +\t\t\t      port_priv->idx);\n> +\tif (err) {\n> +\t\tnetdev_err(netdev, \"dpsw_if_disable err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\treturn 0;\n> +}\n> +\n> +static netdev_tx_t port_dropframe(struct sk_buff *skb,\n> +\t\t\t\t  struct net_device *netdev)\n> +{\n> +\t/* we don't support I/O for now, drop the frame */\n> +\tdev_kfree_skb_any(skb);\n> +\n> +\treturn NETDEV_TX_OK;\n> +}\n> +\n> +static const struct net_device_ops ethsw_port_ops = {\n> +\t.ndo_open\t\t= port_open,\n> +\t.ndo_stop\t\t= port_stop,\n> +\n> +\t.ndo_set_mac_address\t= eth_mac_addr,\n> +\t.ndo_change_mtu\t\t= port_change_mtu,\n> +\t.ndo_has_offload_stats\t= port_has_offload_stats,\n> +\t.ndo_get_offload_stats\t= port_get_offload_stats,\n> +\n> +\t.ndo_start_xmit\t\t= port_dropframe,\n> +};\n> +\n> +static void ethsw_links_state_update(struct ethsw_core *ethsw)\n> +{\n> +\tint i;\n> +\n> +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++)\n> +\t\tport_carrier_state_sync(ethsw->ports[i]->netdev);\n> +}\n> +\n> +static irqreturn_t ethsw_irq0_handler(int irq_num, void *arg)\n> +{\n> +\treturn IRQ_WAKE_THREAD;\n> +}\n> +\n> +static irqreturn_t ethsw_irq0_handler_thread(int irq_num, void *arg)\n> +{\n> +\tstruct device *dev = (struct device *)arg;\n> +\tstruct ethsw_core *ethsw = dev_get_drvdata(dev);\n> +\n> +\t/* Mask the events and the if_id reserved bits to be cleared on read */\n> +\tu32 status = DPSW_IRQ_EVENT_LINK_CHANGED | 0xFFFF0000;\n> +\tint err;\n> +\n> +\terr = dpsw_get_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t\t  DPSW_IRQ_INDEX_IF, &status);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"Can't get irq status (err %d)\", err);\n> +\n> +\t\terr = dpsw_clear_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t\t\t    DPSW_IRQ_INDEX_IF, 0xFFFFFFFF);\n> +\t\tif (err)\n> +\t\t\tdev_err(dev, \"Can't clear irq status (err %d)\", err);\n> +\t\tgoto out;\n> +\t}\n> +\n> +\tif (status & DPSW_IRQ_EVENT_LINK_CHANGED)\n> +\t\tethsw_links_state_update(ethsw);\n> +\n> +out:\n> +\treturn IRQ_HANDLED;\n> +}\n> +\n> +static int ethsw_setup_irqs(struct fsl_mc_device *sw_dev)\n> +{\n> +\tstruct device *dev = &sw_dev->dev;\n> +\tstruct ethsw_core *ethsw = dev_get_drvdata(dev);\n> +\tu32 mask = DPSW_IRQ_EVENT_LINK_CHANGED;\n> +\tstruct fsl_mc_device_irq *irq;\n> +\tint err;\n> +\n> +\terr = fsl_mc_allocate_irqs(sw_dev);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"MC irqs allocation failed\\n\");\n> +\t\treturn err;\n> +\t}\n> +\n> +\tif (WARN_ON(sw_dev->obj_desc.irq_count != DPSW_IRQ_NUM)) {\n> +\t\terr = -EINVAL;\n> +\t\tgoto free_irq;\n> +\t}\n> +\n> +\terr = dpsw_set_irq_enable(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t\t  DPSW_IRQ_INDEX_IF, 0);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"dpsw_set_irq_enable err %d\\n\", err);\n> +\t\tgoto free_irq;\n> +\t}\n> +\n> +\tirq = sw_dev->irqs[DPSW_IRQ_INDEX_IF];\n> +\n> +\terr = devm_request_threaded_irq(dev, irq->msi_desc->irq,\n> +\t\t\t\t\tethsw_irq0_handler,\n> +\t\t\t\t\tethsw_irq0_handler_thread,\n> +\t\t\t\t\tIRQF_NO_SUSPEND | IRQF_ONESHOT,\n> +\t\t\t\t\tdev_name(dev), dev);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"devm_request_threaded_irq(): %d\", err);\n> +\t\tgoto free_irq;\n> +\t}\n> +\n> +\terr = dpsw_set_irq_mask(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t\tDPSW_IRQ_INDEX_IF, mask);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"dpsw_set_irq_mask(): %d\", err);\n> +\t\tgoto free_devm_irq;\n> +\t}\n> +\n> +\terr = dpsw_set_irq_enable(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t\t  DPSW_IRQ_INDEX_IF, 1);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"dpsw_set_irq_enable(): %d\", err);\n> +\t\tgoto free_devm_irq;\n> +\t}\n> +\n> +\treturn 0;\n> +\n> +free_devm_irq:\n> +\tdevm_free_irq(dev, irq->msi_desc->irq, dev);\n> +free_irq:\n> +\tfsl_mc_free_irqs(sw_dev);\n> +\treturn err;\n> +}\n> +\n> +static void ethsw_teardown_irqs(struct fsl_mc_device *sw_dev)\n> +{\n> +\tstruct device *dev = &sw_dev->dev;\n> +\tstruct ethsw_core *ethsw = dev_get_drvdata(dev);\n> +\tstruct fsl_mc_device_irq *irq;\n> +\n> +\tirq = sw_dev->irqs[DPSW_IRQ_INDEX_IF];\n> +\tdpsw_set_irq_enable(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t    DPSW_IRQ_INDEX_IF, 0);\n\nYou can still print an error message here, in case something goes wrong.\n\n> +\tfsl_mc_free_irqs(sw_dev);\n> +}\n> +\n> +static int swdev_port_attr_get(struct net_device *netdev,\n> +\t\t\t       struct switchdev_attr *attr)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\n> +\tswitch (attr->id) {\n> +\tcase SWITCHDEV_ATTR_ID_PORT_PARENT_ID:\n> +\t\tattr->u.ppid.id_len = 1;\n> +\t\tattr->u.ppid.id[0] = port_priv->ethsw_data->dev_id;\n> +\t\tbreak;\n> +\tcase SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:\n> +\t\tattr->u.brport_flags =\n> +\t\t\t(port_priv->ethsw_data->learning ? BR_LEARNING : 0) |\n> +\t\t\t(port_priv->flood ? BR_FLOOD : 0);\n> +\t\tbreak;\n> +\tcase SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:\n> +\t\tattr->u.brport_flags_support = BR_LEARNING | BR_FLOOD;\n> +\t\tbreak;\n> +\tdefault:\n> +\t\treturn -EOPNOTSUPP;\n> +\t}\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int port_attr_stp_state_set(struct net_device *netdev,\n> +\t\t\t\t   struct switchdev_trans *trans,\n> +\t\t\t\t   u8 state)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\n> +\tif (switchdev_trans_ph_prepare(trans))\n> +\t\treturn 0;\n> +\n> +\treturn ethsw_port_set_stp_state(port_priv, state);\n> +}\n> +\n> +static int port_attr_br_flags_set(struct net_device *netdev,\n> +\t\t\t\t  struct switchdev_trans *trans,\n> +\t\t\t\t  unsigned long flags)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\tint err = 0;\n> +\n> +\tif (switchdev_trans_ph_prepare(trans))\n> +\t\treturn 0;\n> +\n> +\t/* Learning is enabled per switch */\n> +\terr = ethsw_set_learning(port_priv->ethsw_data, flags & BR_LEARNING);\n> +\tif (err)\n> +\t\tgoto exit;\n> +\n> +\terr = ethsw_port_set_flood(port_priv, flags & BR_FLOOD);\n> +\n> +exit:\n> +\treturn err;\n> +}\n> +\n> +static int swdev_port_attr_set(struct net_device *netdev,\n> +\t\t\t       const struct switchdev_attr *attr,\n> +\t\t\t       struct switchdev_trans *trans)\n> +{\n> +\tint err = 0;\n> +\n> +\tswitch (attr->id) {\n> +\tcase SWITCHDEV_ATTR_ID_PORT_STP_STATE:\n> +\t\terr = port_attr_stp_state_set(netdev, trans,\n> +\t\t\t\t\t      attr->u.stp_state);\n> +\t\tbreak;\n> +\tcase SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:\n> +\t\terr = port_attr_br_flags_set(netdev, trans,\n> +\t\t\t\t\t     attr->u.brport_flags);\n> +\t\tbreak;\n> +\tcase SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:\n> +\t\t/* VLANs are supported by default  */\n> +\t\tbreak;\n> +\tdefault:\n> +\t\terr = -EOPNOTSUPP;\n> +\t\tbreak;\n> +\t}\n> +\n> +\treturn err;\n> +}\n> +\n> +static int port_vlans_add(struct net_device *netdev,\n> +\t\t\t  const struct switchdev_obj_port_vlan *vlan,\n> +\t\t\t  struct switchdev_trans *trans)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\tint vid, err;\n> +\n> +\tif (switchdev_trans_ph_prepare(trans))\n> +\t\treturn 0;\n> +\n> +\tfor (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {\n> +\t\tif (!port_priv->ethsw_data->vlans[vid]) {\n> +\t\t\t/* this is a new VLAN */\n> +\t\t\terr = ethsw_add_vlan(port_priv->ethsw_data, vid);\n> +\t\t\tif (err)\n> +\t\t\t\treturn err;\n> +\n> +\t\t\tport_priv->ethsw_data->vlans[vid] |= ETHSW_VLAN_GLOBAL;\n> +\t\t}\n> +\t\terr = ethsw_port_add_vlan(port_priv, vid, vlan->flags);\n> +\t\tif (err)\n> +\t\t\tbreak;\n> +\t}\n> +\n> +\treturn err;\n> +}\n> +\n> +static int port_lookup_address(struct net_device *netdev, int is_uc,\n> +\t\t\t       const unsigned char *addr)\n> +{\n> +\tstruct netdev_hw_addr_list *list = (is_uc) ? &netdev->uc : &netdev->mc;\n> +\tstruct netdev_hw_addr *ha;\n> +\n> +\tnetif_addr_lock_bh(netdev);\n> +\tlist_for_each_entry(ha, &list->list, list) {\n> +\t\tif (ether_addr_equal(ha->addr, addr)) {\n> +\t\t\tnetif_addr_unlock_bh(netdev);\n> +\t\t\treturn 1;\n> +\t\t}\n> +\t}\n> +\tnetif_addr_unlock_bh(netdev);\n> +\treturn 0;\n> +}\n> +\n> +static int port_mdb_add(struct net_device *netdev,\n> +\t\t\tconst struct switchdev_obj_port_mdb *mdb,\n> +\t\t\tstruct switchdev_trans *trans)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\tint err;\n> +\n> +\tif (switchdev_trans_ph_prepare(trans))\n> +\t\treturn 0;\n> +\n> +\t/* Check if address is already set on this port */\n> +\tif (port_lookup_address(netdev, 0, mdb->addr))\n> +\t\treturn -EEXIST;\n> +\n> +\terr = ethsw_port_fdb_add_mc(port_priv, mdb->addr);\n> +\tif (err)\n> +\t\treturn err;\n> +\n> +\terr = dev_mc_add(netdev, mdb->addr);\n> +\tif (err)\n> +\t\tnetdev_err(netdev, \"dev_mc_add err %d\\n\", err);\n\nIn the error case, shouldn't there be a \"ethsw_port_fdb_del_mc\" ?\n\n> +\n> +\treturn err;\n> +}\n> +\n> +static int swdev_port_obj_add(struct net_device *netdev,\n> +\t\t\t      const struct switchdev_obj *obj,\n> +\t\t\t      struct switchdev_trans *trans)\n> +{\n> +\tint err;\n> +\n> +\tswitch (obj->id) {\n> +\tcase SWITCHDEV_OBJ_ID_PORT_VLAN:\n> +\t\terr = port_vlans_add(netdev,\n> +\t\t\t\t     SWITCHDEV_OBJ_PORT_VLAN(obj),\n> +\t\t\t\t     trans);\n> +\t\tbreak;\n> +\tcase SWITCHDEV_OBJ_ID_PORT_MDB:\n> +\t\terr = port_mdb_add(netdev,\n> +\t\t\t\t   SWITCHDEV_OBJ_PORT_MDB(obj),\n> +\t\t\t\t   trans);\n> +\t\tbreak;\n> +\tdefault:\n> +\t\terr = -EOPNOTSUPP;\n> +\t\tbreak;\n> +\t}\n> +\n> +\treturn err;\n> +}\n> +\n> +static int ethsw_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid)\n> +{\n> +\tstruct ethsw_core *ethsw = port_priv->ethsw_data;\n> +\tstruct net_device *netdev = port_priv->netdev;\n> +\tstruct dpsw_vlan_if_cfg vcfg;\n> +\tint i, err, err2;\n> +\tbool is_oper;\n> +\n> +\tif (!port_priv->vlans[vid])\n> +\t\treturn -ENOENT;\n> +\n> +\tif (port_priv->vlans[vid] & ETHSW_VLAN_PVID) {\n> +\t\tstruct dpsw_tci_cfg tci_cfg = { 0 };\n> +\t\t/* Interface needs to be down to change PVID */\n> +\t\tis_oper = netif_oper_up(netdev);\n> +\n> +\t\tif (is_oper) {\n> +\t\t\terr = dpsw_if_disable(ethsw->mc_io, 0,\n> +\t\t\t\t\t      ethsw->dpsw_handle,\n> +\t\t\t\t\t      port_priv->idx);\n> +\t\t\tif (err) {\n> +\t\t\t\tnetdev_err(netdev, \"dpsw_if_disable err %d\\n\",\n> +\t\t\t\t\t   err);\n> +\t\t\t\tgoto exit_err;\n> +\t\t\t}\n> +\t\t}\n> +\n> +\t\terr = dpsw_if_set_tci(ethsw->mc_io, 0,\n> +\t\t\t\t      ethsw->dpsw_handle,\n> +\t\t\t\t      port_priv->idx, &tci_cfg);\n> +\t\tif (!err) {\n> +\t\t\tport_priv->vlans[vid] &= ~ETHSW_VLAN_PVID;\n> +\t\t\tport_priv->pvid = 0;\n> +\t\t} else {\n> +\t\t\tnetdev_err(netdev, \"dpsw_if_set_tci err %d\\n\", err);\n> +\t\t}\n> +\n> +\t\tif (is_oper) {\n> +\t\t\terr2 = dpsw_if_enable(ethsw->mc_io, 0,\n> +\t\t\t\t\t      ethsw->dpsw_handle,\n> +\t\t\t\t\t      port_priv->idx);\n> +\t\t\tif (err2) {\n> +\t\t\t\tnetdev_err(netdev, \"dpsw_if_enable err %d\\n\",\n> +\t\t\t\t\t   err2);\n> +\t\t\t\treturn err2;\n> +\t\t\t}\n> +\t\t}\n> +\n> +\t\tif (err)\n> +\t\t\tgoto exit_err;\n> +\t}\n> +\n> +\tvcfg.num_ifs = 1;\n> +\tvcfg.if_id[0] = port_priv->idx;\n> +\tif (port_priv->vlans[vid] & ETHSW_VLAN_UNTAGGED) {\n> +\t\terr = dpsw_vlan_remove_if_untagged(ethsw->mc_io, 0,\n> +\t\t\t\t\t\t   ethsw->dpsw_handle,\n> +\t\t\t\t\t\t   vid, &vcfg);\n> +\t\tif (err) {\n> +\t\t\tnetdev_err(netdev,\n> +\t\t\t\t   \"dpsw_vlan_remove_if_untagged err %d\\n\",\n> +\t\t\t\t   err);\n> +\t\t}\n> +\t\tport_priv->vlans[vid] &= ~ETHSW_VLAN_UNTAGGED;\n> +\t}\n> +\n> +\tif (port_priv->vlans[vid] & ETHSW_VLAN_MEMBER) {\n> +\t\terr = dpsw_vlan_remove_if(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t\t\t  vid, &vcfg);\n> +\t\tif (err) {\n> +\t\t\tnetdev_err(netdev,\n> +\t\t\t\t   \"dpsw_vlan_remove_if err %d\\n\", err);\n> +\t\t\treturn err;\n> +\t\t}\n> +\t\tport_priv->vlans[vid] &= ~ETHSW_VLAN_MEMBER;\n> +\n> +\t\t/* Delete VLAN from switch if it is no longer configured on\n> +\t\t * any port\n> +\t\t */\n> +\t\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++)\n> +\t\t\tif (ethsw->ports[i]->vlans[vid] & ETHSW_VLAN_MEMBER)\n> +\t\t\t\treturn 0; /* Found a port member in VID */\n> +\n> +\t\tethsw->vlans[vid] &= ~ETHSW_VLAN_GLOBAL;\n> +\n> +\t\terr = ethsw_dellink_switch(ethsw, vid);\n> +\t\tif (err)\n> +\t\t\tgoto exit_err;\n> +\t}\n> +\n> +\treturn 0;\n> +exit_err:\n> +\treturn err;\n> +}\n> +\n> +static int port_vlans_del(struct net_device *netdev,\n> +\t\t\t  const struct switchdev_obj_port_vlan *vlan)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\tint vid, err;\n> +\n> +\tfor (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {\n> +\t\terr = ethsw_port_del_vlan(port_priv, vid);\n> +\t\tif (err)\n> +\t\t\tbreak;\n> +\t}\n> +\n> +\treturn err;\n> +}\n> +\n> +static int port_mdb_del(struct net_device *netdev,\n> +\t\t\tconst struct switchdev_obj_port_mdb *mdb)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\tint err;\n> +\n> +\tif (!port_lookup_address(netdev, 0, mdb->addr))\n> +\t\treturn -ENOENT;\n> +\n> +\terr = ethsw_port_fdb_del_mc(port_priv, mdb->addr);\n> +\tif (err)\n> +\t\treturn err;\n> +\n> +\terr = dev_mc_del(netdev, mdb->addr);\n> +\tif (err) {\n> +\t\tnetdev_err(netdev, \"dev_mc_del err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\treturn err;\n> +}\n> +\n> +static int swdev_port_obj_del(struct net_device *netdev,\n> +\t\t\t      const struct switchdev_obj *obj)\n> +{\n> +\tint err;\n> +\n> +\tswitch (obj->id) {\n> +\tcase SWITCHDEV_OBJ_ID_PORT_VLAN:\n> +\t\terr = port_vlans_del(netdev, SWITCHDEV_OBJ_PORT_VLAN(obj));\n> +\t\tbreak;\n> +\tcase SWITCHDEV_OBJ_ID_PORT_MDB:\n> +\t\terr = port_mdb_del(netdev, SWITCHDEV_OBJ_PORT_MDB(obj));\n> +\t\tbreak;\n> +\tdefault:\n> +\t\terr = -EOPNOTSUPP;\n> +\t\tbreak;\n> +\t}\n> +\treturn err;\n> +}\n> +\n> +static const struct switchdev_ops ethsw_port_switchdev_ops = {\n> +\t.switchdev_port_attr_get\t= swdev_port_attr_get,\n> +\t.switchdev_port_attr_set\t= swdev_port_attr_set,\n> +\t.switchdev_port_obj_add\t\t= swdev_port_obj_add,\n> +\t.switchdev_port_obj_del\t\t= swdev_port_obj_del,\n> +};\n> +\n> +/* For the moment, only flood setting needs to be updated */\n> +static int port_bridge_join(struct net_device *netdev)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\n> +\t/* Enable flooding */\n> +\treturn ethsw_port_set_flood(port_priv, 1);\n> +}\n> +\n> +static int port_bridge_leave(struct net_device *netdev)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> +\n> +\t/* Disable flooding */\n> +\treturn ethsw_port_set_flood(port_priv, 0);\n> +}\n> +\n> +static int port_netdevice_event(struct notifier_block *unused,\n> +\t\t\t\tunsigned long event, void *ptr)\n> +{\n> +\tstruct net_device *netdev = netdev_notifier_info_to_dev(ptr);\n> +\tstruct netdev_notifier_changeupper_info *info = ptr;\n> +\tstruct net_device *upper_dev;\n> +\tint err = 0;\n> +\n> +\tif (netdev->netdev_ops != &ethsw_port_ops)\n> +\t\treturn NOTIFY_DONE;\n> +\n> +\t/* Handle just upper dev link/unlink for the moment */\n> +\tif (event == NETDEV_CHANGEUPPER) {\n> +\t\tupper_dev = info->upper_dev;\n> +\t\tif (netif_is_bridge_master(upper_dev)) {\n> +\t\t\tif (info->linking)\n> +\t\t\t\terr = port_bridge_join(netdev);\n> +\t\t\telse\n> +\t\t\t\terr = port_bridge_leave(netdev);\n> +\t\t}\n> +\t}\n> +\n> +\treturn notifier_from_errno(err);\n> +}\n> +\n> +static struct notifier_block port_nb __read_mostly = {\n> +\t.notifier_call = port_netdevice_event,\n> +};\n> +\n> +struct ethsw_switchdev_event_work {\n> +\tstruct work_struct work;\n> +\tstruct switchdev_notifier_fdb_info fdb_info;\n> +\tstruct net_device *dev;\n> +\tunsigned long event;\n> +};\n> +\n> +static void ethsw_switchdev_event_work(struct work_struct *work)\n> +{\n> +\tstruct ethsw_switchdev_event_work *switchdev_work =\n> +\t\tcontainer_of(work, struct ethsw_switchdev_event_work, work);\n> +\tstruct net_device *dev = switchdev_work->dev;\n> +\tstruct switchdev_notifier_fdb_info *fdb_info;\n> +\tstruct ethsw_port_priv *port_priv;\n> +\n> +\trtnl_lock();\n> +\tport_priv = netdev_priv(dev);\n> +\tfdb_info = &switchdev_work->fdb_info;\n> +\n> +\tswitch (switchdev_work->event) {\n> +\tcase SWITCHDEV_FDB_ADD_TO_DEVICE:\n> +\t\tethsw_port_fdb_add_uc(netdev_priv(dev), fdb_info->addr);\n> +\t\tbreak;\n> +\tcase SWITCHDEV_FDB_DEL_TO_DEVICE:\n> +\t\tethsw_port_fdb_del_uc(netdev_priv(dev), fdb_info->addr);\n> +\t\tbreak;\n> +\t}\n> +\n> +\trtnl_unlock();\n> +\tkfree(switchdev_work->fdb_info.addr);\n> +\tkfree(switchdev_work);\n> +\tdev_put(dev);\n> +}\n> +\n> +/* Called under rcu_read_lock() */\n> +static int port_switchdev_event(struct notifier_block *unused,\n> +\t\t\t\tunsigned long event, void *ptr)\n> +{\n> +\tstruct net_device *dev = switchdev_notifier_info_to_dev(ptr);\n> +\tstruct ethsw_switchdev_event_work *switchdev_work;\n> +\tstruct switchdev_notifier_fdb_info *fdb_info = ptr;\n> +\n> +\tswitchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);\n> +\tif (!switchdev_work)\n> +\t\treturn NOTIFY_BAD;\n> +\n> +\tINIT_WORK(&switchdev_work->work, ethsw_switchdev_event_work);\n> +\tswitchdev_work->dev = dev;\n> +\tswitchdev_work->event = event;\n> +\n> +\tswitch (event) {\n> +\tcase SWITCHDEV_FDB_ADD_TO_DEVICE:\n> +\tcase SWITCHDEV_FDB_DEL_TO_DEVICE:\n> +\t\tmemcpy(&switchdev_work->fdb_info, ptr,\n> +\t\t       sizeof(switchdev_work->fdb_info));\n> +\t\tswitchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);\n> +\t\tif (!switchdev_work->fdb_info.addr)\n> +\t\t\tgoto err_addr_alloc;\n> +\n> +\t\tether_addr_copy((u8 *)switchdev_work->fdb_info.addr,\n> +\t\t\t\tfdb_info->addr);\n> +\n> +\t\t/* Take a reference on the device to avoid being freed. */\n> +\t\tdev_hold(dev);\n> +\t\tbreak;\n> +\tdefault:\n> +\t\treturn NOTIFY_DONE;\n> +\t}\n> +\n> +\tqueue_work(ethsw_owq, &switchdev_work->work);\n> +\n> +\treturn NOTIFY_DONE;\n> +\n> +err_addr_alloc:\n> +\tkfree(switchdev_work);\n> +\treturn NOTIFY_BAD;\n> +}\n> +\n> +static struct notifier_block port_switchdev_nb = {\n> +\t.notifier_call = port_switchdev_event,\n> +};\n> +\n> +static int ethsw_register_notifier(struct device *dev)\n> +{\n> +\tint err;\n> +\n> +\terr = register_netdevice_notifier(&port_nb);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"Failed to register netdev notifier\\n\");\n> +\t\treturn err;\n> +\t}\n> +\n> +\terr = register_switchdev_notifier(&port_switchdev_nb);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"Failed to register switchdev notifier\\n\");\n> +\t\tgoto err_switchdev_nb;\n> +\t}\n> +\n> +\treturn 0;\n> +\n> +err_switchdev_nb:\n> +\tunregister_netdevice_notifier(&port_nb);\n> +\treturn err;\n> +}\n> +\n> +static int ethsw_open(struct ethsw_core\t*ethsw)\n\nMinor formatting error, tab in function signature - see following function as well.\n\n> +{\n> +\tstruct ethsw_port_priv *port_priv = NULL;\n> +\tint i, err;\n> +\n> +\terr = dpsw_enable(ethsw->mc_io, 0, ethsw->dpsw_handle);\n> +\tif (err) {\n> +\t\tdev_err(ethsw->dev, \"dpsw_enable err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> +\t\tport_priv = ethsw->ports[i];\n> +\t\terr = dev_open(port_priv->netdev);\n> +\t\tif (err) {\n> +\t\t\tnetdev_err(port_priv->netdev, \"dev_open err %d\\n\", err);\n> +\t\t\treturn err;\n> +\t\t}\n> +\t}\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int ethsw_stop(struct ethsw_core\t*ethsw)\n> +{\n> +\tstruct ethsw_port_priv *port_priv = NULL;\n> +\tint i, err;\n> +\n> +\tdestroy_workqueue(ethsw_owq);\n\nIf workqueue is destroyed here, shouldn't it be alloc'd in ethsw_open?\n\n> +\n> +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> +\t\tport_priv = ethsw->ports[i];\n> +\t\tdev_close(port_priv->netdev);\n> +\t}\n> +\n> +\terr = dpsw_disable(ethsw->mc_io, 0, ethsw->dpsw_handle);\n> +\tif (err) {\n> +\t\tdev_err(ethsw->dev, \"dpsw_disable err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int ethsw_init(struct fsl_mc_device *sw_dev)\n> +{\n> +\tstruct device *dev = &sw_dev->dev;\n> +\tstruct ethsw_core *ethsw = dev_get_drvdata(dev);\n> +\tu16 version_major, version_minor, i;\n> +\tstruct dpsw_stp_cfg stp_cfg;\n> +\tint err;\n> +\n> +\tethsw->dev_id = sw_dev->obj_desc.id;\n> +\n> +\terr = dpsw_open(ethsw->mc_io, 0, ethsw->dev_id, &ethsw->dpsw_handle);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"dpsw_open err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\terr = dpsw_get_attributes(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t\t  &ethsw->sw_attr);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"dpsw_get_attributes err %d\\n\", err);\n> +\t\tgoto err_close;\n> +\t}\n> +\n> +\terr = dpsw_get_api_version(ethsw->mc_io, 0,\n> +\t\t\t\t   &version_major,\n> +\t\t\t\t   &version_minor);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"dpsw_get_api_version err %d\\n\", err);\n> +\t\tgoto err_close;\n> +\t}\n> +\n> +\t/* Minimum supported DPSW version check */\n> +\tif (version_major < DPSW_MIN_VER_MAJOR ||\n> +\t    (version_major == DPSW_MIN_VER_MAJOR &&\n> +\t     version_minor < DPSW_MIN_VER_MINOR)) {\n> +\t\tdev_err(dev, \"DPSW version %d:%d not supported. Use %d.%d or\n> greater.\\n\",\n> +\t\t\tversion_major,\n> +\t\t\tversion_minor,\n> +\t\t\tDPSW_MIN_VER_MAJOR, DPSW_MIN_VER_MINOR);\n> +\t\terr = -ENOTSUPP;\n> +\t\tgoto err_close;\n> +\t}\n> +\n> +\terr = dpsw_reset(ethsw->mc_io, 0, ethsw->dpsw_handle);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"dpsw_reset err %d\\n\", err);\n> +\t\tgoto err_close;\n> +\t}\n> +\n> +\terr = dpsw_fdb_set_learning_mode(ethsw->mc_io, 0, ethsw->dpsw_handle, 0,\n> +\t\t\t\t\t DPSW_FDB_LEARNING_MODE_HW);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"dpsw_fdb_set_learning_mode err %d\\n\", err);\n> +\t\tgoto err_close;\n> +\t}\n> +\n> +\tstp_cfg.vlan_id = DEFAULT_VLAN_ID;\n> +\tstp_cfg.state = DPSW_STP_STATE_FORWARDING;\n> +\n> +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> +\t\terr = dpsw_if_set_stp(ethsw->mc_io, 0, ethsw->dpsw_handle, i,\n> +\t\t\t\t      &stp_cfg);\n> +\t\tif (err) {\n> +\t\t\tdev_err(dev, \"dpsw_if_set_stp err %d for port %d\\n\",\n> +\t\t\t\terr, i);\n> +\t\t\tgoto err_close;\n> +\t\t}\n> +\n> +\t\terr = dpsw_if_set_broadcast(ethsw->mc_io, 0,\n> +\t\t\t\t\t    ethsw->dpsw_handle, i, 1);\n> +\t\tif (err) {\n> +\t\t\tdev_err(dev,\n> +\t\t\t\t\"dpsw_if_set_broadcast err %d for port %d\\n\",\n> +\t\t\t\terr, i);\n> +\t\t\tgoto err_close;\n> +\t\t}\n> +\t}\n> +\n> +\tethsw_owq = alloc_ordered_workqueue(\"%s_ordered\", WQ_MEM_RECLAIM,\n> +\t\t\t\t\t    \"ethsw\");\n> +\tif (!ethsw_owq) {\n> +\t\terr = -ENOMEM;\n> +\t\tgoto err_close;\n> +\t}\n> +\n> +\terr = ethsw_register_notifier(dev);\n> +\tif (err)\n> +\t\tgoto err_destroy_ordered_workqueue;\n> +\n> +\treturn 0;\n> +\n> +err_destroy_ordered_workqueue:\n> +\tdestroy_workqueue(ethsw_owq);\n> +\n> +err_close:\n> +\tdpsw_close(ethsw->mc_io, 0, ethsw->dpsw_handle);\n> +\treturn err;\n> +}\n> +\n> +static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port)\n> +{\n> +\tconst char def_mcast[ETH_ALEN] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0x01};\n> +\tstruct net_device *netdev = port_priv->netdev;\n> +\tstruct ethsw_core *ethsw = port_priv->ethsw_data;\n> +\tstruct dpsw_tci_cfg tci_cfg = {0};\n> +\tstruct dpsw_vlan_if_cfg vcfg;\n> +\tint err;\n> +\n> +\t/* Switch starts with all ports configured to VLAN 1. Need to\n> +\t * remove this setting to allow configuration at bridge join\n> +\t */\n> +\tvcfg.num_ifs = 1;\n> +\tvcfg.if_id[0] = port_priv->idx;\n> +\n> +\terr = dpsw_vlan_remove_if_untagged(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t\t\t   DEFAULT_VLAN_ID, &vcfg);\n> +\tif (err) {\n> +\t\tnetdev_err(netdev, \"dpsw_vlan_remove_if_untagged err %d\\n\",\n> +\t\t\t   err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\terr = dpsw_if_set_tci(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t      port_priv->idx, &tci_cfg);\n> +\tif (err) {\n> +\t\tnetdev_err(netdev, \"dpsw_if_set_tci err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\terr = dpsw_vlan_remove_if(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> +\t\t\t\t  DEFAULT_VLAN_ID, &vcfg);\n> +\tif (err) {\n> +\t\tnetdev_err(netdev, \"dpsw_vlan_remove_if err %d\\n\", err);\n> +\t\treturn err;\n> +\t}\n> +\n> +\terr = ethsw_port_fdb_add_mc(port_priv, def_mcast);\n> +\n> +\treturn err;\n> +}\n> +\n> +static void ethsw_takedown(struct fsl_mc_device *sw_dev)\n> +{\n> +\tstruct device *dev = &sw_dev->dev;\n> +\tstruct ethsw_core *ethsw = dev_get_drvdata(dev);\n> +\tint err;\n> +\n> +\terr = unregister_switchdev_notifier(&port_switchdev_nb);\n> +\tif (err)\n> +\t\tdev_err(dev,\n> +\t\t\t\"Failed to unregister switchdev notifier (%d)\\n\", err);\n> +\n> +\terr = unregister_netdevice_notifier(&port_nb);\n> +\tif (err)\n> +\t\tdev_err(dev,\n> +\t\t\t\"Failed to unregister netdev notifier (%d)\\n\", err);\n\nAbove 2 can be grouped into ethsw_unregister_notifier.\n\n> +\n> +\terr = dpsw_close(ethsw->mc_io, 0, ethsw->dpsw_handle);\n> +\tif (err)\n> +\t\tdev_warn(dev, \"dpsw_close err %d\\n\", err);\n> +}\n> +\n> +static int ethsw_remove(struct fsl_mc_device *sw_dev)\n> +{\n> +\tstruct ethsw_port_priv *port_priv;\n> +\tstruct ethsw_core *ethsw;\n> +\tstruct device *dev;\n> +\tint i;\n> +\n> +\tdev = &sw_dev->dev;\n> +\tethsw = dev_get_drvdata(dev);\n> +\n> +\tethsw_teardown_irqs(sw_dev);\n> +\n> +\trtnl_lock();\n> +\tethsw_stop(ethsw);\n> +\trtnl_unlock();\n> +\n> +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> +\t\tport_priv = ethsw->ports[i];\n> +\t\tunregister_netdev(port_priv->netdev);\n> +\t\tfree_netdev(port_priv->netdev);\n> +\t}\n> +\tkfree(ethsw->ports);\n> +\n> +\tethsw_takedown(sw_dev);\n> +\tfsl_mc_portal_free(ethsw->mc_io);\n> +\n> +\tkfree(ethsw);\n> +\n> +\tdev_set_drvdata(dev, NULL);\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int ethsw_probe_port(struct ethsw_core *ethsw, u16 port_idx)\n> +{\n> +\tstruct ethsw_port_priv *port_priv;\n> +\tstruct device *dev = ethsw->dev;\n> +\tstruct net_device *port_netdev;\n> +\tint err;\n> +\n> +\tport_netdev = alloc_etherdev(sizeof(struct ethsw_port_priv));\n> +\tif (!port_netdev) {\n> +\t\tdev_err(dev, \"alloc_etherdev error\\n\");\n> +\t\treturn -ENOMEM;\n> +\t}\n> +\n> +\tport_priv = netdev_priv(port_netdev);\n> +\tport_priv->netdev = port_netdev;\n> +\tport_priv->ethsw_data = ethsw;\n> +\n> +\tport_priv->idx = port_idx;\n> +\tport_priv->stp_state = BR_STATE_FORWARDING;\n> +\n> +\t/* Flooding is implicitly enabled */\n> +\tport_priv->flood = true;\n> +\n> +\tSET_NETDEV_DEV(port_netdev, dev);\n> +\tport_netdev->netdev_ops = &ethsw_port_ops;\n> +\tport_netdev->switchdev_ops = &ethsw_port_switchdev_ops;\n> +\n> +\t/* Set MTU limits */\n> +\tport_netdev->min_mtu = ETH_MIN_MTU;\n> +\tport_netdev->max_mtu = ETHSW_MAX_FRAME_LENGTH;\n> +\n> +\terr = register_netdev(port_netdev);\n> +\tif (err < 0) {\n> +\t\tdev_err(dev, \"register_netdev error %d\\n\", err);\n> +\t\t\tfree_netdev(port_netdev);\n> +\t\t\treturn err;\n> +\t\t}\n> +\n> +\tethsw->ports[port_idx] = port_priv;\n> +\n> +\treturn ethsw_port_init(port_priv, port_idx);\n> +}\n> +\n> +static int ethsw_probe(struct fsl_mc_device *sw_dev)\n> +{\n> +\tstruct device *dev = &sw_dev->dev;\n> +\tstruct ethsw_core *ethsw;\n> +\tint err;\n> +\tu16 i, j;\n> +\n> +\t/* Allocate switch core*/\n> +\tethsw = kzalloc(sizeof(*ethsw), GFP_KERNEL);\n> +\n> +\tif (!ethsw)\n> +\t\treturn -ENOMEM;\n> +\n> +\tethsw->dev = dev;\n> +\tdev_set_drvdata(dev, ethsw);\n> +\n> +\terr = fsl_mc_portal_allocate(sw_dev, 0, &ethsw->mc_io);\n> +\tif (err) {\n> +\t\tdev_err(dev, \"fsl_mc_portal_allocate err %d\\n\", err);\n> +\t\tgoto err_free_drvdata;\n> +\t}\n> +\n> +\terr = ethsw_init(sw_dev);\n> +\tif (err)\n> +\t\tgoto err_free_cmdport;\n> +\n> +\t/* DEFAULT_VLAN_ID is implicitly configured on the switch */\n> +\tethsw->vlans[DEFAULT_VLAN_ID] = ETHSW_VLAN_MEMBER;\n> +\n> +\t/* Learning is implicitly enabled */\n> +\tethsw->learning = true;\n> +\n> +\tethsw->ports = kcalloc(ethsw->sw_attr.num_ifs, sizeof(*ethsw->ports),\n> +\t\t\t       GFP_KERNEL);\n> +\tif (!(ethsw->ports)) {\n> +\t\terr = -ENOMEM;\n> +\t\tgoto err_takedown;\n> +\t}\n> +\n> +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> +\t\terr = ethsw_probe_port(ethsw, i);\n> +\t\tif (err) {\n> +\t\t\t/* Cleanup previous ports only */\n> +\t\t\tfor (j = 0; j < i; j++) {\n\nI think you can go with\nfor (i--; i >= 0; i--)\n\nor better yet:\ngoto err_free_ports\nand refactor err_free_ports to look like:\nfor (i--; i >= 0; i--) {\n...\n}\n\nBest regards,\nBogdan P.\n\n> +\t\t\t\tunregister_netdev(ethsw->ports[j]->netdev);\n> +\t\t\t\tfree_netdev(ethsw->ports[j]->netdev);\n> +\t\t\t}\n> +\t\t\tgoto err_takedown;\n> +\t\t}\n> +\t}\n> +\n> +\t/* Switch starts up enabled */\n> +\trtnl_lock();\n> +\terr = ethsw_open(ethsw);\n> +\trtnl_unlock();\n> +\tif (err)\n> +\t\tgoto err_free_ports;\n> +\n> +\t/* Setup IRQs */\n> +\terr = ethsw_setup_irqs(sw_dev);\n> +\tif (err)\n> +\t\tgoto err_stop;\n> +\n> +\tdev_info(dev, \"probed %d port switch\\n\", ethsw->sw_attr.num_ifs);\n> +\treturn 0;\n> +\n> +err_stop:\n> +\trtnl_lock();\n> +\tethsw_stop(ethsw);\n> +\trtnl_unlock();\n> +\n> +err_free_ports:\n> +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> +\t\tunregister_netdev(ethsw->ports[i]->netdev);\n> +\t\tfree_netdev(ethsw->ports[i]->netdev);\n> +\t}\n> +\tkfree(ethsw->ports);\n> +\n> +err_takedown:\n> +\tethsw_takedown(sw_dev);\n> +\n> +err_free_cmdport:\n> +\tfsl_mc_portal_free(ethsw->mc_io);\n> +\n> +err_free_drvdata:\n> +\tkfree(ethsw);\n> +\tdev_set_drvdata(dev, NULL);\n> +\n> +\treturn err;\n> +}\n> +\n> +static const struct fsl_mc_device_id ethsw_match_id_table[] = {\n> +\t{\n> +\t\t.vendor = FSL_MC_VENDOR_FREESCALE,\n> +\t\t.obj_type = \"dpsw\",\n> +\t},\n> +\t{ .vendor = 0x0 }\n> +};\n> +MODULE_DEVICE_TABLE(fslmc, ethsw_match_id_table);\n> +\n> +static struct fsl_mc_driver eth_sw_drv = {\n> +\t.driver = {\n> +\t\t.name = KBUILD_MODNAME,\n> +\t\t.owner = THIS_MODULE,\n> +\t},\n> +\t.probe = ethsw_probe,\n> +\t.remove = ethsw_remove,\n> +\t.match_id_table = ethsw_match_id_table\n> +};\n> +\n> +module_fsl_mc_driver(eth_sw_drv);\n> +\n> +MODULE_LICENSE(\"Dual BSD/GPL\");\n> +MODULE_DESCRIPTION(\"DPAA2 Ethernet Switch Driver\");\n> diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h b/drivers/staging/fsl-\n> dpaa2/ethsw/ethsw.h\n> new file mode 100644\n> index 0000000..8c1d645\n> --- /dev/null\n> +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h\n> @@ -0,0 +1,88 @@\n> +/* Copyright 2014-2017 Freescale Semiconductor Inc.\n> + * Copyright 2017 NXP\n> + *\n> + * Redistribution and use in source and binary forms, with or without\n> + * modification, are permitted provided that the following conditions are met:\n> + *     * Redistributions of source code must retain the above copyright\n> + *\t notice, this list of conditions and the following disclaimer.\n> + *     * Redistributions in binary form must reproduce the above copyright\n> + *\t notice, this list of conditions and the following disclaimer in the\n> + *\t documentation and/or other materials provided with the distribution.\n> + *     * Neither the name of the above-listed copyright holders nor the\n> + *\t names of any contributors may be used to endorse or promote products\n> + *\t derived from this software without specific prior written permission.\n> + *\n> + *\n> + * ALTERNATIVELY, this software may be distributed under the terms of the\n> + * GNU General Public License (\"GPL\") as published by the Free Software\n> + * Foundation, either version 2 of that License or (at your option) any\n> + * later version.\n> + *\n> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE\n> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n> + * POSSIBILITY OF SUCH DAMAGE.\n> + */\n> +\n> +#ifndef __ETHSW_H\n> +#define __ETHSW_H\n> +\n> +#include <linux/netdevice.h>\n> +#include <linux/etherdevice.h>\n> +#include <linux/rtnetlink.h>\n> +#include <linux/if_vlan.h>\n> +#include <uapi/linux/if_bridge.h>\n> +#include <net/switchdev.h>\n> +#include <linux/if_bridge.h>\n> +\n> +#include \"dpsw.h\"\n> +\n> +/* Number of IRQs supported */\n> +#define DPSW_IRQ_NUM\t2\n> +\n> +#define ETHSW_VLAN_MEMBER\t1\n> +#define ETHSW_VLAN_UNTAGGED\t2\n> +#define ETHSW_VLAN_PVID\t\t4\n> +#define ETHSW_VLAN_GLOBAL\t8\n> +\n> +/* Maximum Frame Length supported by HW (currently 10k) */\n> +#define DPAA2_MFL\t\t(10 * 1024)\n> +#define ETHSW_MAX_FRAME_LENGTH\t(DPAA2_MFL - VLAN_ETH_HLEN - ETH_FCS_LEN)\n> +#define ETHSW_L2_MAX_FRM(mtu)\t((mtu) + VLAN_ETH_HLEN + ETH_FCS_LEN)\n> +\n> +struct ethsw_core;\n> +\n> +/* Per port private data */\n> +struct ethsw_port_priv {\n> +\tstruct net_device\t*netdev;\n> +\tu16\t\t\tidx;\n> +\tstruct ethsw_core\t*ethsw_data;\n> +\tu8\t\t\tlink_state;\n> +\tu8\t\t\tstp_state;\n> +\tbool\t\t\tflood;\n> +\n> +\tu8\t\t\tvlans[VLAN_VID_MASK + 1];\n> +\tu16\t\t\tpvid;\n> +};\n> +\n> +/* Switch data */\n> +struct ethsw_core {\n> +\tstruct device\t\t\t*dev;\n> +\tstruct fsl_mc_io\t\t*mc_io;\n> +\tu16\t\t\t\tdpsw_handle;\n> +\tstruct dpsw_attr\t\tsw_attr;\n> +\tint\t\t\t\tdev_id;\n> +\tstruct ethsw_port_priv\t\t**ports;\n> +\n> +\tu8\t\t\t\tvlans[VLAN_VID_MASK + 1];\n> +\tbool\t\t\t\tlearning;\n> +};\n> +\n> +#endif\t/* __ETHSW_H */\n> --\n> 1.9.1","headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"sgkRlKnN\";\n\tdkim-atps=neutral","spf=none (sender IP is )\n\tsmtp.mailfrom=bogdan.purcareata@nxp.com; "],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3y3Xdj3X14z9t4g\n\tfor <patchwork-incoming@ozlabs.org>;\n\tFri, 29 Sep 2017 23:36:25 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752067AbdI2NgO (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tFri, 29 Sep 2017 09:36:14 -0400","from mail-ve1eur01on0082.outbound.protection.outlook.com\n\t([104.47.1.82]:53923\n\t\"EHLO EUR01-VE1-obe.outbound.protection.outlook.com\"\n\trhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP\n\tid S1751805AbdI2NgL (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tFri, 29 Sep 2017 09:36:11 -0400","from DB5PR04MB1240.eurprd04.prod.outlook.com (10.162.156.142) by\n\tAM3PR04MB0743.eurprd04.prod.outlook.com (10.160.5.23) with Microsoft\n\tSMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id\n\t15.20.77.7; Fri, 29 Sep 2017 13:36:06 +0000","from DB5PR04MB1240.eurprd04.prod.outlook.com\n\t([fe80::fcba:d81f:2ae1:f86c]) by\n\tDB5PR04MB1240.eurprd04.prod.outlook.com\n\t([fe80::fcba:d81f:2ae1:f86c%14]) with mapi id 15.20.0077.016;\n\tFri, 29 Sep 2017 13:36:04 +0000"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version;\n\tbh=s2aGlpVuY+HClF3uXX10FBtOr00bclWHtIdKRshR5Ag=;\n\tb=sgkRlKnNKQj4nLZx7lGseWlJsLQkEmZXIv2nmtCP5A3iKZP2no70389ABQbP7EM/c/iYGHC2Yjb7/6n024Ph7q5lYj8Js5G32kvT9CBn8vCXJmJWOoyTtcVdX1YZQ2HwdHCk9ejMkFZ4Bl9ZZcAld98fFHpvyO9q7X59XfYOVZs=","From":"Bogdan Purcareata <bogdan.purcareata@nxp.com>","To":"Razvan Stefanescu <razvan.stefanescu@nxp.com>,\n\t\"gregkh@linuxfoundation.org\" <gregkh@linuxfoundation.org>","CC":"\"devel@driverdev.osuosl.org\" <devel@driverdev.osuosl.org>,\n\t\"linux-kernel@vger.kernel.org\" <linux-kernel@vger.kernel.org>,\n\t\"netdev@vger.kernel.org\" <netdev@vger.kernel.org>,\n\t\"agraf@suse.de\" <agraf@suse.de>, \"arnd@arndb.de\" <arnd@arndb.de>,\n\tAlexandru Marginean <alexandru.marginean@nxp.com>,\n\tRuxandra Ioana Radulescu <ruxandra.radulescu@nxp.com>,\n\tLaurentiu Tudor <laurentiu.tudor@nxp.com>,\n\t\"stuyoder@gmail.com\" <stuyoder@gmail.com>","Subject":"RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale DPAA2\n\tEthernet Switch driver","Thread-Topic":"[RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale\n\tDPAA2 Ethernet Switch driver","Thread-Index":"AQHTMUVIURzq0Mu98kOnNvl46Hnvg6LL6+eA","Date":"Fri, 29 Sep 2017 13:36:04 +0000","Message-ID":"<DB5PR04MB12400025DF190790B4792B50EA7E0@DB5PR04MB1240.eurprd04.prod.outlook.com>","References":"<1505825158-8192-1-git-send-email-razvan.stefanescu@nxp.com>\n\t<1505825158-8192-3-git-send-email-razvan.stefanescu@nxp.com>","In-Reply-To":"<1505825158-8192-3-git-send-email-razvan.stefanescu@nxp.com>","Accept-Language":"en-US","Content-Language":"en-US","X-MS-Has-Attach":"","X-MS-TNEF-Correlator":"","authentication-results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"sgkRlKnN\";\n\tdkim-atps=neutral","spf=none (sender IP is )\n\tsmtp.mailfrom=bogdan.purcareata@nxp.com; "],"x-originating-ip":"[192.88.146.1]","x-ms-publictraffictype":"Email","x-microsoft-exchange-diagnostics":"1; AM3PR04MB0743;\n\t6:P2PCUdIEWCw4scEGMj4guqhuW1DOBE4uDB47ngA/6ddDvpfHU+VgT+2peXS8+QRNt7nkMB1yPWhGUnrajjNU0Ybayi3CW2v0JPiskEEyllymEnuptIfQi7wn8P+uu9GFeHEbq1NUrC77bK4y2Xo4nRgrqJ3q1Su3Ll9mxOoiTxjldKKFsOiw8qiak23BXmo1aj1si7A8e+4KM7LT4qJYar59xuAgHk2bnZ+b0aqkecRXGOqPORaxqgZrX5g4QiTADYRhZnY8IV9BPYlazzjGuTznOEcX9WBqy77JdnOy4Si5hTjL8qQoaH7f/Q29W9KTBFAFj88lnYQ92Kw3Zyvnmg==;\n\t5:1DPVdOWD9jSgHeagWnPT3LJXoHfUL7d7+x3SxD88pmm7oqoJ1U0AwnB29efKVyDUKwP7lqmyj7akH73MUqGDHDBRthu/pvgSz+7oxgsrwwGtbqxS/g5uG6l5y8rOgWaFXVXNIfrwWVOlmUlSIEOSpg==;\n\t24:JM+efKYfdaKq9q0pUQK1dolrrGR1sAKQnC7wvW2eB12ioPQH7AYnr4/Rz8hzmsphZDgFuImkzq7jCvHhmafYVVnPsHCAIAWK+Rqz5KCX9YI=;\n\t7:tta6hPR/f2z44VXGA47mWbVZWddRBNjhMUOPX9wC521xP0Y513goGuM7wzrVblyCE+U+8tAw4jmoqZkkK9UnlYn4rf1NeJ0mt74nz0m2qSVK8bTfvzcel3Omfkesb4BGuJ4UryK+1bY4JW8lcH87q54T1LZz1UBnIS/pz0lzsfXPkIHQErKue+eJsbUpmhm/QLEQVecKciFoVsHHpZkd/4dWhV3gSkoEUwDjk4Alrz0=","x-ms-exchange-antispam-srfa-diagnostics":"SSOS;SSOR;","x-forefront-antispam-report":"SFV:SKI; SCL:-1; SFV:NSPM;\n\tSFS:(10009020)(6009001)(39860400002)(376002)(346002)(189002)(199003)(51234002)(16200700003)(2906002)(99286003)(110136005)(55016002)(76176999)(66066001)(54356999)(7696004)(25786009)(50986999)(53936002)(53946003)(2501003)(3660700001)(4326008)(3280700002)(6246003)(102836003)(81156014)(3846002)(229853002)(101416001)(316002)(39060400002)(6116002)(33656002)(86362001)(106356001)(2900100001)(105586002)(2950100002)(189998001)(81166006)(97736004)(54906003)(14454004)(5250100002)(9686003)(8936002)(5660300001)(68736007)(305945005)(478600001)(6506006)(74316002)(7736002)(8676002)(6436002)(2004002)(217873001)(559001)(569006);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM3PR04MB0743;\n\tH:DB5PR04MB1240.eurprd04.prod.outlook.com; FPR:; SPF:None;\n\tPTR:InfoNoRecords; MX:1; A:1; LANG:en; ","x-ms-office365-filtering-correlation-id":"3a31ac90-8810-4267-9ad2-08d5073f082a","x-ms-office365-filtering-ht":"Tenant","x-microsoft-antispam":"UriScan:; BCL:0; PCL:0;\n\tRULEID:(22001)(2017030254152)(48565401081)(2017052603199)(201703131423075)(201703031133081)(201702281549075);\n\tSRVR:AM3PR04MB0743; ","x-ms-traffictypediagnostic":"AM3PR04MB0743:","x-exchange-antispam-report-test":"UriScan:(185117386973197);","x-microsoft-antispam-prvs":"<AM3PR04MB0743DC779476254BA11818EEEA7E0@AM3PR04MB0743.eurprd04.prod.outlook.com>","x-exchange-antispam-report-cfa-test":"BCL:0; PCL:0;\n\tRULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(93006095)(93001095)(3002001)(10201501046)(100000703101)(100105400095)(6055026)(6041248)(20161123564025)(20161123555025)(20161123558100)(20161123562025)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);\n\tSRVR:AM3PR04MB0743; BCL:0; PCL:0;\n\tRULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);\n\tSRVR:AM3PR04MB0743; ","x-forefront-prvs":"0445A82F82","received-spf":"None (protection.outlook.com: nxp.com does not designate\n\tpermitted sender hosts)","spamdiagnosticoutput":"1:99","spamdiagnosticmetadata":"NSPM","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"quoted-printable","MIME-Version":"1.0","X-OriginatorOrg":"nxp.com","X-MS-Exchange-CrossTenant-originalarrivaltime":"29 Sep 2017 13:36:04.2887\n\t(UTC)","X-MS-Exchange-CrossTenant-fromentityheader":"Hosted","X-MS-Exchange-CrossTenant-id":"686ea1d3-bc2b-4c6f-a92c-d99c5c301635","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"AM3PR04MB0743","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"}},{"id":1777558,"web_url":"http://patchwork.ozlabs.org/comment/1777558/","msgid":"<AM3PR04MB0743F62497ED0CB445F51524E67E0@AM3PR04MB0743.eurprd04.prod.outlook.com>","list_archive_url":null,"date":"2017-09-29T13:59:18","subject":"RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale DPAA2\n\tEthernet Switch driver","submitter":{"id":72391,"url":"http://patchwork.ozlabs.org/api/people/72391/","name":"Razvan Stefanescu","email":"razvan.stefanescu@nxp.com"},"content":"> -----Original Message-----\n> From: Bogdan Purcareata\n> Sent: Friday, September 29, 2017 16:36\n> To: Razvan Stefanescu <razvan.stefanescu@nxp.com>;\n> gregkh@linuxfoundation.org\n> Cc: devel@driverdev.osuosl.org; linux-kernel@vger.kernel.org;\n> netdev@vger.kernel.org; agraf@suse.de; arnd@arndb.de; Alexandru Marginean\n> <alexandru.marginean@nxp.com>; Ruxandra Ioana Radulescu\n> <ruxandra.radulescu@nxp.com>; Laurentiu Tudor <laurentiu.tudor@nxp.com>;\n> stuyoder@gmail.com\n> Subject: RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale DPAA2\n> Ethernet Switch driver\n> \n> > Introduce the DPAA2 Ethernet Switch driver, which manages Datapath Switch\n> > (DPSW) objects discovered on the MC bus.\n> >\n> > Suggested-by: Alexandru Marginean <alexandru.marginean@nxp.com>\n> > Signed-off-by: Razvan Stefanescu <razvan.stefanescu@nxp.com>\n> > ---\n> >  drivers/staging/fsl-dpaa2/ethsw/Makefile |    2 +-\n> >  drivers/staging/fsl-dpaa2/ethsw/ethsw.c  | 1523\n> ++++++++++++++++++++++++++++++\n> >  drivers/staging/fsl-dpaa2/ethsw/ethsw.h  |   88 ++\n> >  3 files changed, 1612 insertions(+), 1 deletion(-)\n> >  create mode 100644 drivers/staging/fsl-dpaa2/ethsw/ethsw.c\n> >  create mode 100644 drivers/staging/fsl-dpaa2/ethsw/ethsw.h\n> >\n> > diff --git a/drivers/staging/fsl-dpaa2/ethsw/Makefile b/drivers/staging/fsl-\n> > dpaa2/ethsw/Makefile\n> > index db137f7..a6d72d1 100644\n> > --- a/drivers/staging/fsl-dpaa2/ethsw/Makefile\n> > +++ b/drivers/staging/fsl-dpaa2/ethsw/Makefile\n> > @@ -4,4 +4,4 @@\n> >\n> >  obj-$(CONFIG_FSL_DPAA2_ETHSW) += dpaa2-ethsw.o\n> >\n> > -dpaa2-ethsw-objs := dpsw.o\n> > +dpaa2-ethsw-objs := ethsw.o dpsw.o\n> > diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-\n> > dpaa2/ethsw/ethsw.c\n> > new file mode 100644\n> > index 0000000..ae86078\n> > --- /dev/null\n> > +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c\n> > @@ -0,0 +1,1523 @@\n> > +/* Copyright 2014-2016 Freescale Semiconductor Inc.\n> > + * Copyright 2017 NXP\n> > + *\n> > + * Redistribution and use in source and binary forms, with or without\n> > + * modification, are permitted provided that the following conditions are met:\n> > + *     * Redistributions of source code must retain the above copyright\n> > + *\t notice, this list of conditions and the following disclaimer.\n> > + *     * Redistributions in binary form must reproduce the above copyright\n> > + *\t notice, this list of conditions and the following disclaimer in the\n> > + *\t documentation and/or other materials provided with the distribution.\n> > + *     * Neither the name of the above-listed copyright holders nor the\n> > + *\t names of any contributors may be used to endorse or promote products\n> > + *\t derived from this software without specific prior written permission.\n> > + *\n> > + *\n> > + * ALTERNATIVELY, this software may be distributed under the terms of the\n> > + * GNU General Public License (\"GPL\") as published by the Free Software\n> > + * Foundation, either version 2 of that License or (at your option) any\n> > + * later version.\n> > + *\n> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n> CONTRIBUTORS \"AS IS\"\n> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n> LIMITED TO, THE\n> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n> PARTICULAR PURPOSE\n> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR\n> CONTRIBUTORS BE\n> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n> PROCUREMENT OF\n> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n> BUSINESS\n> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n> WHETHER IN\n> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n> OTHERWISE)\n> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n> ADVISED OF THE\n> > + * POSSIBILITY OF SUCH DAMAGE.\n> > + */\n> > +\n> > +#include <linux/module.h>\n> > +\n> > +#include <linux/interrupt.h>\n> > +#include <linux/msi.h>\n> > +#include <linux/kthread.h>\n> > +#include <linux/workqueue.h>\n> > +\n> > +#include \"../../fsl-mc/include/mc.h\"\n> > +\n> > +#include \"ethsw.h\"\n> > +\n> > +static struct workqueue_struct *ethsw_owq;\n> > +\n> > +/* Minimal supported DPSW version */\n> > +#define DPSW_MIN_VER_MAJOR\t\t8\n> > +#define DPSW_MIN_VER_MINOR\t\t0\n> > +\n> > +#define DEFAULT_VLAN_ID\t\t\t1\n> > +\n> > +static int ethsw_add_vlan(struct ethsw_core *ethsw, u16 vid)\n> > +{\n> > +\tint err;\n> > +\n> > +\tstruct dpsw_vlan_cfg\tvcfg = {\n> > +\t\t.fdb_id = 0,\n> > +\t};\n> > +\n> > +\tif (ethsw->vlans[vid]) {\n> > +\t\tdev_err(ethsw->dev, \"VLAN already configured\\n\");\n> > +\t\treturn -EEXIST;\n> > +\t}\n> > +\n> > +\terr = dpsw_vlan_add(ethsw->mc_io, 0,\n> > +\t\t\t    ethsw->dpsw_handle, vid, &vcfg);\n> > +\tif (err) {\n> > +\t\tdev_err(ethsw->dev, \"dpsw_vlan_add err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\tethsw->vlans[vid] = ETHSW_VLAN_MEMBER;/\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int ethsw_port_add_vlan(struct ethsw_port_priv *port_priv,\n> > +\t\t\t       u16 vid, u16 flags)\n> > +{\n> > +\tstruct ethsw_core *ethsw = port_priv->ethsw_data;\n> > +\tstruct net_device *netdev = port_priv->netdev;\n> > +\tstruct dpsw_vlan_if_cfg vcfg;\n> > +\tbool is_oper;\n> > +\tint err, err2;\n> \n> Mild suggestion - s/err2/ret/, just because it sounds better, at least to me (same\n> for similar situations in the rest of the file).\n> \nThank you for your suggestion. I will make the change and send v2.\n> > +\n> > +\tif (port_priv->vlans[vid]) {\n> > +\t\tnetdev_warn(netdev, \"VLAN %d already configured\\n\", vid);\n> > +\t\treturn -EEXIST;\n> > +\t}\n> > +\n> > +\tvcfg.num_ifs = 1;\n> > +\tvcfg.if_id[0] = port_priv->idx;\n> > +\terr = dpsw_vlan_add_if(ethsw->mc_io, 0, ethsw->dpsw_handle, vid,\n> &vcfg);\n> > +\tif (err) {\n> > +\t\tnetdev_err(netdev, \"dpsw_vlan_add_if err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\tport_priv->vlans[vid] = ETHSW_VLAN_MEMBER;\n> > +\n> > +\tif (flags & BRIDGE_VLAN_INFO_UNTAGGED) {\n> > +\t\terr = dpsw_vlan_add_if_untagged(ethsw->mc_io, 0,\n> > +\t\t\t\t\t\tethsw->dpsw_handle,\n> > +\t\t\t\t\t\tvid, &vcfg);\n> > +\t\tif (err) {\n> > +\t\t\tnetdev_err(netdev,\n> > +\t\t\t\t   \"dpsw_vlan_add_if_untagged err %d\\n\", err);\n> > +\t\t\treturn err;\n> > +\t\t}\n> > +\t\tport_priv->vlans[vid] |= ETHSW_VLAN_UNTAGGED;\n> > +\t}\n> > +\n> > +\tif (flags & BRIDGE_VLAN_INFO_PVID) {\n> > +\t\tstruct dpsw_tci_cfg tci_cfg = {\n> > +\t\t\t.pcp = 0,\n> > +\t\t\t.dei = 0,\n> > +\t\t\t.vlan_id = vid,\n> > +\t\t};\n> > +\n> > +\t\t/* Interface needs to be down to change PVID */\n> > +\t\tis_oper = netif_oper_up(netdev);\n> > +\t\tif (is_oper) {\n> > +\t\t\terr = dpsw_if_disable(ethsw->mc_io, 0,\n> > +\t\t\t\t\t      ethsw->dpsw_handle,\n> > +\t\t\t\t\t      port_priv->idx);\n> > +\t\t\tif (err) {\n> > +\t\t\t\tnetdev_err(netdev,\n> > +\t\t\t\t\t   \"dpsw_if_disable err %d\\n\", err);\n> > +\t\t\t\treturn err;\n> > +\t\t\t}\n> > +\t\t}\n> > +\n> > +\t\terr = dpsw_if_set_tci(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> > +\t\t\t\t      port_priv->idx, &tci_cfg);\n> > +\t\tif (!err) {\n> > +\t\t\t/* Delete previous PVID info and mark the new one */\n> > +\t\t\tif (port_priv->pvid)\n> > +\t\t\t\tport_priv->vlans[port_priv->pvid]\n> > +\t\t\t\t\t\t ^= ETHSW_VLAN_PVID;\n> \n> Can it be \" &= ~ETHSW_VLAN_PVID\" ? Are there other implications?\n> \nYou are right. Flag must be un-set. Will update in v2, along with the other observations.\nThank you,\nRazvan S.\n> > +\n> > +\t\t\tport_priv->vlans[vid] |= ETHSW_VLAN_PVID;\n> > +\t\t\tport_priv->pvid = vid;\n> > +\t\t} else {\n> > +\t\t\tnetdev_err(netdev, \"dpsw_if_set_tci err %d\\n\", err);\n> > +\t\t}\n> > +\n> > +\t\tif (is_oper) {\n> > +\t\t\terr2 = dpsw_if_enable(ethsw->mc_io, 0,\n> > +\t\t\t\t\t      ethsw->dpsw_handle,\n> > +\t\t\t\t\t      port_priv->idx);\n> > +\t\t\tif (err2) {\n> > +\t\t\t\tnetdev_err(netdev,\n> > +\t\t\t\t\t   \"dpsw_if_enable err %d\\n\", err2);\n> > +\t\t\t\treturn err2;\n> > +\t\t\t}\n> > +\t\t}\n> > +\t}\n> > +\n> > +\treturn err;\n> > +}\n> > +\n> > +static int ethsw_set_learning(struct ethsw_core *ethsw, u8 flag)\n> > +{\n> > +\tenum dpsw_fdb_learning_mode learn_mode;\n> > +\tint err;\n> > +\n> > +\tif (flag)\n> > +\t\tlearn_mode = DPSW_FDB_LEARNING_MODE_HW;\n> > +\telse\n> > +\t\tlearn_mode = DPSW_FDB_LEARNING_MODE_DIS;\n> > +\n> > +\terr = dpsw_fdb_set_learning_mode(ethsw->mc_io, 0, ethsw-\n> >dpsw_handle, 0,\n> > +\t\t\t\t\t learn_mode);\n> > +\tif (err) {\n> > +\t\tdev_err(ethsw->dev, \"dpsw_fdb_set_learning_mode err %d\\n\",\n> err);\n> > +\t\treturn err;\n> > +\t}\n> > +\tethsw->learning = !!flag;\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int ethsw_port_set_flood(struct ethsw_port_priv *port_priv, u8 flag)\n> > +{\n> > +\tint err;\n> > +\n> > +\terr = dpsw_if_set_flooding(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t   port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t   port_priv->idx, (int)flag);\n> \n> Why is this cast necessary? Can't the API be reworked to use u8 (or, better yet,\n> bool) instead of int?\n> \n> > +\tif (err) {\n> > +\t\tnetdev_err(port_priv->netdev,\n> > +\t\t\t   \"dpsw_fdb_set_learning_mode err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\tport_priv->flood = !!flag;\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int ethsw_port_set_stp_state(struct ethsw_port_priv *port_priv, u8\n> > state)\n> > +{\n> > +\tstruct dpsw_stp_cfg stp_cfg = {\n> > +\t\t.vlan_id = DEFAULT_VLAN_ID,\n> > +\t\t.state = state,\n> > +\t};\n> > +\tint err;\n> > +\n> > +\tif (!netif_oper_up(port_priv->netdev) || state == port_priv->stp_state)\n> > +\t\treturn 0;\t/* Nothing to do */\n> > +\n> > +\terr = dpsw_if_set_stp(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t      port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t      port_priv->idx, &stp_cfg);\n> > +\tif (err) {\n> > +\t\tnetdev_err(port_priv->netdev,\n> > +\t\t\t   \"dpsw_if_set_stp err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\tport_priv->stp_state = state;\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int ethsw_dellink_switch(struct ethsw_core *ethsw, u16 vid)\n> > +{\n> > +\tstruct ethsw_port_priv *ppriv_local = NULL;\n> > +\tint i, err;\n> > +\n> > +\tif (!ethsw->vlans[vid])\n> > +\t\treturn -ENOENT;\n> > +\n> > +\terr = dpsw_vlan_remove(ethsw->mc_io, 0, ethsw->dpsw_handle, vid);\n> > +\tif (err) {\n> > +\t\tdev_err(ethsw->dev, \"dpsw_vlan_remove err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\tethsw->vlans[vid] = 0;\n> > +\n> > +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> > +\t\tppriv_local = ethsw->ports[i];\n> > +\t\tppriv_local->vlans[vid] = 0;\n> > +\t}\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int ethsw_port_fdb_add_uc(struct ethsw_port_priv *port_priv,\n> > +\t\t\t\t const unsigned char *addr)\n> > +{\n> > +\tstruct dpsw_fdb_unicast_cfg entry = {0};\n> > +\tint err;\n> > +\n> > +\tentry.if_egress = port_priv->idx;\n> > +\tentry.type = DPSW_FDB_ENTRY_STATIC;\n> > +\tether_addr_copy(entry.mac_addr, addr);\n> > +\n> > +\terr = dpsw_fdb_add_unicast(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t   port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t   0, &entry);\n> > +\tif (err)\n> > +\t\tnetdev_err(port_priv->netdev,\n> > +\t\t\t   \"dpsw_fdb_add_unicast err %d\\n\", err);\n> > +\treturn err;\n> > +}\n> > +\n> > +static int ethsw_port_fdb_del_uc(struct ethsw_port_priv *port_priv,\n> > +\t\t\t\t const unsigned char *addr)\n> > +{\n> > +\tstruct dpsw_fdb_unicast_cfg entry = {0};\n> > +\tint err;\n> > +\n> > +\tentry.if_egress = port_priv->idx;\n> > +\tentry.type = DPSW_FDB_ENTRY_STATIC;\n> > +\tether_addr_copy(entry.mac_addr, addr);\n> > +\n> > +\terr = dpsw_fdb_remove_unicast(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t      port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t      0, &entry);\n> > +\tif (err)\n> > +\t\tnetdev_err(port_priv->netdev,\n> > +\t\t\t   \"dpsw_fdb_remove_unicast err %d\\n\", err);\n> > +\treturn err;\n> > +}\n> > +\n> > +static int ethsw_port_fdb_add_mc(struct ethsw_port_priv *port_priv,\n> > +\t\t\t\t const unsigned char *addr)\n> > +{\n> > +\tstruct dpsw_fdb_multicast_cfg entry = {0};\n> > +\tint err;\n> > +\n> > +\tether_addr_copy(entry.mac_addr, addr);\n> > +\tentry.type = DPSW_FDB_ENTRY_STATIC;\n> > +\tentry.num_ifs = 1;\n> > +\tentry.if_id[0] = port_priv->idx;\n> > +\n> > +\terr = dpsw_fdb_add_multicast(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t     port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t     0, &entry);\n> > +\tif (err)\n> > +\t\tnetdev_err(port_priv->netdev, \"dpsw_fdb_add_multicast err\n> %d\\n\",\n> > +\t\t\t   err);\n> > +\treturn err;\n> > +}\n> > +\n> > +static int ethsw_port_fdb_del_mc(struct ethsw_port_priv *port_priv,\n> > +\t\t\t\t const unsigned char *addr)\n> > +{\n> > +\tstruct dpsw_fdb_multicast_cfg entry = {0};\n> > +\tint err;\n> > +\n> > +\tether_addr_copy(entry.mac_addr, addr);\n> > +\tentry.type = DPSW_FDB_ENTRY_STATIC;\n> > +\tentry.num_ifs = 1;\n> > +\tentry.if_id[0] = port_priv->idx;\n> > +\n> > +\terr = dpsw_fdb_remove_multicast(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t\tport_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t\t0, &entry);\n> > +\tif (err)\n> > +\t\tnetdev_err(port_priv->netdev,\n> > +\t\t\t   \"dpsw_fdb_remove_multicast err %d\\n\", err);\n> > +\treturn err;\n> > +}\n> > +\n> > +static void port_get_stats(struct net_device *netdev,\n> > +\t\t\t   struct rtnl_link_stats64 *stats)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\tu64 tmp;\n> > +\tint err;\n> > +\n> > +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t  port_priv->idx,\n> > +\t\t\t\t  DPSW_CNT_ING_FRAME, &stats->rx_packets);\n> > +\tif (err)\n> > +\t\tgoto error;\n> > +\n> > +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t  port_priv->idx,\n> > +\t\t\t\t  DPSW_CNT_EGR_FRAME, &stats->tx_packets);\n> > +\tif (err)\n> > +\t\tgoto error;\n> > +\n> > +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t  port_priv->idx,\n> > +\t\t\t\t  DPSW_CNT_ING_BYTE, &stats->rx_bytes);\n> > +\tif (err)\n> > +\t\tgoto error;\n> > +\n> > +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t  port_priv->idx,\n> > +\t\t\t\t  DPSW_CNT_EGR_BYTE, &stats->tx_bytes);\n> > +\tif (err)\n> > +\t\tgoto error;\n> > +\n> > +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t  port_priv->idx,\n> > +\t\t\t\t  DPSW_CNT_ING_FRAME_DISCARD,\n> > +\t\t\t\t  &stats->rx_dropped);\n> > +\tif (err)\n> > +\t\tgoto error;\n> > +\n> > +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t  port_priv->idx,\n> > +\t\t\t\t  DPSW_CNT_ING_FLTR_FRAME,\n> > +\t\t\t\t  &tmp);\n> > +\tif (err)\n> > +\t\tgoto error;\n> > +\tstats->rx_dropped += tmp;\n> > +\n> > +\terr = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t  port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t  port_priv->idx,\n> > +\t\t\t\t  DPSW_CNT_EGR_FRAME_DISCARD,\n> > +\t\t\t\t  &stats->tx_dropped);\n> > +\tif (err)\n> > +\t\tgoto error;\n> > +\n> > +\treturn;\n> > +\n> > +error:\n> > +\tnetdev_err(netdev, \"dpsw_if_get_counter err %d\\n\", err);\n> > +}\n> > +\n> > +static bool port_has_offload_stats(const struct net_device *netdev,\n> > +\t\t\t\t   int attr_id)\n> > +{\n> > +\treturn (attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT);\n> > +}\n> > +\n> > +static int port_get_offload_stats(int attr_id,\n> > +\t\t\t\t  const struct net_device *netdev,\n> > +\t\t\t\t  void *sp)\n> > +{\n> > +\tswitch (attr_id) {\n> > +\tcase IFLA_OFFLOAD_XSTATS_CPU_HIT:\n> > +\t\tport_get_stats((struct net_device *)netdev, sp);\n> > +\t\treturn 0;\n> > +\t}\n> > +\n> > +\treturn -EINVAL;\n> > +}\n> > +\n> > +static int port_change_mtu(struct net_device *netdev, int mtu)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\tint err;\n> > +\n> > +\terr = dpsw_if_set_max_frame_length(port_priv->ethsw_data->mc_io,\n> > +\t\t\t\t\t   0,\n> > +\t\t\t\t\t   port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t\t   port_priv->idx,\n> > +\t\t\t\t\t   (u16)ETHSW_L2_MAX_FRM(mtu));\n> > +\tif (err) {\n> > +\t\tnetdev_err(netdev,\n> > +\t\t\t   \"dpsw_if_set_max_frame_length() err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\tnetdev->mtu = mtu;\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int port_carrier_state_sync(struct net_device *netdev)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\tstruct dpsw_link_state state;\n> > +\tint err;\n> > +\n> > +\terr = dpsw_if_get_link_state(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t\t     port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t\t     port_priv->idx, &state);\n> > +\tif (err) {\n> > +\t\tnetdev_err(netdev, \"dpsw_if_get_link_state() err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\tWARN_ONCE(state.up > 1, \"Garbage read into link_state\");\n> > +\n> > +\tif (state.up != port_priv->link_state) {\n> > +\t\tif (state.up)\n> > +\t\t\tnetif_carrier_on(netdev);\n> > +\t\telse\n> > +\t\t\tnetif_carrier_off(netdev);\n> > +\t\tport_priv->link_state = state.up;\n> > +\t}\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int port_open(struct net_device *netdev)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\tint err;\n> > +\n> > +\t/* No need to allow Tx as control interface is disabled */\n> > +\tnetif_tx_stop_all_queues(netdev);\n> > +\n> > +\terr = dpsw_if_enable(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t     port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t     port_priv->idx);\n> > +\tif (err) {\n> > +\t\tnetdev_err(netdev, \"dpsw_if_enable err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\t/* sync carrier state */\n> > +\terr = port_carrier_state_sync(netdev);\n> > +\tif (err) {\n> > +\t\tnetdev_err(netdev,\n> > +\t\t\t   \"port_carrier_state_sync err %d\\n\", err);\n> > +\t\tgoto err_carrier_sync;\n> > +\t}\n> > +\n> > +\treturn 0;\n> > +\n> > +err_carrier_sync:\n> > +\tdpsw_if_disable(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\tport_priv->ethsw_data->dpsw_handle,\n> > +\t\t\tport_priv->idx);\n> > +\treturn err;\n> > +}\n> > +\n> > +static int port_stop(struct net_device *netdev)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\tint err;\n> > +\n> > +\terr = dpsw_if_disable(port_priv->ethsw_data->mc_io, 0,\n> > +\t\t\t      port_priv->ethsw_data->dpsw_handle,\n> > +\t\t\t      port_priv->idx);\n> > +\tif (err) {\n> > +\t\tnetdev_err(netdev, \"dpsw_if_disable err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> > +static netdev_tx_t port_dropframe(struct sk_buff *skb,\n> > +\t\t\t\t  struct net_device *netdev)\n> > +{\n> > +\t/* we don't support I/O for now, drop the frame */\n> > +\tdev_kfree_skb_any(skb);\n> > +\n> > +\treturn NETDEV_TX_OK;\n> > +}\n> > +\n> > +static const struct net_device_ops ethsw_port_ops = {\n> > +\t.ndo_open\t\t= port_open,\n> > +\t.ndo_stop\t\t= port_stop,\n> > +\n> > +\t.ndo_set_mac_address\t= eth_mac_addr,\n> > +\t.ndo_change_mtu\t\t= port_change_mtu,\n> > +\t.ndo_has_offload_stats\t= port_has_offload_stats,\n> > +\t.ndo_get_offload_stats\t= port_get_offload_stats,\n> > +\n> > +\t.ndo_start_xmit\t\t= port_dropframe,\n> > +};\n> > +\n> > +static void ethsw_links_state_update(struct ethsw_core *ethsw)\n> > +{\n> > +\tint i;\n> > +\n> > +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++)\n> > +\t\tport_carrier_state_sync(ethsw->ports[i]->netdev);\n> > +}\n> > +\n> > +static irqreturn_t ethsw_irq0_handler(int irq_num, void *arg)\n> > +{\n> > +\treturn IRQ_WAKE_THREAD;\n> > +}\n> > +\n> > +static irqreturn_t ethsw_irq0_handler_thread(int irq_num, void *arg)\n> > +{\n> > +\tstruct device *dev = (struct device *)arg;\n> > +\tstruct ethsw_core *ethsw = dev_get_drvdata(dev);\n> > +\n> > +\t/* Mask the events and the if_id reserved bits to be cleared on read */\n> > +\tu32 status = DPSW_IRQ_EVENT_LINK_CHANGED | 0xFFFF0000;\n> > +\tint err;\n> > +\n> > +\terr = dpsw_get_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> > +\t\t\t\t  DPSW_IRQ_INDEX_IF, &status);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"Can't get irq status (err %d)\", err);\n> > +\n> > +\t\terr = dpsw_clear_irq_status(ethsw->mc_io, 0, ethsw-\n> >dpsw_handle,\n> > +\t\t\t\t\t    DPSW_IRQ_INDEX_IF, 0xFFFFFFFF);\n> > +\t\tif (err)\n> > +\t\t\tdev_err(dev, \"Can't clear irq status (err %d)\", err);\n> > +\t\tgoto out;\n> > +\t}\n> > +\n> > +\tif (status & DPSW_IRQ_EVENT_LINK_CHANGED)\n> > +\t\tethsw_links_state_update(ethsw);\n> > +\n> > +out:\n> > +\treturn IRQ_HANDLED;\n> > +}\n> > +\n> > +static int ethsw_setup_irqs(struct fsl_mc_device *sw_dev)\n> > +{\n> > +\tstruct device *dev = &sw_dev->dev;\n> > +\tstruct ethsw_core *ethsw = dev_get_drvdata(dev);\n> > +\tu32 mask = DPSW_IRQ_EVENT_LINK_CHANGED;\n> > +\tstruct fsl_mc_device_irq *irq;\n> > +\tint err;\n> > +\n> > +\terr = fsl_mc_allocate_irqs(sw_dev);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"MC irqs allocation failed\\n\");\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\tif (WARN_ON(sw_dev->obj_desc.irq_count != DPSW_IRQ_NUM)) {\n> > +\t\terr = -EINVAL;\n> > +\t\tgoto free_irq;\n> > +\t}\n> > +\n> > +\terr = dpsw_set_irq_enable(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> > +\t\t\t\t  DPSW_IRQ_INDEX_IF, 0);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"dpsw_set_irq_enable err %d\\n\", err);\n> > +\t\tgoto free_irq;\n> > +\t}\n> > +\n> > +\tirq = sw_dev->irqs[DPSW_IRQ_INDEX_IF];\n> > +\n> > +\terr = devm_request_threaded_irq(dev, irq->msi_desc->irq,\n> > +\t\t\t\t\tethsw_irq0_handler,\n> > +\t\t\t\t\tethsw_irq0_handler_thread,\n> > +\t\t\t\t\tIRQF_NO_SUSPEND | IRQF_ONESHOT,\n> > +\t\t\t\t\tdev_name(dev), dev);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"devm_request_threaded_irq(): %d\", err);\n> > +\t\tgoto free_irq;\n> > +\t}\n> > +\n> > +\terr = dpsw_set_irq_mask(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> > +\t\t\t\tDPSW_IRQ_INDEX_IF, mask);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"dpsw_set_irq_mask(): %d\", err);\n> > +\t\tgoto free_devm_irq;\n> > +\t}\n> > +\n> > +\terr = dpsw_set_irq_enable(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> > +\t\t\t\t  DPSW_IRQ_INDEX_IF, 1);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"dpsw_set_irq_enable(): %d\", err);\n> > +\t\tgoto free_devm_irq;\n> > +\t}\n> > +\n> > +\treturn 0;\n> > +\n> > +free_devm_irq:\n> > +\tdevm_free_irq(dev, irq->msi_desc->irq, dev);\n> > +free_irq:\n> > +\tfsl_mc_free_irqs(sw_dev);\n> > +\treturn err;\n> > +}\n> > +\n> > +static void ethsw_teardown_irqs(struct fsl_mc_device *sw_dev)\n> > +{\n> > +\tstruct device *dev = &sw_dev->dev;\n> > +\tstruct ethsw_core *ethsw = dev_get_drvdata(dev);\n> > +\tstruct fsl_mc_device_irq *irq;\n> > +\n> > +\tirq = sw_dev->irqs[DPSW_IRQ_INDEX_IF];\n> > +\tdpsw_set_irq_enable(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> > +\t\t\t    DPSW_IRQ_INDEX_IF, 0);\n> \n> You can still print an error message here, in case something goes wrong.\n> \n> > +\tfsl_mc_free_irqs(sw_dev);\n> > +}\n> > +\n> > +static int swdev_port_attr_get(struct net_device *netdev,\n> > +\t\t\t       struct switchdev_attr *attr)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\n> > +\tswitch (attr->id) {\n> > +\tcase SWITCHDEV_ATTR_ID_PORT_PARENT_ID:\n> > +\t\tattr->u.ppid.id_len = 1;\n> > +\t\tattr->u.ppid.id[0] = port_priv->ethsw_data->dev_id;\n> > +\t\tbreak;\n> > +\tcase SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:\n> > +\t\tattr->u.brport_flags =\n> > +\t\t\t(port_priv->ethsw_data->learning ? BR_LEARNING : 0) |\n> > +\t\t\t(port_priv->flood ? BR_FLOOD : 0);\n> > +\t\tbreak;\n> > +\tcase SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:\n> > +\t\tattr->u.brport_flags_support = BR_LEARNING | BR_FLOOD;\n> > +\t\tbreak;\n> > +\tdefault:\n> > +\t\treturn -EOPNOTSUPP;\n> > +\t}\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int port_attr_stp_state_set(struct net_device *netdev,\n> > +\t\t\t\t   struct switchdev_trans *trans,\n> > +\t\t\t\t   u8 state)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\n> > +\tif (switchdev_trans_ph_prepare(trans))\n> > +\t\treturn 0;\n> > +\n> > +\treturn ethsw_port_set_stp_state(port_priv, state);\n> > +}\n> > +\n> > +static int port_attr_br_flags_set(struct net_device *netdev,\n> > +\t\t\t\t  struct switchdev_trans *trans,\n> > +\t\t\t\t  unsigned long flags)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\tint err = 0;\n> > +\n> > +\tif (switchdev_trans_ph_prepare(trans))\n> > +\t\treturn 0;\n> > +\n> > +\t/* Learning is enabled per switch */\n> > +\terr = ethsw_set_learning(port_priv->ethsw_data, flags &\n> BR_LEARNING);\n> > +\tif (err)\n> > +\t\tgoto exit;\n> > +\n> > +\terr = ethsw_port_set_flood(port_priv, flags & BR_FLOOD);\n> > +\n> > +exit:\n> > +\treturn err;\n> > +}\n> > +\n> > +static int swdev_port_attr_set(struct net_device *netdev,\n> > +\t\t\t       const struct switchdev_attr *attr,\n> > +\t\t\t       struct switchdev_trans *trans)\n> > +{\n> > +\tint err = 0;\n> > +\n> > +\tswitch (attr->id) {\n> > +\tcase SWITCHDEV_ATTR_ID_PORT_STP_STATE:\n> > +\t\terr = port_attr_stp_state_set(netdev, trans,\n> > +\t\t\t\t\t      attr->u.stp_state);\n> > +\t\tbreak;\n> > +\tcase SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:\n> > +\t\terr = port_attr_br_flags_set(netdev, trans,\n> > +\t\t\t\t\t     attr->u.brport_flags);\n> > +\t\tbreak;\n> > +\tcase SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:\n> > +\t\t/* VLANs are supported by default  */\n> > +\t\tbreak;\n> > +\tdefault:\n> > +\t\terr = -EOPNOTSUPP;\n> > +\t\tbreak;\n> > +\t}\n> > +\n> > +\treturn err;\n> > +}\n> > +\n> > +static int port_vlans_add(struct net_device *netdev,\n> > +\t\t\t  const struct switchdev_obj_port_vlan *vlan,\n> > +\t\t\t  struct switchdev_trans *trans)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\tint vid, err;\n> > +\n> > +\tif (switchdev_trans_ph_prepare(trans))\n> > +\t\treturn 0;\n> > +\n> > +\tfor (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {\n> > +\t\tif (!port_priv->ethsw_data->vlans[vid]) {\n> > +\t\t\t/* this is a new VLAN */\n> > +\t\t\terr = ethsw_add_vlan(port_priv->ethsw_data, vid);\n> > +\t\t\tif (err)\n> > +\t\t\t\treturn err;\n> > +\n> > +\t\t\tport_priv->ethsw_data->vlans[vid] |=\n> ETHSW_VLAN_GLOBAL;\n> > +\t\t}\n> > +\t\terr = ethsw_port_add_vlan(port_priv, vid, vlan->flags);\n> > +\t\tif (err)\n> > +\t\t\tbreak;\n> > +\t}\n> > +\n> > +\treturn err;\n> > +}\n> > +\n> > +static int port_lookup_address(struct net_device *netdev, int is_uc,\n> > +\t\t\t       const unsigned char *addr)\n> > +{\n> > +\tstruct netdev_hw_addr_list *list = (is_uc) ? &netdev->uc : &netdev->mc;\n> > +\tstruct netdev_hw_addr *ha;\n> > +\n> > +\tnetif_addr_lock_bh(netdev);\n> > +\tlist_for_each_entry(ha, &list->list, list) {\n> > +\t\tif (ether_addr_equal(ha->addr, addr)) {\n> > +\t\t\tnetif_addr_unlock_bh(netdev);\n> > +\t\t\treturn 1;\n> > +\t\t}\n> > +\t}\n> > +\tnetif_addr_unlock_bh(netdev);\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int port_mdb_add(struct net_device *netdev,\n> > +\t\t\tconst struct switchdev_obj_port_mdb *mdb,\n> > +\t\t\tstruct switchdev_trans *trans)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\tint err;\n> > +\n> > +\tif (switchdev_trans_ph_prepare(trans))\n> > +\t\treturn 0;\n> > +\n> > +\t/* Check if address is already set on this port */\n> > +\tif (port_lookup_address(netdev, 0, mdb->addr))\n> > +\t\treturn -EEXIST;\n> > +\n> > +\terr = ethsw_port_fdb_add_mc(port_priv, mdb->addr);\n> > +\tif (err)\n> > +\t\treturn err;\n> > +\n> > +\terr = dev_mc_add(netdev, mdb->addr);\n> > +\tif (err)\n> > +\t\tnetdev_err(netdev, \"dev_mc_add err %d\\n\", err);\n> \n> In the error case, shouldn't there be a \"ethsw_port_fdb_del_mc\" ?\n> \n> > +\n> > +\treturn err;\n> > +}\n> > +\n> > +static int swdev_port_obj_add(struct net_device *netdev,\n> > +\t\t\t      const struct switchdev_obj *obj,\n> > +\t\t\t      struct switchdev_trans *trans)\n> > +{\n> > +\tint err;\n> > +\n> > +\tswitch (obj->id) {\n> > +\tcase SWITCHDEV_OBJ_ID_PORT_VLAN:\n> > +\t\terr = port_vlans_add(netdev,\n> > +\t\t\t\t     SWITCHDEV_OBJ_PORT_VLAN(obj),\n> > +\t\t\t\t     trans);\n> > +\t\tbreak;\n> > +\tcase SWITCHDEV_OBJ_ID_PORT_MDB:\n> > +\t\terr = port_mdb_add(netdev,\n> > +\t\t\t\t   SWITCHDEV_OBJ_PORT_MDB(obj),\n> > +\t\t\t\t   trans);\n> > +\t\tbreak;\n> > +\tdefault:\n> > +\t\terr = -EOPNOTSUPP;\n> > +\t\tbreak;\n> > +\t}\n> > +\n> > +\treturn err;\n> > +}\n> > +\n> > +static int ethsw_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid)\n> > +{\n> > +\tstruct ethsw_core *ethsw = port_priv->ethsw_data;\n> > +\tstruct net_device *netdev = port_priv->netdev;\n> > +\tstruct dpsw_vlan_if_cfg vcfg;\n> > +\tint i, err, err2;\n> > +\tbool is_oper;\n> > +\n> > +\tif (!port_priv->vlans[vid])\n> > +\t\treturn -ENOENT;\n> > +\n> > +\tif (port_priv->vlans[vid] & ETHSW_VLAN_PVID) {\n> > +\t\tstruct dpsw_tci_cfg tci_cfg = { 0 };\n> > +\t\t/* Interface needs to be down to change PVID */\n> > +\t\tis_oper = netif_oper_up(netdev);\n> > +\n> > +\t\tif (is_oper) {\n> > +\t\t\terr = dpsw_if_disable(ethsw->mc_io, 0,\n> > +\t\t\t\t\t      ethsw->dpsw_handle,\n> > +\t\t\t\t\t      port_priv->idx);\n> > +\t\t\tif (err) {\n> > +\t\t\t\tnetdev_err(netdev, \"dpsw_if_disable err %d\\n\",\n> > +\t\t\t\t\t   err);\n> > +\t\t\t\tgoto exit_err;\n> > +\t\t\t}\n> > +\t\t}\n> > +\n> > +\t\terr = dpsw_if_set_tci(ethsw->mc_io, 0,\n> > +\t\t\t\t      ethsw->dpsw_handle,\n> > +\t\t\t\t      port_priv->idx, &tci_cfg);\n> > +\t\tif (!err) {\n> > +\t\t\tport_priv->vlans[vid] &= ~ETHSW_VLAN_PVID;\n> > +\t\t\tport_priv->pvid = 0;\n> > +\t\t} else {\n> > +\t\t\tnetdev_err(netdev, \"dpsw_if_set_tci err %d\\n\", err);\n> > +\t\t}\n> > +\n> > +\t\tif (is_oper) {\n> > +\t\t\terr2 = dpsw_if_enable(ethsw->mc_io, 0,\n> > +\t\t\t\t\t      ethsw->dpsw_handle,\n> > +\t\t\t\t\t      port_priv->idx);\n> > +\t\t\tif (err2) {\n> > +\t\t\t\tnetdev_err(netdev, \"dpsw_if_enable err %d\\n\",\n> > +\t\t\t\t\t   err2);\n> > +\t\t\t\treturn err2;\n> > +\t\t\t}\n> > +\t\t}\n> > +\n> > +\t\tif (err)\n> > +\t\t\tgoto exit_err;\n> > +\t}\n> > +\n> > +\tvcfg.num_ifs = 1;\n> > +\tvcfg.if_id[0] = port_priv->idx;\n> > +\tif (port_priv->vlans[vid] & ETHSW_VLAN_UNTAGGED) {\n> > +\t\terr = dpsw_vlan_remove_if_untagged(ethsw->mc_io, 0,\n> > +\t\t\t\t\t\t   ethsw->dpsw_handle,\n> > +\t\t\t\t\t\t   vid, &vcfg);\n> > +\t\tif (err) {\n> > +\t\t\tnetdev_err(netdev,\n> > +\t\t\t\t   \"dpsw_vlan_remove_if_untagged err %d\\n\",\n> > +\t\t\t\t   err);\n> > +\t\t}\n> > +\t\tport_priv->vlans[vid] &= ~ETHSW_VLAN_UNTAGGED;\n> > +\t}\n> > +\n> > +\tif (port_priv->vlans[vid] & ETHSW_VLAN_MEMBER) {\n> > +\t\terr = dpsw_vlan_remove_if(ethsw->mc_io, 0, ethsw-\n> >dpsw_handle,\n> > +\t\t\t\t\t  vid, &vcfg);\n> > +\t\tif (err) {\n> > +\t\t\tnetdev_err(netdev,\n> > +\t\t\t\t   \"dpsw_vlan_remove_if err %d\\n\", err);\n> > +\t\t\treturn err;\n> > +\t\t}\n> > +\t\tport_priv->vlans[vid] &= ~ETHSW_VLAN_MEMBER;\n> > +\n> > +\t\t/* Delete VLAN from switch if it is no longer configured on\n> > +\t\t * any port\n> > +\t\t */\n> > +\t\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++)\n> > +\t\t\tif (ethsw->ports[i]->vlans[vid] &\n> ETHSW_VLAN_MEMBER)\n> > +\t\t\t\treturn 0; /* Found a port member in VID */\n> > +\n> > +\t\tethsw->vlans[vid] &= ~ETHSW_VLAN_GLOBAL;\n> > +\n> > +\t\terr = ethsw_dellink_switch(ethsw, vid);\n> > +\t\tif (err)\n> > +\t\t\tgoto exit_err;\n> > +\t}\n> > +\n> > +\treturn 0;\n> > +exit_err:\n> > +\treturn err;\n> > +}\n> > +\n> > +static int port_vlans_del(struct net_device *netdev,\n> > +\t\t\t  const struct switchdev_obj_port_vlan *vlan)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\tint vid, err;\n> > +\n> > +\tfor (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {\n> > +\t\terr = ethsw_port_del_vlan(port_priv, vid);\n> > +\t\tif (err)\n> > +\t\t\tbreak;\n> > +\t}\n> > +\n> > +\treturn err;\n> > +}\n> > +\n> > +static int port_mdb_del(struct net_device *netdev,\n> > +\t\t\tconst struct switchdev_obj_port_mdb *mdb)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\tint err;\n> > +\n> > +\tif (!port_lookup_address(netdev, 0, mdb->addr))\n> > +\t\treturn -ENOENT;\n> > +\n> > +\terr = ethsw_port_fdb_del_mc(port_priv, mdb->addr);\n> > +\tif (err)\n> > +\t\treturn err;\n> > +\n> > +\terr = dev_mc_del(netdev, mdb->addr);\n> > +\tif (err) {\n> > +\t\tnetdev_err(netdev, \"dev_mc_del err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\treturn err;\n> > +}\n> > +\n> > +static int swdev_port_obj_del(struct net_device *netdev,\n> > +\t\t\t      const struct switchdev_obj *obj)\n> > +{\n> > +\tint err;\n> > +\n> > +\tswitch (obj->id) {\n> > +\tcase SWITCHDEV_OBJ_ID_PORT_VLAN:\n> > +\t\terr = port_vlans_del(netdev,\n> SWITCHDEV_OBJ_PORT_VLAN(obj));\n> > +\t\tbreak;\n> > +\tcase SWITCHDEV_OBJ_ID_PORT_MDB:\n> > +\t\terr = port_mdb_del(netdev, SWITCHDEV_OBJ_PORT_MDB(obj));\n> > +\t\tbreak;\n> > +\tdefault:\n> > +\t\terr = -EOPNOTSUPP;\n> > +\t\tbreak;\n> > +\t}\n> > +\treturn err;\n> > +}\n> > +\n> > +static const struct switchdev_ops ethsw_port_switchdev_ops = {\n> > +\t.switchdev_port_attr_get\t= swdev_port_attr_get,\n> > +\t.switchdev_port_attr_set\t= swdev_port_attr_set,\n> > +\t.switchdev_port_obj_add\t\t= swdev_port_obj_add,\n> > +\t.switchdev_port_obj_del\t\t= swdev_port_obj_del,\n> > +};\n> > +\n> > +/* For the moment, only flood setting needs to be updated */\n> > +static int port_bridge_join(struct net_device *netdev)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\n> > +\t/* Enable flooding */\n> > +\treturn ethsw_port_set_flood(port_priv, 1);\n> > +}\n> > +\n> > +static int port_bridge_leave(struct net_device *netdev)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = netdev_priv(netdev);\n> > +\n> > +\t/* Disable flooding */\n> > +\treturn ethsw_port_set_flood(port_priv, 0);\n> > +}\n> > +\n> > +static int port_netdevice_event(struct notifier_block *unused,\n> > +\t\t\t\tunsigned long event, void *ptr)\n> > +{\n> > +\tstruct net_device *netdev = netdev_notifier_info_to_dev(ptr);\n> > +\tstruct netdev_notifier_changeupper_info *info = ptr;\n> > +\tstruct net_device *upper_dev;\n> > +\tint err = 0;\n> > +\n> > +\tif (netdev->netdev_ops != &ethsw_port_ops)\n> > +\t\treturn NOTIFY_DONE;\n> > +\n> > +\t/* Handle just upper dev link/unlink for the moment */\n> > +\tif (event == NETDEV_CHANGEUPPER) {\n> > +\t\tupper_dev = info->upper_dev;\n> > +\t\tif (netif_is_bridge_master(upper_dev)) {\n> > +\t\t\tif (info->linking)\n> > +\t\t\t\terr = port_bridge_join(netdev);\n> > +\t\t\telse\n> > +\t\t\t\terr = port_bridge_leave(netdev);\n> > +\t\t}\n> > +\t}\n> > +\n> > +\treturn notifier_from_errno(err);\n> > +}\n> > +\n> > +static struct notifier_block port_nb __read_mostly = {\n> > +\t.notifier_call = port_netdevice_event,\n> > +};\n> > +\n> > +struct ethsw_switchdev_event_work {\n> > +\tstruct work_struct work;\n> > +\tstruct switchdev_notifier_fdb_info fdb_info;\n> > +\tstruct net_device *dev;\n> > +\tunsigned long event;\n> > +};\n> > +\n> > +static void ethsw_switchdev_event_work(struct work_struct *work)\n> > +{\n> > +\tstruct ethsw_switchdev_event_work *switchdev_work =\n> > +\t\tcontainer_of(work, struct ethsw_switchdev_event_work, work);\n> > +\tstruct net_device *dev = switchdev_work->dev;\n> > +\tstruct switchdev_notifier_fdb_info *fdb_info;\n> > +\tstruct ethsw_port_priv *port_priv;\n> > +\n> > +\trtnl_lock();\n> > +\tport_priv = netdev_priv(dev);\n> > +\tfdb_info = &switchdev_work->fdb_info;\n> > +\n> > +\tswitch (switchdev_work->event) {\n> > +\tcase SWITCHDEV_FDB_ADD_TO_DEVICE:\n> > +\t\tethsw_port_fdb_add_uc(netdev_priv(dev), fdb_info->addr);\n> > +\t\tbreak;\n> > +\tcase SWITCHDEV_FDB_DEL_TO_DEVICE:\n> > +\t\tethsw_port_fdb_del_uc(netdev_priv(dev), fdb_info->addr);\n> > +\t\tbreak;\n> > +\t}\n> > +\n> > +\trtnl_unlock();\n> > +\tkfree(switchdev_work->fdb_info.addr);\n> > +\tkfree(switchdev_work);\n> > +\tdev_put(dev);\n> > +}\n> > +\n> > +/* Called under rcu_read_lock() */\n> > +static int port_switchdev_event(struct notifier_block *unused,\n> > +\t\t\t\tunsigned long event, void *ptr)\n> > +{\n> > +\tstruct net_device *dev = switchdev_notifier_info_to_dev(ptr);\n> > +\tstruct ethsw_switchdev_event_work *switchdev_work;\n> > +\tstruct switchdev_notifier_fdb_info *fdb_info = ptr;\n> > +\n> > +\tswitchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);\n> > +\tif (!switchdev_work)\n> > +\t\treturn NOTIFY_BAD;\n> > +\n> > +\tINIT_WORK(&switchdev_work->work, ethsw_switchdev_event_work);\n> > +\tswitchdev_work->dev = dev;\n> > +\tswitchdev_work->event = event;\n> > +\n> > +\tswitch (event) {\n> > +\tcase SWITCHDEV_FDB_ADD_TO_DEVICE:\n> > +\tcase SWITCHDEV_FDB_DEL_TO_DEVICE:\n> > +\t\tmemcpy(&switchdev_work->fdb_info, ptr,\n> > +\t\t       sizeof(switchdev_work->fdb_info));\n> > +\t\tswitchdev_work->fdb_info.addr = kzalloc(ETH_ALEN,\n> GFP_ATOMIC);\n> > +\t\tif (!switchdev_work->fdb_info.addr)\n> > +\t\t\tgoto err_addr_alloc;\n> > +\n> > +\t\tether_addr_copy((u8 *)switchdev_work->fdb_info.addr,\n> > +\t\t\t\tfdb_info->addr);\n> > +\n> > +\t\t/* Take a reference on the device to avoid being freed. */\n> > +\t\tdev_hold(dev);\n> > +\t\tbreak;\n> > +\tdefault:\n> > +\t\treturn NOTIFY_DONE;\n> > +\t}\n> > +\n> > +\tqueue_work(ethsw_owq, &switchdev_work->work);\n> > +\n> > +\treturn NOTIFY_DONE;\n> > +\n> > +err_addr_alloc:\n> > +\tkfree(switchdev_work);\n> > +\treturn NOTIFY_BAD;\n> > +}\n> > +\n> > +static struct notifier_block port_switchdev_nb = {\n> > +\t.notifier_call = port_switchdev_event,\n> > +};\n> > +\n> > +static int ethsw_register_notifier(struct device *dev)\n> > +{\n> > +\tint err;\n> > +\n> > +\terr = register_netdevice_notifier(&port_nb);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"Failed to register netdev notifier\\n\");\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\terr = register_switchdev_notifier(&port_switchdev_nb);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"Failed to register switchdev notifier\\n\");\n> > +\t\tgoto err_switchdev_nb;\n> > +\t}\n> > +\n> > +\treturn 0;\n> > +\n> > +err_switchdev_nb:\n> > +\tunregister_netdevice_notifier(&port_nb);\n> > +\treturn err;\n> > +}\n> > +\n> > +static int ethsw_open(struct ethsw_core\t*ethsw)\n> \n> Minor formatting error, tab in function signature - see following function as well.\n> \n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = NULL;\n> > +\tint i, err;\n> > +\n> > +\terr = dpsw_enable(ethsw->mc_io, 0, ethsw->dpsw_handle);\n> > +\tif (err) {\n> > +\t\tdev_err(ethsw->dev, \"dpsw_enable err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> > +\t\tport_priv = ethsw->ports[i];\n> > +\t\terr = dev_open(port_priv->netdev);\n> > +\t\tif (err) {\n> > +\t\t\tnetdev_err(port_priv->netdev, \"dev_open err %d\\n\",\n> err);\n> > +\t\t\treturn err;\n> > +\t\t}\n> > +\t}\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int ethsw_stop(struct ethsw_core\t*ethsw)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv = NULL;\n> > +\tint i, err;\n> > +\n> > +\tdestroy_workqueue(ethsw_owq);\n> \n> If workqueue is destroyed here, shouldn't it be alloc'd in ethsw_open?\n> \n> > +\n> > +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> > +\t\tport_priv = ethsw->ports[i];\n> > +\t\tdev_close(port_priv->netdev);\n> > +\t}\n> > +\n> > +\terr = dpsw_disable(ethsw->mc_io, 0, ethsw->dpsw_handle);\n> > +\tif (err) {\n> > +\t\tdev_err(ethsw->dev, \"dpsw_disable err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int ethsw_init(struct fsl_mc_device *sw_dev)\n> > +{\n> > +\tstruct device *dev = &sw_dev->dev;\n> > +\tstruct ethsw_core *ethsw = dev_get_drvdata(dev);\n> > +\tu16 version_major, version_minor, i;\n> > +\tstruct dpsw_stp_cfg stp_cfg;\n> > +\tint err;\n> > +\n> > +\tethsw->dev_id = sw_dev->obj_desc.id;\n> > +\n> > +\terr = dpsw_open(ethsw->mc_io, 0, ethsw->dev_id, &ethsw-\n> >dpsw_handle);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"dpsw_open err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\terr = dpsw_get_attributes(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> > +\t\t\t\t  &ethsw->sw_attr);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"dpsw_get_attributes err %d\\n\", err);\n> > +\t\tgoto err_close;\n> > +\t}\n> > +\n> > +\terr = dpsw_get_api_version(ethsw->mc_io, 0,\n> > +\t\t\t\t   &version_major,\n> > +\t\t\t\t   &version_minor);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"dpsw_get_api_version err %d\\n\", err);\n> > +\t\tgoto err_close;\n> > +\t}\n> > +\n> > +\t/* Minimum supported DPSW version check */\n> > +\tif (version_major < DPSW_MIN_VER_MAJOR ||\n> > +\t    (version_major == DPSW_MIN_VER_MAJOR &&\n> > +\t     version_minor < DPSW_MIN_VER_MINOR)) {\n> > +\t\tdev_err(dev, \"DPSW version %d:%d not supported. Use %d.%d\n> or\n> > greater.\\n\",\n> > +\t\t\tversion_major,\n> > +\t\t\tversion_minor,\n> > +\t\t\tDPSW_MIN_VER_MAJOR, DPSW_MIN_VER_MINOR);\n> > +\t\terr = -ENOTSUPP;\n> > +\t\tgoto err_close;\n> > +\t}\n> > +\n> > +\terr = dpsw_reset(ethsw->mc_io, 0, ethsw->dpsw_handle);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"dpsw_reset err %d\\n\", err);\n> > +\t\tgoto err_close;\n> > +\t}\n> > +\n> > +\terr = dpsw_fdb_set_learning_mode(ethsw->mc_io, 0, ethsw-\n> >dpsw_handle, 0,\n> > +\t\t\t\t\t DPSW_FDB_LEARNING_MODE_HW);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"dpsw_fdb_set_learning_mode err %d\\n\", err);\n> > +\t\tgoto err_close;\n> > +\t}\n> > +\n> > +\tstp_cfg.vlan_id = DEFAULT_VLAN_ID;\n> > +\tstp_cfg.state = DPSW_STP_STATE_FORWARDING;\n> > +\n> > +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> > +\t\terr = dpsw_if_set_stp(ethsw->mc_io, 0, ethsw->dpsw_handle, i,\n> > +\t\t\t\t      &stp_cfg);\n> > +\t\tif (err) {\n> > +\t\t\tdev_err(dev, \"dpsw_if_set_stp err %d for port %d\\n\",\n> > +\t\t\t\terr, i);\n> > +\t\t\tgoto err_close;\n> > +\t\t}\n> > +\n> > +\t\terr = dpsw_if_set_broadcast(ethsw->mc_io, 0,\n> > +\t\t\t\t\t    ethsw->dpsw_handle, i, 1);\n> > +\t\tif (err) {\n> > +\t\t\tdev_err(dev,\n> > +\t\t\t\t\"dpsw_if_set_broadcast err %d for port %d\\n\",\n> > +\t\t\t\terr, i);\n> > +\t\t\tgoto err_close;\n> > +\t\t}\n> > +\t}\n> > +\n> > +\tethsw_owq = alloc_ordered_workqueue(\"%s_ordered\",\n> WQ_MEM_RECLAIM,\n> > +\t\t\t\t\t    \"ethsw\");\n> > +\tif (!ethsw_owq) {\n> > +\t\terr = -ENOMEM;\n> > +\t\tgoto err_close;\n> > +\t}\n> > +\n> > +\terr = ethsw_register_notifier(dev);\n> > +\tif (err)\n> > +\t\tgoto err_destroy_ordered_workqueue;\n> > +\n> > +\treturn 0;\n> > +\n> > +err_destroy_ordered_workqueue:\n> > +\tdestroy_workqueue(ethsw_owq);\n> > +\n> > +err_close:\n> > +\tdpsw_close(ethsw->mc_io, 0, ethsw->dpsw_handle);\n> > +\treturn err;\n> > +}\n> > +\n> > +static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port)\n> > +{\n> > +\tconst char def_mcast[ETH_ALEN] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0x01};\n> > +\tstruct net_device *netdev = port_priv->netdev;\n> > +\tstruct ethsw_core *ethsw = port_priv->ethsw_data;\n> > +\tstruct dpsw_tci_cfg tci_cfg = {0};\n> > +\tstruct dpsw_vlan_if_cfg vcfg;\n> > +\tint err;\n> > +\n> > +\t/* Switch starts with all ports configured to VLAN 1. Need to\n> > +\t * remove this setting to allow configuration at bridge join\n> > +\t */\n> > +\tvcfg.num_ifs = 1;\n> > +\tvcfg.if_id[0] = port_priv->idx;\n> > +\n> > +\terr = dpsw_vlan_remove_if_untagged(ethsw->mc_io, 0, ethsw-\n> >dpsw_handle,\n> > +\t\t\t\t\t   DEFAULT_VLAN_ID, &vcfg);\n> > +\tif (err) {\n> > +\t\tnetdev_err(netdev, \"dpsw_vlan_remove_if_untagged err\n> %d\\n\",\n> > +\t\t\t   err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\terr = dpsw_if_set_tci(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> > +\t\t\t      port_priv->idx, &tci_cfg);\n> > +\tif (err) {\n> > +\t\tnetdev_err(netdev, \"dpsw_if_set_tci err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\terr = dpsw_vlan_remove_if(ethsw->mc_io, 0, ethsw->dpsw_handle,\n> > +\t\t\t\t  DEFAULT_VLAN_ID, &vcfg);\n> > +\tif (err) {\n> > +\t\tnetdev_err(netdev, \"dpsw_vlan_remove_if err %d\\n\", err);\n> > +\t\treturn err;\n> > +\t}\n> > +\n> > +\terr = ethsw_port_fdb_add_mc(port_priv, def_mcast);\n> > +\n> > +\treturn err;\n> > +}\n> > +\n> > +static void ethsw_takedown(struct fsl_mc_device *sw_dev)\n> > +{\n> > +\tstruct device *dev = &sw_dev->dev;\n> > +\tstruct ethsw_core *ethsw = dev_get_drvdata(dev);\n> > +\tint err;\n> > +\n> > +\terr = unregister_switchdev_notifier(&port_switchdev_nb);\n> > +\tif (err)\n> > +\t\tdev_err(dev,\n> > +\t\t\t\"Failed to unregister switchdev notifier (%d)\\n\", err);\n> > +\n> > +\terr = unregister_netdevice_notifier(&port_nb);\n> > +\tif (err)\n> > +\t\tdev_err(dev,\n> > +\t\t\t\"Failed to unregister netdev notifier (%d)\\n\", err);\n> \n> Above 2 can be grouped into ethsw_unregister_notifier.\n> \n> > +\n> > +\terr = dpsw_close(ethsw->mc_io, 0, ethsw->dpsw_handle);\n> > +\tif (err)\n> > +\t\tdev_warn(dev, \"dpsw_close err %d\\n\", err);\n> > +}\n> > +\n> > +static int ethsw_remove(struct fsl_mc_device *sw_dev)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv;\n> > +\tstruct ethsw_core *ethsw;\n> > +\tstruct device *dev;\n> > +\tint i;\n> > +\n> > +\tdev = &sw_dev->dev;\n> > +\tethsw = dev_get_drvdata(dev);\n> > +\n> > +\tethsw_teardown_irqs(sw_dev);\n> > +\n> > +\trtnl_lock();\n> > +\tethsw_stop(ethsw);\n> > +\trtnl_unlock();\n> > +\n> > +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> > +\t\tport_priv = ethsw->ports[i];\n> > +\t\tunregister_netdev(port_priv->netdev);\n> > +\t\tfree_netdev(port_priv->netdev);\n> > +\t}\n> > +\tkfree(ethsw->ports);\n> > +\n> > +\tethsw_takedown(sw_dev);\n> > +\tfsl_mc_portal_free(ethsw->mc_io);\n> > +\n> > +\tkfree(ethsw);\n> > +\n> > +\tdev_set_drvdata(dev, NULL);\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int ethsw_probe_port(struct ethsw_core *ethsw, u16 port_idx)\n> > +{\n> > +\tstruct ethsw_port_priv *port_priv;\n> > +\tstruct device *dev = ethsw->dev;\n> > +\tstruct net_device *port_netdev;\n> > +\tint err;\n> > +\n> > +\tport_netdev = alloc_etherdev(sizeof(struct ethsw_port_priv));\n> > +\tif (!port_netdev) {\n> > +\t\tdev_err(dev, \"alloc_etherdev error\\n\");\n> > +\t\treturn -ENOMEM;\n> > +\t}\n> > +\n> > +\tport_priv = netdev_priv(port_netdev);\n> > +\tport_priv->netdev = port_netdev;\n> > +\tport_priv->ethsw_data = ethsw;\n> > +\n> > +\tport_priv->idx = port_idx;\n> > +\tport_priv->stp_state = BR_STATE_FORWARDING;\n> > +\n> > +\t/* Flooding is implicitly enabled */\n> > +\tport_priv->flood = true;\n> > +\n> > +\tSET_NETDEV_DEV(port_netdev, dev);\n> > +\tport_netdev->netdev_ops = &ethsw_port_ops;\n> > +\tport_netdev->switchdev_ops = &ethsw_port_switchdev_ops;\n> > +\n> > +\t/* Set MTU limits */\n> > +\tport_netdev->min_mtu = ETH_MIN_MTU;\n> > +\tport_netdev->max_mtu = ETHSW_MAX_FRAME_LENGTH;\n> > +\n> > +\terr = register_netdev(port_netdev);\n> > +\tif (err < 0) {\n> > +\t\tdev_err(dev, \"register_netdev error %d\\n\", err);\n> > +\t\t\tfree_netdev(port_netdev);\n> > +\t\t\treturn err;\n> > +\t\t}\n> > +\n> > +\tethsw->ports[port_idx] = port_priv;\n> > +\n> > +\treturn ethsw_port_init(port_priv, port_idx);\n> > +}\n> > +\n> > +static int ethsw_probe(struct fsl_mc_device *sw_dev)\n> > +{\n> > +\tstruct device *dev = &sw_dev->dev;\n> > +\tstruct ethsw_core *ethsw;\n> > +\tint err;\n> > +\tu16 i, j;\n> > +\n> > +\t/* Allocate switch core*/\n> > +\tethsw = kzalloc(sizeof(*ethsw), GFP_KERNEL);\n> > +\n> > +\tif (!ethsw)\n> > +\t\treturn -ENOMEM;\n> > +\n> > +\tethsw->dev = dev;\n> > +\tdev_set_drvdata(dev, ethsw);\n> > +\n> > +\terr = fsl_mc_portal_allocate(sw_dev, 0, &ethsw->mc_io);\n> > +\tif (err) {\n> > +\t\tdev_err(dev, \"fsl_mc_portal_allocate err %d\\n\", err);\n> > +\t\tgoto err_free_drvdata;\n> > +\t}\n> > +\n> > +\terr = ethsw_init(sw_dev);\n> > +\tif (err)\n> > +\t\tgoto err_free_cmdport;\n> > +\n> > +\t/* DEFAULT_VLAN_ID is implicitly configured on the switch */\n> > +\tethsw->vlans[DEFAULT_VLAN_ID] = ETHSW_VLAN_MEMBER;\n> > +\n> > +\t/* Learning is implicitly enabled */\n> > +\tethsw->learning = true;\n> > +\n> > +\tethsw->ports = kcalloc(ethsw->sw_attr.num_ifs, sizeof(*ethsw->ports),\n> > +\t\t\t       GFP_KERNEL);\n> > +\tif (!(ethsw->ports)) {\n> > +\t\terr = -ENOMEM;\n> > +\t\tgoto err_takedown;\n> > +\t}\n> > +\n> > +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> > +\t\terr = ethsw_probe_port(ethsw, i);\n> > +\t\tif (err) {\n> > +\t\t\t/* Cleanup previous ports only */\n> > +\t\t\tfor (j = 0; j < i; j++) {\n> \n> I think you can go with\n> for (i--; i >= 0; i--)\n> \n> or better yet:\n> goto err_free_ports\n> and refactor err_free_ports to look like:\n> for (i--; i >= 0; i--) {\n> ...\n> }\n> \n> Best regards,\n> Bogdan P.\n> \n> > +\t\t\t\tunregister_netdev(ethsw->ports[j]->netdev);\n> > +\t\t\t\tfree_netdev(ethsw->ports[j]->netdev);\n> > +\t\t\t}\n> > +\t\t\tgoto err_takedown;\n> > +\t\t}\n> > +\t}\n> > +\n> > +\t/* Switch starts up enabled */\n> > +\trtnl_lock();\n> > +\terr = ethsw_open(ethsw);\n> > +\trtnl_unlock();\n> > +\tif (err)\n> > +\t\tgoto err_free_ports;\n> > +\n> > +\t/* Setup IRQs */\n> > +\terr = ethsw_setup_irqs(sw_dev);\n> > +\tif (err)\n> > +\t\tgoto err_stop;\n> > +\n> > +\tdev_info(dev, \"probed %d port switch\\n\", ethsw->sw_attr.num_ifs);\n> > +\treturn 0;\n> > +\n> > +err_stop:\n> > +\trtnl_lock();\n> > +\tethsw_stop(ethsw);\n> > +\trtnl_unlock();\n> > +\n> > +err_free_ports:\n> > +\tfor (i = 0; i < ethsw->sw_attr.num_ifs; i++) {\n> > +\t\tunregister_netdev(ethsw->ports[i]->netdev);\n> > +\t\tfree_netdev(ethsw->ports[i]->netdev);\n> > +\t}\n> > +\tkfree(ethsw->ports);\n> > +\n> > +err_takedown:\n> > +\tethsw_takedown(sw_dev);\n> > +\n> > +err_free_cmdport:\n> > +\tfsl_mc_portal_free(ethsw->mc_io);\n> > +\n> > +err_free_drvdata:\n> > +\tkfree(ethsw);\n> > +\tdev_set_drvdata(dev, NULL);\n> > +\n> > +\treturn err;\n> > +}\n> > +\n> > +static const struct fsl_mc_device_id ethsw_match_id_table[] = {\n> > +\t{\n> > +\t\t.vendor = FSL_MC_VENDOR_FREESCALE,\n> > +\t\t.obj_type = \"dpsw\",\n> > +\t},\n> > +\t{ .vendor = 0x0 }\n> > +};\n> > +MODULE_DEVICE_TABLE(fslmc, ethsw_match_id_table);\n> > +\n> > +static struct fsl_mc_driver eth_sw_drv = {\n> > +\t.driver = {\n> > +\t\t.name = KBUILD_MODNAME,\n> > +\t\t.owner = THIS_MODULE,\n> > +\t},\n> > +\t.probe = ethsw_probe,\n> > +\t.remove = ethsw_remove,\n> > +\t.match_id_table = ethsw_match_id_table\n> > +};\n> > +\n> > +module_fsl_mc_driver(eth_sw_drv);\n> > +\n> > +MODULE_LICENSE(\"Dual BSD/GPL\");\n> > +MODULE_DESCRIPTION(\"DPAA2 Ethernet Switch Driver\");\n> > diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h b/drivers/staging/fsl-\n> > dpaa2/ethsw/ethsw.h\n> > new file mode 100644\n> > index 0000000..8c1d645\n> > --- /dev/null\n> > +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h\n> > @@ -0,0 +1,88 @@\n> > +/* Copyright 2014-2017 Freescale Semiconductor Inc.\n> > + * Copyright 2017 NXP\n> > + *\n> > + * Redistribution and use in source and binary forms, with or without\n> > + * modification, are permitted provided that the following conditions are met:\n> > + *     * Redistributions of source code must retain the above copyright\n> > + *\t notice, this list of conditions and the following disclaimer.\n> > + *     * Redistributions in binary form must reproduce the above copyright\n> > + *\t notice, this list of conditions and the following disclaimer in the\n> > + *\t documentation and/or other materials provided with the distribution.\n> > + *     * Neither the name of the above-listed copyright holders nor the\n> > + *\t names of any contributors may be used to endorse or promote products\n> > + *\t derived from this software without specific prior written permission.\n> > + *\n> > + *\n> > + * ALTERNATIVELY, this software may be distributed under the terms of the\n> > + * GNU General Public License (\"GPL\") as published by the Free Software\n> > + * Foundation, either version 2 of that License or (at your option) any\n> > + * later version.\n> > + *\n> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n> CONTRIBUTORS \"AS IS\"\n> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n> LIMITED TO, THE\n> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n> PARTICULAR PURPOSE\n> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR\n> CONTRIBUTORS BE\n> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n> PROCUREMENT OF\n> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n> BUSINESS\n> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n> WHETHER IN\n> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n> OTHERWISE)\n> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n> ADVISED OF THE\n> > + * POSSIBILITY OF SUCH DAMAGE.\n> > + */\n> > +\n> > +#ifndef __ETHSW_H\n> > +#define __ETHSW_H\n> > +\n> > +#include <linux/netdevice.h>\n> > +#include <linux/etherdevice.h>\n> > +#include <linux/rtnetlink.h>\n> > +#include <linux/if_vlan.h>\n> > +#include <uapi/linux/if_bridge.h>\n> > +#include <net/switchdev.h>\n> > +#include <linux/if_bridge.h>\n> > +\n> > +#include \"dpsw.h\"\n> > +\n> > +/* Number of IRQs supported */\n> > +#define DPSW_IRQ_NUM\t2\n> > +\n> > +#define ETHSW_VLAN_MEMBER\t1\n> > +#define ETHSW_VLAN_UNTAGGED\t2\n> > +#define ETHSW_VLAN_PVID\t\t4\n> > +#define ETHSW_VLAN_GLOBAL\t8\n> > +\n> > +/* Maximum Frame Length supported by HW (currently 10k) */\n> > +#define DPAA2_MFL\t\t(10 * 1024)\n> > +#define ETHSW_MAX_FRAME_LENGTH\t(DPAA2_MFL - VLAN_ETH_HLEN -\n> ETH_FCS_LEN)\n> > +#define ETHSW_L2_MAX_FRM(mtu)\t((mtu) + VLAN_ETH_HLEN +\n> ETH_FCS_LEN)\n> > +\n> > +struct ethsw_core;\n> > +\n> > +/* Per port private data */\n> > +struct ethsw_port_priv {\n> > +\tstruct net_device\t*netdev;\n> > +\tu16\t\t\tidx;\n> > +\tstruct ethsw_core\t*ethsw_data;\n> > +\tu8\t\t\tlink_state;\n> > +\tu8\t\t\tstp_state;\n> > +\tbool\t\t\tflood;\n> > +\n> > +\tu8\t\t\tvlans[VLAN_VID_MASK + 1];\n> > +\tu16\t\t\tpvid;\n> > +};\n> > +\n> > +/* Switch data */\n> > +struct ethsw_core {\n> > +\tstruct device\t\t\t*dev;\n> > +\tstruct fsl_mc_io\t\t*mc_io;\n> > +\tu16\t\t\t\tdpsw_handle;\n> > +\tstruct dpsw_attr\t\tsw_attr;\n> > +\tint\t\t\t\tdev_id;\n> > +\tstruct ethsw_port_priv\t\t**ports;\n> > +\n> > +\tu8\t\t\t\tvlans[VLAN_VID_MASK + 1];\n> > +\tbool\t\t\t\tlearning;\n> > +};\n> > +\n> > +#endif\t/* __ETHSW_H */\n> > --\n> > 1.9.1","headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"U9Opc15N\";\n\tdkim-atps=neutral","spf=none (sender IP is )\n\tsmtp.mailfrom=razvan.stefanescu@nxp.com; "],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3y3Y8T4nK2z9t4g\n\tfor <patchwork-incoming@ozlabs.org>;\n\tFri, 29 Sep 2017 23:59:37 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752008AbdI2N7Z (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tFri, 29 Sep 2017 09:59:25 -0400","from mail-ve1eur01on0057.outbound.protection.outlook.com\n\t([104.47.1.57]:1472\n\t\"EHLO EUR01-VE1-obe.outbound.protection.outlook.com\"\n\trhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP\n\tid S1751667AbdI2N7X (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tFri, 29 Sep 2017 09:59:23 -0400","from AM3PR04MB0743.eurprd04.prod.outlook.com (10.160.5.23) by\n\tAM3PR04MB1234.eurprd04.prod.outlook.com (10.163.6.155) with Microsoft\n\tSMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id\n\t15.20.77.7; Fri, 29 Sep 2017 13:59:20 +0000","from AM3PR04MB0743.eurprd04.prod.outlook.com\n\t([fe80::581c:6f9f:d8a9:26f9]) by\n\tAM3PR04MB0743.eurprd04.prod.outlook.com\n\t([fe80::581c:6f9f:d8a9:26f9%14]) with mapi id 15.20.0077.016;\n\tFri, 29 Sep 2017 13:59:19 +0000"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version;\n\tbh=BRNJahcLHx+NXibo/S+YO8K0ECdg7Tg4PHTOyN4OqvE=;\n\tb=U9Opc15NRgUsqraiENaO8QDrBtr1LDwi3aXhqqP3hpSCQllGmy3a74EY7ncot6CsSAjdpLiDdfaXX8mA3eIOSg6lKVlnY7eRoCgxeLQCUOtF+bEV9sSZau5DQZ0vyGdaro3v5KpInHEcWpVWrqXHVjihWc8toS6oNHtTQRxxalg=","From":"Razvan Stefanescu <razvan.stefanescu@nxp.com>","To":"Bogdan Purcareata <bogdan.purcareata@nxp.com>,\n\t\"gregkh@linuxfoundation.org\" <gregkh@linuxfoundation.org>","CC":"\"devel@driverdev.osuosl.org\" <devel@driverdev.osuosl.org>,\n\t\"linux-kernel@vger.kernel.org\" <linux-kernel@vger.kernel.org>,\n\t\"netdev@vger.kernel.org\" <netdev@vger.kernel.org>,\n\t\"agraf@suse.de\" <agraf@suse.de>, \"arnd@arndb.de\" <arnd@arndb.de>,\n\tAlexandru Marginean <alexandru.marginean@nxp.com>,\n\tRuxandra Ioana Radulescu <ruxandra.radulescu@nxp.com>,\n\tLaurentiu Tudor <laurentiu.tudor@nxp.com>,\n\t\"stuyoder@gmail.com\" <stuyoder@gmail.com>","Subject":"RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale DPAA2\n\tEthernet Switch driver","Thread-Topic":"[RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale\n\tDPAA2 Ethernet Switch driver","Thread-Index":"AQHTOSfmpZmz5yI+sE2MGlZW7Vq6j6LL4dEg","Date":"Fri, 29 Sep 2017 13:59:18 +0000","Message-ID":"<AM3PR04MB0743F62497ED0CB445F51524E67E0@AM3PR04MB0743.eurprd04.prod.outlook.com>","References":"<1505825158-8192-1-git-send-email-razvan.stefanescu@nxp.com>\n\t<1505825158-8192-3-git-send-email-razvan.stefanescu@nxp.com>\n\t<DB5PR04MB12400025DF190790B4792B50EA7E0@DB5PR04MB1240.eurprd04.prod.outlook.com>","In-Reply-To":"<DB5PR04MB12400025DF190790B4792B50EA7E0@DB5PR04MB1240.eurprd04.prod.outlook.com>","Accept-Language":"en-US","Content-Language":"en-US","X-MS-Has-Attach":"","X-MS-TNEF-Correlator":"","authentication-results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"U9Opc15N\";\n\tdkim-atps=neutral","spf=none (sender IP is )\n\tsmtp.mailfrom=razvan.stefanescu@nxp.com; "],"x-originating-ip":"[192.88.146.1]","x-ms-publictraffictype":"Email","x-microsoft-exchange-diagnostics":"1; AM3PR04MB1234;\n\t6:Q11I/0vlXGmhD0197fE3t/2DeILez1+6d8xFH732X0GE91ZLgEPBkukvGCMHL1fWrDdae+VvOnh7kUhQtkOnkudRo6snJ9T4d8+Fr4Fi2uvz0vOaoQ9/vvO4wq/C7cz+Y5YoRruEXtKB4u7V6ECLn0vo1a41MS2xPq+lxkq2uBLECNy5YTyqyFq6KcaejW3CsA1TAF/Ra6BXu9xiKkyI7eobkC3mLWEfhRGvIPaALvxHVg0p045+pFGmrCaunncbti4PwySjWpSDdM9Od1RlMPLpehKKQ4jS7+oUHVo13craaEIAyeeVUrRaMXRBMnM2d/owY3vrVqv8N+SCAeTxnA==;\n\t5:Vet0NzkmnysySh3gbOayWjkRIS3Mz07115Kjdfg/81CeN2YBud/wrSX/0ulrox0c+OrlO8EKUC+XPvdzgDjv0asH0xhARiGeaR6Qx4pAV3240nT4TgmWWUWxmcY4TyRKyjK5c3yrvqdZeLVrKOPFbQ==;\n\t24:ABn1fRt3iOSuouaGHbB5FhbDf4b+YjEG5Mq8uQa9wNM19G5OvfBGGe3zIM3HWLrGqjJIKWzz0Ato4/t5WEWXcia0STTgqUuH37yTkzSYoHU=;\n\t7:4iMy1HH2Xj8c2sRSQ+GuCZtreBzVdnBC9Xzwn/qFjw4vl/z2DkW2oSWFJjwSxqRf0u2nBoqEnHYL7B5WK2o5Y1J/rkm6WOfGPuHdxeFQSMZJzeiau2JSugj6eIWgFgh7cs1LErtaCZFe68gNAayboB3op9wE0AkLZjk7NJ0jrM+8I9yjeid6AHx9aIJ3Hbd8JqTQAF4UvpI6HlN0X3/AzsL6MQoaz1qIdhHxWSCKf3I=","x-ms-exchange-antispam-srfa-diagnostics":"SSOS;SSOR;","x-forefront-antispam-report":"SFV:SKI; SCL:-1; SFV:NSPM;\n\tSFS:(10009020)(6009001)(346002)(39860400002)(376002)(13464003)(199003)(189002)(51234002)(81156014)(9686003)(3280700002)(101416001)(54356999)(7736002)(50986999)(66066001)(3660700001)(2501003)(97736004)(6506006)(189998001)(25786009)(5250100002)(76176999)(68736007)(6436002)(105586002)(74316002)(33656002)(345774005)(5660300001)(106356001)(81166006)(86362001)(7696004)(305945005)(53546010)(6116002)(3846002)(102836003)(8676002)(229853002)(478600001)(316002)(99286003)(53936002)(4326008)(2906002)(2950100002)(54906003)(110136005)(16200700003)(14454004)(55016002)(39060400002)(8936002)(2900100001)(53946003)(6246003)(2004002)(217873001)(559001)(579004)(569006);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM3PR04MB1234;\n\tH:AM3PR04MB0743.eurprd04.prod.outlook.com; FPR:; SPF:None;\n\tPTR:InfoNoRecords; A:1; MX:1; LANG:en; ","x-ms-office365-filtering-correlation-id":"66f78c3a-3e43-49d9-9979-08d50742476f","x-ms-office365-filtering-ht":"Tenant","x-microsoft-antispam":"UriScan:; BCL:0; PCL:0;\n\tRULEID:(22001)(2017030254152)(48565401081)(2017052603199)(201703131423075)(201703031133081)(201702281549075);\n\tSRVR:AM3PR04MB1234; ","x-ms-traffictypediagnostic":"AM3PR04MB1234:","x-exchange-antispam-report-test":"UriScan:(9452136761055)(185117386973197);","x-microsoft-antispam-prvs":"<AM3PR04MB12345B92DF372131EED3412DE67E0@AM3PR04MB1234.eurprd04.prod.outlook.com>","x-exchange-antispam-report-cfa-test":"BCL:0; PCL:0;\n\tRULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(3002001)(10201501046)(93006095)(93001095)(100000703101)(100105400095)(6055026)(6041248)(20161123564025)(20161123555025)(20161123562025)(20161123558100)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);\n\tSRVR:AM3PR04MB1234; BCL:0; PCL:0;\n\tRULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);\n\tSRVR:AM3PR04MB1234; ","x-forefront-prvs":"0445A82F82","received-spf":"None (protection.outlook.com: nxp.com does not designate\n\tpermitted sender hosts)","spamdiagnosticoutput":"1:99","spamdiagnosticmetadata":"NSPM","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"quoted-printable","MIME-Version":"1.0","X-OriginatorOrg":"nxp.com","X-MS-Exchange-CrossTenant-originalarrivaltime":"29 Sep 2017 13:59:18.8181\n\t(UTC)","X-MS-Exchange-CrossTenant-fromentityheader":"Hosted","X-MS-Exchange-CrossTenant-id":"686ea1d3-bc2b-4c6f-a92c-d99c5c301635","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"AM3PR04MB1234","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"}},{"id":1777620,"web_url":"http://patchwork.ozlabs.org/comment/1777620/","msgid":"<A4C4732A-CC1F-4707-89F8-E7284F022DB0@gmail.com>","list_archive_url":null,"date":"2017-09-29T16:11:18","subject":"RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale\n\tDPAA2 Ethernet Switch driver","submitter":{"id":2800,"url":"http://patchwork.ozlabs.org/api/people/2800/","name":"Florian Fainelli","email":"f.fainelli@gmail.com"},"content":"On September 29, 2017 6:59:18 AM PDT, Razvan Stefanescu <razvan.stefanescu@nxp.com> wrote:\n>\n>\n>> -----Original Message-----\n>> From: Bogdan Purcareata\n>> Sent: Friday, September 29, 2017 16:36\n>> To: Razvan Stefanescu <razvan.stefanescu@nxp.com>;\n>> gregkh@linuxfoundation.org\n>> Cc: devel@driverdev.osuosl.org; linux-kernel@vger.kernel.org;\n>> netdev@vger.kernel.org; agraf@suse.de; arnd@arndb.de; Alexandru\n>Marginean\n>> <alexandru.marginean@nxp.com>; Ruxandra Ioana Radulescu\n>> <ruxandra.radulescu@nxp.com>; Laurentiu Tudor\n><laurentiu.tudor@nxp.com>;\n>> stuyoder@gmail.com\n>> Subject: RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add\n>Freescale DPAA2\n>> Ethernet Switch driver\n>> \n>> > Introduce the DPAA2 Ethernet Switch driver, which manages Datapath\n>Switch\n>> > (DPSW) objects discovered on the MC bus.\n>> >\n>> > Suggested-by: Alexandru Marginean <alexandru.marginean@nxp.com>\n>> > Signed-off-by: Razvan Stefanescu <razvan.stefanescu@nxp.com>\n\nThis looks pretty good for a new switchdev driver, is there a reason you can't target drivers/net/ethernet instead of staging? Is it because the MC bus code is still in staging (AFAICT)?","headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"bBYetvgK\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3y3c4q47YNz9t44\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSat, 30 Sep 2017 02:11:39 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752212AbdI2QL0 (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tFri, 29 Sep 2017 12:11:26 -0400","from mail-oi0-f44.google.com ([209.85.218.44]:43449 \"EHLO\n\tmail-oi0-f44.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751828AbdI2QLZ (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Fri, 29 Sep 2017 12:11:25 -0400","by mail-oi0-f44.google.com with SMTP id r20so208757oie.0;\n\tFri, 29 Sep 2017 09:11:25 -0700 (PDT)","from ?IPv6:2001:470:d:73f:a9ad:600c:a588:fd61?\n\t([2001:470:d:73f:a9ad:600c:a588:fd61])\n\tby smtp.gmail.com with ESMTPSA id\n\ti9sm2080969oth.56.2017.09.29.09.11.21\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tFri, 29 Sep 2017 09:11:22 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=gmail.com; s=20161025;\n\th=date:user-agent:in-reply-to:references:mime-version\n\t:content-transfer-encoding:subject:to:cc:from:message-id;\n\tbh=FXTm0gTqUDSJKVtMU3qghORMHDi9vmKQ3m/B9NUSjVg=;\n\tb=bBYetvgKwsRFDH5pRbnRd+qR9ZDAdAG1KNVk9krvrcJVHw44mwuO3KmVOvBXdiUdnF\n\tsFTNfb/hX2XlvgQx1rMp7HVNg2KEC9itbfA8lz5MlhL5pZJ0s3flbDm04GvyhTvP5e8C\n\t+6OII+g3qRvdcOkDmdHlD/SYttcKGNnVzmy4gq9Ig32eMfoyUsMcs3VZPXU5BctXFwST\n\tKg3Bnas9YbuBtLzfgw121WpKGXEtfF9fkRZgJwJNegH4J3gmhFYhXrZPrk9IayUQvjxV\n\trXde26GMkmMtGC9+X5nY3s27zJA4TbuIlMylS79ibizgIR02I3yR6L1SDYzx2QhvN9JC\n\tWbkA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:user-agent:in-reply-to:references\n\t:mime-version:content-transfer-encoding:subject:to:cc:from\n\t:message-id;\n\tbh=FXTm0gTqUDSJKVtMU3qghORMHDi9vmKQ3m/B9NUSjVg=;\n\tb=SJjGm4KvbrijMRJOfYc9zWXtgK8JmcNxClil8Eikiex1zqHwEgcnf4VDOSXjHLceHU\n\tByLGmAYhhMt9hblE6Zxbw81fAq+cakec1l6yb4F+jLgcDO8dZGnuaWgMVrTfgFaG/T1l\n\t2/TezhEaHIgrlS457ysPbk97dYNWpZzBUHKKJJAU5EJACn5hmEV4KdUcj+KLNzrG6S/5\n\t2Bv0svZHV0zUJWrigQdTVGNe4XAQDNrdoBArEvROz6FPw+axv+wFcxs0rBBYAIHyMy7o\n\tbH2TkzJp84ncSYqhXiju7XaPp9WS0nEqreeAbRQ5fIznNYdxb9TJ+I0/5sIC0eVkSYYg\n\t+PCQ==","X-Gm-Message-State":"AMCzsaW6l1OoRVGGsS9+WrpoJl25gQ0JLNTKiku0ZntnqqcjAFKNS4WV\n\tq6Ifgv9CTKHPyHcuiszKfCE=","X-Google-Smtp-Source":"AOwi7QBJX4OkNQ9w8R5Oszf5l7mYZ4rS+4+ucutIUZg4GYHWDh8+9fp557tTxtxRnUx+XsMN0sJmlw==","X-Received":"by 10.202.236.76 with SMTP id k73mr2442146oih.349.1506701484522; \n\tFri, 29 Sep 2017 09:11:24 -0700 (PDT)","Date":"Fri, 29 Sep 2017 09:11:18 -0700","User-Agent":"K-9 Mail for Android","In-Reply-To":"<AM3PR04MB0743F62497ED0CB445F51524E67E0@AM3PR04MB0743.eurprd04.prod.outlook.com>","References":"<1505825158-8192-1-git-send-email-razvan.stefanescu@nxp.com>\n\t<1505825158-8192-3-git-send-email-razvan.stefanescu@nxp.com>\n\t<DB5PR04MB12400025DF190790B4792B50EA7E0@DB5PR04MB1240.eurprd04.prod.outlook.com>\n\t<AM3PR04MB0743F62497ED0CB445F51524E67E0@AM3PR04MB0743.eurprd04.prod.outlook.com>","MIME-Version":"1.0","Content-Type":"text/plain;\n charset=utf-8","Content-Transfer-Encoding":"quoted-printable","Subject":"RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale\n\tDPAA2 Ethernet Switch driver","To":"Razvan Stefanescu <razvan.stefanescu@nxp.com>,\n\tBogdan Purcareata <bogdan.purcareata@nxp.com>,\n\t\"gregkh@linuxfoundation.org\" <gregkh@linuxfoundation.org>","CC":"\"devel@driverdev.osuosl.org\" <devel@driverdev.osuosl.org>,\n\t\"linux-kernel@vger.kernel.org\" <linux-kernel@vger.kernel.org>,\n\t\"netdev@vger.kernel.org\" <netdev@vger.kernel.org>,\n\t\"agraf@suse.de\" <agraf@suse.de>, \"arnd@arndb.de\" <arnd@arndb.de>,\n\tAlexandru Marginean <alexandru.marginean@nxp.com>,\n\tRuxandra Ioana Radulescu <ruxandra.radulescu@nxp.com>,\n\tLaurentiu Tudor <laurentiu.tudor@nxp.com>,\n\t\"stuyoder@gmail.com\" <stuyoder@gmail.com>","From":"Florian Fainelli <f.fainelli@gmail.com>","Message-ID":"<A4C4732A-CC1F-4707-89F8-E7284F022DB0@gmail.com>","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"}},{"id":1778178,"web_url":"http://patchwork.ozlabs.org/comment/1778178/","msgid":"<AM3PR04MB0743CC52EC71DC2BC7D0C2BEE67D0@AM3PR04MB0743.eurprd04.prod.outlook.com>","list_archive_url":null,"date":"2017-10-02T07:18:52","subject":"RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale DPAA2\n\tEthernet Switch driver","submitter":{"id":72391,"url":"http://patchwork.ozlabs.org/api/people/72391/","name":"Razvan Stefanescu","email":"razvan.stefanescu@nxp.com"},"content":"> -----Original Message-----\r\n> From: Florian Fainelli [mailto:f.fainelli@gmail.com]\r\n> Sent: Friday, September 29, 2017 19:11\r\n> To: Razvan Stefanescu <razvan.stefanescu@nxp.com>; Bogdan Purcareata\r\n> <bogdan.purcareata@nxp.com>; gregkh@linuxfoundation.org\r\n> Cc: devel@driverdev.osuosl.org; linux-kernel@vger.kernel.org;\r\n> netdev@vger.kernel.org; agraf@suse.de; arnd@arndb.de; Alexandru Marginean\r\n> <alexandru.marginean@nxp.com>; Ruxandra Ioana Radulescu\r\n> <ruxandra.radulescu@nxp.com>; Laurentiu Tudor <laurentiu.tudor@nxp.com>;\r\n> stuyoder@gmail.com\r\n> Subject: RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale DPAA2\r\n> Ethernet Switch driver\r\n> \r\n> On September 29, 2017 6:59:18 AM PDT, Razvan Stefanescu\r\n> <razvan.stefanescu@nxp.com> wrote:\r\n> >\r\n> >\r\n> >> -----Original Message-----\r\n> >> From: Bogdan Purcareata\r\n> >> Sent: Friday, September 29, 2017 16:36\r\n> >> To: Razvan Stefanescu <razvan.stefanescu@nxp.com>;\r\n> >> gregkh@linuxfoundation.org\r\n> >> Cc: devel@driverdev.osuosl.org; linux-kernel@vger.kernel.org;\r\n> >> netdev@vger.kernel.org; agraf@suse.de; arnd@arndb.de; Alexandru\r\n> >Marginean\r\n> >> <alexandru.marginean@nxp.com>; Ruxandra Ioana Radulescu\r\n> >> <ruxandra.radulescu@nxp.com>; Laurentiu Tudor\r\n> ><laurentiu.tudor@nxp.com>;\r\n> >> stuyoder@gmail.com\r\n> >> Subject: RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add\r\n> >Freescale DPAA2\r\n> >> Ethernet Switch driver\r\n> >>\r\n> >> > Introduce the DPAA2 Ethernet Switch driver, which manages Datapath\r\n> >Switch\r\n> >> > (DPSW) objects discovered on the MC bus.\r\n> >> >\r\n> >> > Suggested-by: Alexandru Marginean <alexandru.marginean@nxp.com>\r\n> >> > Signed-off-by: Razvan Stefanescu <razvan.stefanescu@nxp.com>\r\n> \r\n> This looks pretty good for a new switchdev driver, is there a reason you can't\r\n> target drivers/net/ethernet instead of staging? Is it because the MC bus code is\r\n> still in staging (AFAICT)?\r\n> \r\nYes, driver depends on MC bus, which is still in staging.  Also, control traffic\r\ncode will require access to DPIO functions, that are also in staging.\r\n\r\nBest regards,\r\nRazvan S.\r\n> --\r\n> Florian","headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"PJUWZM6/\";\n\tdkim-atps=neutral","spf=none (sender IP is )\n\tsmtp.mailfrom=razvan.stefanescu@nxp.com; "],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3y5D752N8Cz9sPs\n\tfor <patchwork-incoming@ozlabs.org>;\n\tMon,  2 Oct 2017 18:19:13 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1750903AbdJBHS6 (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 2 Oct 2017 03:18:58 -0400","from mail-ve1eur01on0060.outbound.protection.outlook.com\n\t([104.47.1.60]:48768\n\t\"EHLO EUR01-VE1-obe.outbound.protection.outlook.com\"\n\trhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP\n\tid S1750770AbdJBHS4 (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tMon, 2 Oct 2017 03:18:56 -0400","from AM3PR04MB0743.eurprd04.prod.outlook.com (10.160.5.23) by\n\tAM3PR04MB1234.eurprd04.prod.outlook.com (10.163.6.155) with Microsoft\n\tSMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id\n\t15.20.77.7; Mon, 2 Oct 2017 07:18:53 +0000","from AM3PR04MB0743.eurprd04.prod.outlook.com\n\t([fe80::581c:6f9f:d8a9:26f9]) by\n\tAM3PR04MB0743.eurprd04.prod.outlook.com\n\t([fe80::581c:6f9f:d8a9:26f9%14]) with mapi id 15.20.0077.018;\n\tMon, 2 Oct 2017 07:18:52 +0000"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version;\n\tbh=II+EXyQuZUanutS8mLznzCDMgJL6ZgVdrgozPA6CqA8=;\n\tb=PJUWZM6/EdVfu0YQniz42I1/soracK2YnzBppQuXCg1yXZvzZAp64GM7pCeOHOaVaho55vEHcrVzkjGpSuP4Q1hs6zf6RpOHW+g6wSA30RCDEQ7bQScVzPnoPFIZb4gW+mZ2Q/J5+eLitsnGE9pT2JWxHKZ6eN4C8wVZ5Rh0Q6o=","From":"Razvan Stefanescu <razvan.stefanescu@nxp.com>","To":"Florian Fainelli <f.fainelli@gmail.com>,\n\tBogdan Purcareata <bogdan.purcareata@nxp.com>,\n\t\"gregkh@linuxfoundation.org\" <gregkh@linuxfoundation.org>","CC":"\"devel@driverdev.osuosl.org\" <devel@driverdev.osuosl.org>,\n\t\"linux-kernel@vger.kernel.org\" <linux-kernel@vger.kernel.org>,\n\t\"netdev@vger.kernel.org\" <netdev@vger.kernel.org>,\n\t\"agraf@suse.de\" <agraf@suse.de>, \"arnd@arndb.de\" <arnd@arndb.de>,\n\tAlexandru Marginean <alexandru.marginean@nxp.com>,\n\tRuxandra Ioana Radulescu <ruxandra.radulescu@nxp.com>,\n\tLaurentiu Tudor <laurentiu.tudor@nxp.com>,\n\t\"stuyoder@gmail.com\" <stuyoder@gmail.com>","Subject":"RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale DPAA2\n\tEthernet Switch driver","Thread-Topic":"[RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale\n\tDPAA2 Ethernet Switch driver","Thread-Index":"AQHTOSfmpZmz5yI+sE2MGlZW7Vq6j6LL4dEggAAnCQCABAcM4A==","Date":"Mon, 2 Oct 2017 07:18:52 +0000","Message-ID":"<AM3PR04MB0743CC52EC71DC2BC7D0C2BEE67D0@AM3PR04MB0743.eurprd04.prod.outlook.com>","References":"<1505825158-8192-1-git-send-email-razvan.stefanescu@nxp.com>\n\t<1505825158-8192-3-git-send-email-razvan.stefanescu@nxp.com>\n\t<DB5PR04MB12400025DF190790B4792B50EA7E0@DB5PR04MB1240.eurprd04.prod.outlook.com>\n\t<AM3PR04MB0743F62497ED0CB445F51524E67E0@AM3PR04MB0743.eurprd04.prod.outlook.com>\n\t<A4C4732A-CC1F-4707-89F8-E7284F022DB0@gmail.com>","In-Reply-To":"<A4C4732A-CC1F-4707-89F8-E7284F022DB0@gmail.com>","Accept-Language":"en-US","Content-Language":"en-US","X-MS-Has-Attach":"","X-MS-TNEF-Correlator":"","authentication-results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"PJUWZM6/\";\n\tdkim-atps=neutral","spf=none (sender IP is )\n\tsmtp.mailfrom=razvan.stefanescu@nxp.com; "],"x-originating-ip":"[192.88.146.1]","x-ms-publictraffictype":"Email","x-microsoft-exchange-diagnostics":"1; AM3PR04MB1234;\n\t6:V90AOEa5W8tGd/HThE/zGFNgEx5cL+oyu67bKBX8/+Uhx56fzUap+MnDdLbxoEKP4pXg/k5i/TrhBWV8zNdgF9U1nqwJOOr5CM+mxwjk3W1oYf5aEYqFLzuVGIJXcUGJSNmnYchtuKsZ/tdQxlR6LrgbUPjPY7U9fE1DQJCsqtMb5OzYkj6fvWMYcP6qh+nACcnQ1hLlaopdvExzWbvZb03X5V2I9wAVUE3Jn6jRFZWP24zeryKCQeE54N5XXjN0PFpCBne3CQJtuUUboYlW7kjmWK8Fgx7SVyQAoC0JDb+7jbA/2hxgaAFPjg8zCsPKZSLSZqxe3m32fQWjrQcHAg==;\n\t5:7Bp0tlRbcONOtAIM01bQsbxcXnYRKyqFLZtdCQ+aIrSfARxzkBxMKHqIQz4KmGN+9hIDoc0Qt7FaWxRDeuOOhmY0tTsXAsCnd1iwj6LMLOLDouC8EaxNORz3jK4FCkfAnK0ycq3PCgI+qifOeWCh8Q==;\n\t24:FHYxsyjGplXDlVIw8UTjSlt6PDiAG9elWRgwLF/9PZ+ZkOb1WgLgar+1RlczKnWLbMMTX1pWrYlk8Mk+r3P8/xpoDdQGbYY/OPCoy1OEkWs=;\n\t7:ItVhcp+pNL0KOJ+p0qJ4TZGwVRIlU1SVfe4BXZHWsITRPNbdoM2C8xEbeuLF8s0dDC/yzgfbkERxTfHZuNq9g8a60qVzhfsUAV9P0zR3JAt2cxCu8hB50D1hpjM5PcR/36an1tHQpq9ab6liuXjTHeTWhpZR5zii/MBie6Q1KxL5aK10DXvtXjNxgq/XW58HOgysk8RA1tAyjcqXIfwToHAN5ZaP/mZlQ84yMn3bbto=","x-ms-exchange-antispam-srfa-diagnostics":"SSOS;SSOR;","x-forefront-antispam-report":"SFV:SKI; SCL:-1; SFV:NSPM;\n\tSFS:(10009020)(6009001)(346002)(39860400002)(376002)(24454002)(199003)(13464003)(377454003)(189002)(2900100001)(93886005)(229853002)(33656002)(305945005)(6116002)(3280700002)(3846002)(102836003)(53546010)(74316002)(7696004)(106356001)(81166006)(55016002)(54906003)(86362001)(6246003)(99286003)(110136005)(8936002)(478600001)(316002)(5660300001)(39060400002)(8676002)(2906002)(14454004)(2950100002)(4326008)(53936002)(66066001)(5250100002)(81156014)(9686003)(101416001)(50986999)(7736002)(54356999)(2501003)(3660700001)(68736007)(76176999)(105586002)(189998001)(25786009)(6506006)(97736004)(6436002)(217873001);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM3PR04MB1234;\n\tH:AM3PR04MB0743.eurprd04.prod.outlook.com; FPR:; SPF:None;\n\tPTR:InfoNoRecords; A:1; MX:1; LANG:en; ","x-ms-office365-filtering-correlation-id":"4404acf4-a945-477b-c86a-08d50965d5f2","x-ms-office365-filtering-ht":"Tenant","x-microsoft-antispam":"UriScan:; BCL:0; PCL:0;\n\tRULEID:(22001)(2017030254152)(48565401081)(2017052603199)(201703131423075)(201703031133081)(201702281549075);\n\tSRVR:AM3PR04MB1234; ","x-ms-traffictypediagnostic":"AM3PR04MB1234:","x-exchange-antispam-report-test":"UriScan:(9452136761055)(185117386973197);","x-microsoft-antispam-prvs":"<AM3PR04MB12345B70EA59481B64FCF112E67D0@AM3PR04MB1234.eurprd04.prod.outlook.com>","x-exchange-antispam-report-cfa-test":"BCL:0; PCL:0;\n\tRULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(3002001)(10201501046)(93006095)(93001095)(100000703101)(100105400095)(6055026)(6041248)(20161123562025)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123564025)(20161123555025)(20161123558100)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);\n\tSRVR:AM3PR04MB1234; BCL:0; PCL:0;\n\tRULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);\n\tSRVR:AM3PR04MB1234; ","x-forefront-prvs":"0448A97BF2","received-spf":"None (protection.outlook.com: nxp.com does not designate\n\tpermitted sender hosts)","spamdiagnosticoutput":"1:99","spamdiagnosticmetadata":"NSPM","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","MIME-Version":"1.0","X-OriginatorOrg":"nxp.com","X-MS-Exchange-CrossTenant-originalarrivaltime":"02 Oct 2017 07:18:52.7348\n\t(UTC)","X-MS-Exchange-CrossTenant-fromentityheader":"Hosted","X-MS-Exchange-CrossTenant-id":"686ea1d3-bc2b-4c6f-a92c-d99c5c301635","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"AM3PR04MB1234","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"}},{"id":1778221,"web_url":"http://patchwork.ozlabs.org/comment/1778221/","msgid":"<59D20766.5040606@nxp.com>","list_archive_url":null,"date":"2017-10-02T09:32:29","subject":"Re: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale DPAA2\n\tEthernet Switch driver","submitter":{"id":71003,"url":"http://patchwork.ozlabs.org/api/people/71003/","name":"Laurentiu Tudor","email":"laurentiu.tudor@nxp.com"},"content":"Hi Florian,\r\n\r\nOn 09/29/2017 07:11 PM, Florian Fainelli wrote:\r\n> On September 29, 2017 6:59:18 AM PDT, Razvan Stefanescu <razvan.stefanescu@nxp.com> wrote:\r\n>>\r\n>>\r\n>>> -----Original Message-----\r\n>>> From: Bogdan Purcareata\r\n>>> Sent: Friday, September 29, 2017 16:36\r\n>>> To: Razvan Stefanescu <razvan.stefanescu@nxp.com>;\r\n>>> gregkh@linuxfoundation.org\r\n>>> Cc: devel@driverdev.osuosl.org; linux-kernel@vger.kernel.org;\r\n>>> netdev@vger.kernel.org; agraf@suse.de; arnd@arndb.de; Alexandru\r\n>> Marginean\r\n>>> <alexandru.marginean@nxp.com>; Ruxandra Ioana Radulescu\r\n>>> <ruxandra.radulescu@nxp.com>; Laurentiu Tudor\r\n>> <laurentiu.tudor@nxp.com>;\r\n>>> stuyoder@gmail.com\r\n>>> Subject: RE: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add\r\n>> Freescale DPAA2\r\n>>> Ethernet Switch driver\r\n>>>\r\n>>>> Introduce the DPAA2 Ethernet Switch driver, which manages Datapath\r\n>> Switch\r\n>>>> (DPSW) objects discovered on the MC bus.\r\n>>>>\r\n>>>> Suggested-by: Alexandru Marginean <alexandru.marginean@nxp.com>\r\n>>>> Signed-off-by: Razvan Stefanescu <razvan.stefanescu@nxp.com>\r\n>\r\n> This looks pretty good for a new switchdev driver, is there a reason you can't target drivers/net/ethernet instead of staging? Is it because the MC bus code is still in staging (AFAICT)?\r\n\r\nThere's a pending patch [1] that moves the bus from staging to its place \r\nin drivers/bus. DPIO plus other bits and pieces are next on the list.\r\n\r\nGreg,\r\n\r\nJust a heads up: if this driver goes in first, then i'll need to re-spin \r\nmy patch [1] to also update the #include's in this switch driver.\r\n\r\nP.S. Any news on my patch? :-)\r\n\r\n[1] https://www.spinics.net/lists/arm-kernel/msg603534.html\r\n\r\n---\r\nThanks, Laurentiu","headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"ddg0p5Uw\";\n\tdkim-atps=neutral","spf=none (sender IP is )\n\tsmtp.mailfrom=laurentiu.tudor@nxp.com; "],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3y5H5D5250z9t3f\n\tfor <patchwork-incoming@ozlabs.org>;\n\tMon,  2 Oct 2017 20:32:48 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751015AbdJBJcg (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 2 Oct 2017 05:32:36 -0400","from mail-eopbgr50080.outbound.protection.outlook.com\n\t([40.107.5.80]:56992\n\t\"EHLO EUR03-VE1-obe.outbound.protection.outlook.com\"\n\trhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP\n\tid S1750878AbdJBJce (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tMon, 2 Oct 2017 05:32:34 -0400","from VI1PR0401MB1856.eurprd04.prod.outlook.com (10.165.235.22) by\n\tAM3PR04MB0741.eurprd04.prod.outlook.com (10.160.5.21) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id\n\t15.20.77.7; Mon, 2 Oct 2017 09:32:31 +0000","from VI1PR0401MB1856.eurprd04.prod.outlook.com\n\t([fe80::3dff:70fb:259c:3fbe]) by\n\tVI1PR0401MB1856.eurprd04.prod.outlook.com\n\t([fe80::3dff:70fb:259c:3fbe%14]) with mapi id 15.20.0077.018;\n\tMon, 2 Oct 2017 09:32:30 +0000"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version;\n\tbh=u4rAJBzSGiPHEMS9N44BABkZvPUjmPuI8Gr44J8Or4U=;\n\tb=ddg0p5UwTWUvJc7tO9RW2U6IOIN9tDPUfKv83tHCVSo41QOsw0hdHVRq/vSjfYzXR5mPZ63AOa7/PScsZAZRX+5pgKuxW8um+QjUr4Srmt6EpRFNfYsaAI0DO4xIFlbwCFOLOqOFoUzXzfladLOmBtcCaRRhwiM5ntphg6Y+8Oc=","From":"Laurentiu Tudor <laurentiu.tudor@nxp.com>","To":"Florian Fainelli <f.fainelli@gmail.com>,\n\tRazvan Stefanescu <razvan.stefanescu@nxp.com>,\n\tBogdan Purcareata <bogdan.purcareata@nxp.com>,\n\t\"gregkh@linuxfoundation.org\" <gregkh@linuxfoundation.org>","CC":"\"devel@driverdev.osuosl.org\" <devel@driverdev.osuosl.org>,\n\t\"linux-kernel@vger.kernel.org\" <linux-kernel@vger.kernel.org>,\n\t\"netdev@vger.kernel.org\" <netdev@vger.kernel.org>,\n\t\"agraf@suse.de\" <agraf@suse.de>, \"arnd@arndb.de\" <arnd@arndb.de>,\n\tAlexandru Marginean <alexandru.marginean@nxp.com>,\n\tRuxandra Ioana Radulescu <ruxandra.radulescu@nxp.com>,\n\t\"stuyoder@gmail.com\" <stuyoder@gmail.com>","Subject":"Re: [RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale DPAA2\n\tEthernet Switch driver","Thread-Topic":"[RESEND PATCH 2/6] staging: fsl-dpaa2/ethsw: Add Freescale\n\tDPAA2 Ethernet Switch driver","Thread-Index":"AQHTMUVIXaeHBbFWpEW/zy1UIzG+9KLL7UAAgAAGfgCAACThAIAERzwA","Date":"Mon, 2 Oct 2017 09:32:29 +0000","Message-ID":"<59D20766.5040606@nxp.com>","References":"<1505825158-8192-1-git-send-email-razvan.stefanescu@nxp.com>\n\t<1505825158-8192-3-git-send-email-razvan.stefanescu@nxp.com>\n\t<DB5PR04MB12400025DF190790B4792B50EA7E0@DB5PR04MB1240.eurprd04.prod.outlook.com>\n\t<AM3PR04MB0743F62497ED0CB445F51524E67E0@AM3PR04MB0743.eurprd04.prod.outlook.com>\n\t<A4C4732A-CC1F-4707-89F8-E7284F022DB0@gmail.com>","In-Reply-To":"<A4C4732A-CC1F-4707-89F8-E7284F022DB0@gmail.com>","Accept-Language":"en-US","Content-Language":"en-US","X-MS-Has-Attach":"","X-MS-TNEF-Correlator":"","authentication-results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"ddg0p5Uw\";\n\tdkim-atps=neutral","spf=none (sender IP is )\n\tsmtp.mailfrom=laurentiu.tudor@nxp.com; "],"x-originating-ip":"[192.88.146.1]","x-ms-publictraffictype":"Email","x-microsoft-exchange-diagnostics":"1; AM3PR04MB0741;\n\t6:rd9I7LPeEquFwXriapvYLiiOt+2YLaz3sGOUEKeCKZPcBE0coOKgUGif3CoCOFLCtYhv8FuqYJnXpRHPibHCAeQ5MuT05UjQe265y7Jw0VxlyT4ysqFQKwvHqV7FG231VJM0xirTuEAabKwPNRnf5zFxP1SmAqCNBskg9uoHyT4mNGB2in68CiZOlBUvfWIdCuPUZR2l2LsXeJxvcC6IrFnic5ARMHSE5MERwvu6rz+EbBVk6lzWNs5lk7zyKEghmg2EKPIP+9vDugAvMIB0BF3FqMilqEEPEpovKFoz4b7cJj46XIr7YyyKNYhaEVITLkK+4/clme0wyjRfV3iPkA==;\n\t5:ybbWTxs4xkmkD4VmumY/VoarxSv+dxMABMDxcSIn5aMCKWqX4bCNv3/pyzIbVOo0CAN+ziP5KuGpXYulQ2YkvAulwrn+kIOjyvcMsR58EVIQpdJ8Hn+ct9j0+Dj7jqOA3MS3fMRStx2w7ndGLp9VSg==;\n\t24:a8Q4YfuUVrqU64/qxU633JKlBHP9PIJQ64K+ldBko2ApGsJ255TQiSsWbPnJCHYEPsRo0huEz9ZHg6z4x7Qco2XWSa8f3WNSdB+SmSQU610=;\n\t7:ZR2jPmU1E3YckES8rN7CwkuAO7xqQfcppfJnE++NlQhz7NS0BruHJwEbH1CVsts0As7vZNPuK6sSR7fnQNJUEn+OcD8mk1Mlv5QoNnI4HeBxugzaCJ6y4HFGOOEEzWbXpCFEV+k9oxe/LmcxrngIfBz1qufnfg+8hsEG2BBoq1zfcTDvM9hxX04CA2SjUKyj736pdYiA0IRTpwhwE2ubHgmcF4y/BD4TVC9nipEScIE=","x-ms-exchange-antispam-srfa-diagnostics":"SSOS;SSOR;","x-forefront-antispam-report":"SFV:SKI; SCL:-1; SFV:NSPM;\n\tSFS:(10009020)(6009001)(346002)(39860400002)(376002)(199003)(377454003)(13464003)(189002)(24454002)(2501003)(76176999)(2900100001)(54356999)(50986999)(65816999)(87266999)(5250100002)(25786009)(106356001)(189998001)(4326008)(53546010)(80316001)(3660700001)(33656002)(3280700002)(6512007)(110136005)(99286003)(6306002)(59896002)(6246003)(53936002)(39060400002)(5660300001)(93886005)(2950100002)(105586002)(54906003)(229853002)(36756003)(66066001)(2906002)(478600001)(966005)(6486002)(6506006)(97736004)(14454004)(6436002)(81166006)(81156014)(316002)(3846002)(7736002)(8676002)(305945005)(8936002)(86362001)(6116002)(102836003)(68736007)(101416001)(217873001);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM3PR04MB0741;\n\tH:VI1PR0401MB1856.eurprd04.prod.outlook.com; FPR:; SPF:None;\n\tPTR:InfoNoRecords; A:1; MX:1; LANG:en; ","x-ms-office365-filtering-correlation-id":"92221f9a-24ed-413a-066c-08d5097880ab","x-ms-office365-filtering-ht":"Tenant","x-microsoft-antispam":"UriScan:; BCL:0; PCL:0;\n\tRULEID:(22001)(2017030254152)(48565401081)(2017052603199)(201703131423075)(201703031133081)(201702281549075);\n\tSRVR:AM3PR04MB0741; ","x-ms-traffictypediagnostic":"AM3PR04MB0741:","x-exchange-antispam-report-test":"UriScan:(9452136761055)(185117386973197);","x-microsoft-antispam-prvs":"<AM3PR04MB07418EC48F9D29E5C282A8C0EC7D0@AM3PR04MB0741.eurprd04.prod.outlook.com>","x-exchange-antispam-report-cfa-test":"BCL:0; PCL:0;\n\tRULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(93006095)(93001095)(100000703101)(100105400095)(10201501046)(3002001)(6055026)(6041248)(20161123560025)(20161123555025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123564025)(20161123562025)(20161123558100)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);\n\tSRVR:AM3PR04MB0741; BCL:0; PCL:0;\n\tRULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);\n\tSRVR:AM3PR04MB0741; ","x-forefront-prvs":"0448A97BF2","received-spf":"None (protection.outlook.com: nxp.com does not designate\n\tpermitted sender hosts)","spamdiagnosticoutput":"1:99","spamdiagnosticmetadata":"NSPM","Content-Type":"text/plain; charset=\"utf-8\"","Content-ID":"<4F2DC13F0E627643A3EB18410E999D50@eurprd04.prod.outlook.com>","Content-Transfer-Encoding":"base64","MIME-Version":"1.0","X-OriginatorOrg":"nxp.com","X-MS-Exchange-CrossTenant-originalarrivaltime":"02 Oct 2017 09:32:30.0804\n\t(UTC)","X-MS-Exchange-CrossTenant-fromentityheader":"Hosted","X-MS-Exchange-CrossTenant-id":"686ea1d3-bc2b-4c6f-a92c-d99c5c301635","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"AM3PR04MB0741","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"}}]