diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h index 2a921ed9594db..fc1ba45f8a3f5 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2014-2016 Freescale Semiconductor Inc. - * Copyright 2017-2020 NXP + * Copyright 2017-2021 NXP * */ @@ -10,7 +10,7 @@ /* DPSW Version */ #define DPSW_VER_MAJOR 8 -#define DPSW_VER_MINOR 5 +#define DPSW_VER_MINOR 9 #define DPSW_CMD_BASE_VERSION 1 #define DPSW_CMD_VERSION_2 2 @@ -72,6 +72,8 @@ #define DPSW_CMDID_IF_GET_PRIMARY_MAC_ADDR DPSW_CMD_ID(0x0A8) #define DPSW_CMDID_IF_SET_PRIMARY_MAC_ADDR DPSW_CMD_ID(0x0A9) +#define DPSW_CMDID_CTRL_IF_GET_ATTR DPSW_CMD_ID(0x0A0) + /* Macros for accessing command fields smaller than 1byte */ #define DPSW_MASK(field) \ GENMASK(DPSW_##field##_SHIFT + DPSW_##field##_SIZE - 1, \ @@ -347,6 +349,13 @@ struct dpsw_rsp_fdb_dump { __le16 num_entries; }; +struct dpsw_rsp_ctrl_if_get_attr { + __le64 pad; + __le32 rx_fqid; + __le32 rx_err_fqid; + __le32 tx_err_conf_fqid; +}; + struct dpsw_rsp_get_api_version { __le16 version_major; __le16 version_minor; diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw.c b/drivers/staging/fsl-dpaa2/ethsw/dpsw.c index f7013d71dc849..a7794f012e786 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/dpsw.c +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright 2014-2016 Freescale Semiconductor Inc. - * Copyright 2017-2018 NXP + * Copyright 2017-2021 NXP * */ @@ -1089,6 +1089,37 @@ int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dpsw_ctrl_if_get_attributes() - Obtain control interface attributes + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPSW object + * @attr: Returned control interface attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dpsw_ctrl_if_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, + u16 token, struct dpsw_ctrl_if_attr *attr) +{ + struct dpsw_rsp_ctrl_if_get_attr *rsp_params; + struct fsl_mc_command cmd = { 0 }; + int err; + + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_GET_ATTR, + cmd_flags, token); + + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + rsp_params = (struct dpsw_rsp_ctrl_if_get_attr *)cmd.params; + attr->rx_fqid = le32_to_cpu(rsp_params->rx_fqid); + attr->rx_err_fqid = le32_to_cpu(rsp_params->rx_err_fqid); + attr->tx_err_conf_fqid = le32_to_cpu(rsp_params->tx_err_conf_fqid); + + return 0; +} + /** * dpsw_get_api_version() - Get Data Path Switch API version * @mc_io: Pointer to MC portal's I/O object diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h index bc6bcfb6893d4..8c8cc9600e8db 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2014-2016 Freescale Semiconductor Inc. - * Copyright 2017-2018 NXP + * Copyright 2017-2021 NXP * */ @@ -175,6 +175,27 @@ int dpsw_get_attributes(struct fsl_mc_io *mc_io, u16 token, struct dpsw_attr *attr); +/** + * struct dpsw_ctrl_if_attr - Control interface attributes + * @rx_fqid: Receive FQID + * @rx_err_fqid: Receive error FQID + * @tx_err_conf_fqid: Transmit error and confirmation FQID + */ +struct dpsw_ctrl_if_attr { + u32 rx_fqid; + u32 rx_err_fqid; + u32 tx_err_conf_fqid; +}; + +int dpsw_ctrl_if_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, + u16 token, struct dpsw_ctrl_if_attr *attr); + +enum dpsw_queue_type { + DPSW_QUEUE_RX, + DPSW_QUEUE_TX_ERR_CONF, + DPSW_QUEUE_RX_ERR, +}; + /** * enum dpsw_action - Action selection for special/control frames * @DPSW_ACTION_DROP: Drop frame diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c index 3067289a15a1b..b03211fb6fc9b 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c @@ -20,7 +20,7 @@ /* Minimal supported DPSW version */ #define DPSW_MIN_VER_MAJOR 8 -#define DPSW_MIN_VER_MINOR 1 +#define DPSW_MIN_VER_MINOR 9 #define DEFAULT_VLAN_ID 1 @@ -1334,6 +1334,43 @@ static void dpaa2_switch_detect_features(struct ethsw_core *ethsw) ethsw->features |= ETHSW_FEATURE_MAC_ADDR; } +static int dpaa2_switch_setup_fqs(struct ethsw_core *ethsw) +{ + struct dpsw_ctrl_if_attr ctrl_if_attr; + struct device *dev = ethsw->dev; + int i = 0; + int err; + + err = dpsw_ctrl_if_get_attributes(ethsw->mc_io, 0, ethsw->dpsw_handle, + &ctrl_if_attr); + if (err) { + dev_err(dev, "dpsw_ctrl_if_get_attributes() = %d\n", err); + return err; + } + + ethsw->fq[i].fqid = ctrl_if_attr.rx_fqid; + ethsw->fq[i].ethsw = ethsw; + ethsw->fq[i++].type = DPSW_QUEUE_RX; + + ethsw->fq[i].fqid = ctrl_if_attr.tx_err_conf_fqid; + ethsw->fq[i].ethsw = ethsw; + ethsw->fq[i++].type = DPSW_QUEUE_TX_ERR_CONF; + + return 0; +} + +static int dpaa2_switch_ctrl_if_setup(struct ethsw_core *ethsw) +{ + int err; + + /* setup FQs for Rx and Tx Conf */ + err = dpaa2_switch_setup_fqs(ethsw); + if (err) + return err; + + return 0; +} + static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) { struct device *dev = &sw_dev->dev; @@ -1371,11 +1408,14 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) if (ethsw->major < DPSW_MIN_VER_MAJOR || (ethsw->major == DPSW_MIN_VER_MAJOR && ethsw->minor < DPSW_MIN_VER_MINOR)) { - dev_err(dev, "DPSW version %d:%d not supported. Use %d.%d or greater.\n", - ethsw->major, - ethsw->minor, - DPSW_MIN_VER_MAJOR, DPSW_MIN_VER_MINOR); - err = -ENOTSUPP; + dev_err(dev, "DPSW version %d:%d not supported. Use firmware 10.28.0 or greater.\n", + ethsw->major, ethsw->minor); + err = -EOPNOTSUPP; + goto err_close; + } + + if (!dpaa2_switch_supports_cpu_traffic(ethsw)) { + err = -EOPNOTSUPP; goto err_close; } @@ -1447,6 +1487,10 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) goto err_close; } + err = dpaa2_switch_ctrl_if_setup(ethsw); + if (err) + goto err_destroy_ordered_workqueue; + err = dpaa2_switch_register_notifier(dev); if (err) goto err_destroy_ordered_workqueue; diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h index 448f60755eea7..24a203c42f5f5 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h @@ -3,7 +3,7 @@ * DPAA2 Ethernet Switch declarations * * Copyright 2014-2016 Freescale Semiconductor Inc. - * Copyright 2017-2018 NXP + * Copyright 2017-2021 NXP * */ @@ -39,10 +39,19 @@ #define ETHSW_FEATURE_MAC_ADDR BIT(0) +/* Number of receive queues (one RX and one TX_CONF) */ +#define DPAA2_SWITCH_RX_NUM_FQS 2 + extern const struct ethtool_ops dpaa2_switch_port_ethtool_ops; struct ethsw_core; +struct dpaa2_switch_fq { + struct ethsw_core *ethsw; + enum dpsw_queue_type type; + u32 fqid; +}; + /* Per port private data */ struct ethsw_port_priv { struct net_device *netdev; @@ -74,6 +83,17 @@ struct ethsw_core { struct notifier_block port_switchdev_nb; struct notifier_block port_switchdevb_nb; struct workqueue_struct *workqueue; + + struct dpaa2_switch_fq fq[DPAA2_SWITCH_RX_NUM_FQS]; }; +static inline bool dpaa2_switch_supports_cpu_traffic(struct ethsw_core *ethsw) +{ + if (ethsw->sw_attr.options & DPSW_OPT_CTRL_IF_DIS) { + dev_err(ethsw->dev, "Control Interface is disabled, cannot probe\n"); + return false; + } + + return true; +} #endif /* __ETHSW_H */