From e59b75ffeb9ab81026eb82b75e426a335d740b3b Mon Sep 17 00:00:00 2001 From: Hemant Agrawal Date: Fri, 22 Feb 2019 11:15:58 +0000 Subject: [PATCH] net/dpaa2: support VLAN TPID config This patch add support to config custom tpid in dpni. i.e. value other than 0x8100 and 0x88A8 Signed-off-by: Hemant Agrawal --- drivers/net/dpaa2/dpaa2_ethdev.c | 39 ++++++++++++ drivers/net/dpaa2/mc/dpni.c | 98 +++++++++++++++++++++++++++++ drivers/net/dpaa2/mc/fsl_dpni.h | 20 ++++++ drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 18 ++++++ 4 files changed, 175 insertions(+) diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c index 2b90f4021c..bc3faa8a3e 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.c +++ b/drivers/net/dpaa2/dpaa2_ethdev.c @@ -161,6 +161,44 @@ next_mask: return 0; } +static int +dpaa2_vlan_tpid_set(struct rte_eth_dev *dev, + enum rte_vlan_type vlan_type __rte_unused, + uint16_t tpid) +{ + struct dpaa2_dev_priv *priv = dev->data->dev_private; + struct fsl_mc_io *dpni = priv->hw; + int ret = -ENOTSUP; + + PMD_INIT_FUNC_TRACE(); + + /* nothing to be done for standard vlan tpids */ + if (tpid == 0x8100 || tpid == 0x88A8) + return 0; + + ret = dpni_add_custom_tpid(dpni, CMD_PRI_LOW, + priv->token, tpid); + if (ret < 0) + DPAA2_PMD_INFO("Unable to set vlan tpid = %d", ret); + /* if already configured tpids, remove them first */ + if (ret == -EBUSY) { + struct dpni_custom_tpid_cfg tpid_list = {0}; + + ret = dpni_get_custom_tpid(dpni, CMD_PRI_LOW, + priv->token, &tpid_list); + if (ret < 0) + goto fail; + ret = dpni_remove_custom_tpid(dpni, CMD_PRI_LOW, + priv->token, tpid_list.tpid1); + if (ret < 0) + goto fail; + ret = dpni_add_custom_tpid(dpni, CMD_PRI_LOW, + priv->token, tpid); + } +fail: + return ret; +} + static int dpaa2_fw_version_get(struct rte_eth_dev *dev, char *fw_version, @@ -1832,6 +1870,7 @@ static struct eth_dev_ops dpaa2_ethdev_ops = { .mtu_set = dpaa2_dev_mtu_set, .vlan_filter_set = dpaa2_vlan_filter_set, .vlan_offload_set = dpaa2_vlan_offload_set, + .vlan_tpid_set = dpaa2_vlan_tpid_set, .rx_queue_setup = dpaa2_dev_rx_queue_setup, .rx_queue_release = dpaa2_dev_rx_queue_release, .tx_queue_setup = dpaa2_dev_tx_queue_setup, diff --git a/drivers/net/dpaa2/mc/dpni.c b/drivers/net/dpaa2/mc/dpni.c index 44b5604d38..0907a36996 100644 --- a/drivers/net/dpaa2/mc/dpni.c +++ b/drivers/net/dpaa2/mc/dpni.c @@ -2063,3 +2063,101 @@ int dpni_get_opr(struct fsl_mc_io *mc_io, return 0; } + +/** + * dpni_add_custom_tpid() - Configures a distinct Ethertype value + * (or TPID value) to indicate VLAN tag in addition to the common + * TPID values 0x8100 and 0x88A8 + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @tpid: New value for TPID + * + * Only two custom values are accepted. If the function is called for the third + * time it will return error. + * To replace an existing value use dpni_remove_custom_tpid() to remove + * a previous TPID and after that use again the function. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_add_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, uint16_t tpid) +{ + struct dpni_cmd_add_custom_tpid *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_CUSTOM_TPID, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_add_custom_tpid *)cmd.params; + cmd_params->tpid = cpu_to_le16(tpid); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +/** + * dpni_remove_custom_tpid() - Removes a distinct Ethertype value added + * previously with dpni_add_custom_tpid() + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @tpid: New value for TPID + * + * Use this function when a TPID value added with dpni_add_custom_tpid() needs + * to be replaced. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_remove_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, uint16_t tpid) +{ + struct dpni_cmd_remove_custom_tpid *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_CUSTOM_TPID, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_remove_custom_tpid *)cmd.params; + cmd_params->tpid = cpu_to_le16(tpid); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +/** + * dpni_get_custom_tpid() - Returns custom TPID (vlan tags) values configured + * to detect 802.1q frames + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @tpid: TPID values. Only nonzero members of the structure are valid. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, struct dpni_custom_tpid_cfg *tpid) +{ + struct dpni_rsp_get_custom_tpid *rsp_params; + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_CUSTOM_TPID, + cmd_flags, + token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* read command response */ + rsp_params = (struct dpni_rsp_get_custom_tpid *)cmd.params; + tpid->tpid1 = le16_to_cpu(rsp_params->tpid1); + tpid->tpid2 = le16_to_cpu(rsp_params->tpid2); + + return err; +} diff --git a/drivers/net/dpaa2/mc/fsl_dpni.h b/drivers/net/dpaa2/mc/fsl_dpni.h index de1bcb5bf1..0359a2bc7a 100644 --- a/drivers/net/dpaa2/mc/fsl_dpni.h +++ b/drivers/net/dpaa2/mc/fsl_dpni.h @@ -1202,4 +1202,24 @@ int dpni_get_opr(struct fsl_mc_io *mc_io, struct opr_cfg *cfg, struct opr_qry *qry); +int dpni_add_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, uint16_t tpid); + +int dpni_remove_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, uint16_t tpid); + +/** + * struct dpni_custom_tpid_cfg - custom TPID configuration. Contains custom TPID + * values used in current dpni object to detect 802.1q frames. + * @tpid1: first tag. Not used if zero. + * @tpid2: second tag. Not used if zero. + */ +struct dpni_custom_tpid_cfg { + uint16_t tpid1; + uint16_t tpid2; +}; + +int dpni_get_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, struct dpni_custom_tpid_cfg *tpid); + #endif /* __FSL_DPNI_H */ diff --git a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h index 3df5bcf1fa..81830ed85f 100644 --- a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h +++ b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h @@ -91,6 +91,9 @@ #define DPNI_CMDID_GET_TX_CONFIRMATION_MODE DPNI_CMD(0x26D) #define DPNI_CMDID_SET_OPR DPNI_CMD(0x26e) #define DPNI_CMDID_GET_OPR DPNI_CMD(0x26f) +#define DPNI_CMDID_ADD_CUSTOM_TPID DPNI_CMD(0x275) +#define DPNI_CMDID_REMOVE_CUSTOM_TPID DPNI_CMD(0x276) +#define DPNI_CMDID_GET_CUSTOM_TPID DPNI_CMD(0x277) /* Macros for accessing command fields smaller than 1byte */ #define DPNI_MASK(field) \ @@ -674,5 +677,20 @@ struct dpni_rsp_get_opr { uint16_t opr_id; }; +struct dpni_cmd_add_custom_tpid { + uint16_t pad; + uint16_t tpid; +}; + +struct dpni_cmd_remove_custom_tpid { + uint16_t pad; + uint16_t tpid; +}; + +struct dpni_rsp_get_custom_tpid { + uint16_t tpid1; + uint16_t tpid2; +}; + #pragma pack(pop) #endif /* _FSL_DPNI_CMD_H */ -- 2.20.1