+static int
+cn10k_nix_rx_metadata_negotiate(struct rte_eth_dev *eth_dev, uint64_t *features)
+{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+
+ *features &=
+ (RTE_ETH_RX_METADATA_USER_FLAG | RTE_ETH_RX_METADATA_USER_MARK);
+
+ if (*features) {
+ dev->rx_offload_flags |= NIX_RX_OFFLOAD_MARK_UPDATE_F;
+ dev->rx_mark_update = true;
+ } else {
+ dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_MARK_UPDATE_F;
+ dev->rx_mark_update = false;
+ }
+
+ cn10k_eth_set_rx_function(eth_dev);
+
+ return 0;
+}
+
+static int
+cn10k_nix_reassembly_capability_get(struct rte_eth_dev *eth_dev,
+ struct rte_eth_ip_reassembly_params *reassembly_capa)
+{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+ int rc = -ENOTSUP;
+ RTE_SET_USED(eth_dev);
+
+ if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY) {
+ reassembly_capa->timeout_ms = 60 * 1000;
+ reassembly_capa->max_frags = 4;
+ reassembly_capa->flags = RTE_ETH_DEV_REASSEMBLY_F_IPV4 |
+ RTE_ETH_DEV_REASSEMBLY_F_IPV6;
+ rc = 0;
+ }
+
+ return rc;
+}
+
+static int
+cn10k_nix_reassembly_conf_get(struct rte_eth_dev *eth_dev,
+ struct rte_eth_ip_reassembly_params *conf)
+{
+ RTE_SET_USED(eth_dev);
+ RTE_SET_USED(conf);
+ return -ENOTSUP;
+}
+
+static int
+cn10k_nix_reassembly_conf_set(struct rte_eth_dev *eth_dev,
+ const struct rte_eth_ip_reassembly_params *conf)
+{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+ int rc = 0;
+
+ if (!conf->flags) {
+ /* Clear offload flags on disable */
+ dev->rx_offload_flags &= ~NIX_RX_REAS_F;
+ return 0;
+ }
+
+ rc = roc_nix_reassembly_configure(conf->timeout_ms,
+ conf->max_frags);
+ if (!rc && dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY)
+ dev->rx_offload_flags |= NIX_RX_REAS_F;
+
+ return rc;
+}
+
+static int
+cn10k_nix_tm_mark_vlan_dei(struct rte_eth_dev *eth_dev, int mark_green,
+ int mark_yellow, int mark_red,
+ struct rte_tm_error *error)
+{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+ struct roc_nix *roc_nix = &dev->nix;
+ uint64_t mark_fmt, mark_flag;
+ int rc, i;
+
+ rc = cnxk_nix_tm_mark_vlan_dei(eth_dev, mark_green, mark_yellow,
+ mark_red, error);
+
+ if (rc)
+ goto exit;
+
+ mark_fmt = roc_nix_tm_mark_format_get(roc_nix, &mark_flag);
+ if (mark_flag) {
+ dev->tx_offload_flags |= NIX_TX_OFFLOAD_VLAN_QINQ_F;
+ dev->tx_mark = true;
+ } else {
+ dev->tx_mark = false;
+ if (!(dev->tx_offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT ||
+ dev->tx_offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT))
+ dev->tx_offload_flags &= ~NIX_TX_OFFLOAD_VLAN_QINQ_F;
+ }
+
+ for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+ struct cn10k_eth_txq *txq = eth_dev->data->tx_queues[i];
+
+ txq->mark_flag = mark_flag & CNXK_TM_MARK_MASK;
+ txq->mark_fmt = mark_fmt & CNXK_TX_MARK_FMT_MASK;
+ }
+ cn10k_eth_set_tx_function(eth_dev);
+exit:
+ return rc;
+}
+
+static int
+cn10k_nix_tm_mark_ip_ecn(struct rte_eth_dev *eth_dev, int mark_green,
+ int mark_yellow, int mark_red,
+ struct rte_tm_error *error)
+{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+ struct roc_nix *roc_nix = &dev->nix;
+ uint64_t mark_fmt, mark_flag;
+ int rc, i;
+
+ rc = cnxk_nix_tm_mark_ip_ecn(eth_dev, mark_green, mark_yellow, mark_red,
+ error);
+ if (rc)
+ goto exit;
+
+ mark_fmt = roc_nix_tm_mark_format_get(roc_nix, &mark_flag);
+ if (mark_flag) {
+ dev->tx_offload_flags |= NIX_TX_OFFLOAD_VLAN_QINQ_F;
+ dev->tx_mark = true;
+ } else {
+ dev->tx_mark = false;
+ if (!(dev->tx_offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT ||
+ dev->tx_offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT))
+ dev->tx_offload_flags &= ~NIX_TX_OFFLOAD_VLAN_QINQ_F;
+ }
+
+ for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+ struct cn10k_eth_txq *txq = eth_dev->data->tx_queues[i];
+
+ txq->mark_flag = mark_flag & CNXK_TM_MARK_MASK;
+ txq->mark_fmt = mark_fmt & CNXK_TX_MARK_FMT_MASK;
+ }
+ cn10k_eth_set_tx_function(eth_dev);
+exit:
+ return rc;
+}
+
+static int
+cn10k_nix_tm_mark_ip_dscp(struct rte_eth_dev *eth_dev, int mark_green,
+ int mark_yellow, int mark_red,
+ struct rte_tm_error *error)
+{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+ struct roc_nix *roc_nix = &dev->nix;
+ uint64_t mark_fmt, mark_flag;
+ int rc, i;
+
+ rc = cnxk_nix_tm_mark_ip_dscp(eth_dev, mark_green, mark_yellow,
+ mark_red, error);
+ if (rc)
+ goto exit;
+
+ mark_fmt = roc_nix_tm_mark_format_get(roc_nix, &mark_flag);
+ if (mark_flag) {
+ dev->tx_offload_flags |= NIX_TX_OFFLOAD_VLAN_QINQ_F;
+ dev->tx_mark = true;
+ } else {
+ dev->tx_mark = false;
+ if (!(dev->tx_offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT ||
+ dev->tx_offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT))
+ dev->tx_offload_flags &= ~NIX_TX_OFFLOAD_VLAN_QINQ_F;
+ }
+
+ for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+ struct cn10k_eth_txq *txq = eth_dev->data->tx_queues[i];
+
+ txq->mark_flag = mark_flag & CNXK_TM_MARK_MASK;
+ txq->mark_fmt = mark_fmt & CNXK_TX_MARK_FMT_MASK;
+ }
+ cn10k_eth_set_tx_function(eth_dev);
+exit:
+ return rc;
+}
+