+ (*device_configured) |= local_cfg;
+
+ return 0;
+}
+
+static int
+dpaa2_configure_flow_icmp(struct rte_flow *flow,
+ struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item *pattern,
+ const struct rte_flow_action actions[] __rte_unused,
+ struct rte_flow_error *error __rte_unused,
+ int *device_configured)
+{
+ int index, ret;
+ int local_cfg = 0;
+ uint32_t group;
+ const struct rte_flow_item_icmp *spec, *mask;
+
+ const struct rte_flow_item_icmp *last __rte_unused;
+ struct dpaa2_dev_priv *priv = dev->data->dev_private;
+
+ group = attr->group;
+
+ /* Parse pattern list to get the matching parameters */
+ spec = (const struct rte_flow_item_icmp *)pattern->spec;
+ last = (const struct rte_flow_item_icmp *)pattern->last;
+ mask = (const struct rte_flow_item_icmp *)
+ (pattern->mask ? pattern->mask : &dpaa2_flow_item_icmp_mask);
+
+ /* Get traffic class index and flow id to be configured */
+ flow->tc_id = group;
+ flow->tc_index = attr->priority;
+
+ if (!spec) {
+ /* Don't care any field of ICMP header,
+ * only care ICMP protocol.
+ * Example: flow create 0 ingress pattern icmp /
+ */
+ /* Next proto of Generical IP is actually used
+ * for ICMP identification.
+ */
+ struct proto_discrimination proto;
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_IP, NH_FLD_IP_PROTO);
+ if (index < 0) {
+ ret = dpaa2_flow_proto_discrimination_extract(
+ &priv->extract.qos_key_extract,
+ DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS Extract IP protocol to discriminate ICMP failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_IP, NH_FLD_IP_PROTO);
+ if (index < 0) {
+ ret = dpaa2_flow_proto_discrimination_extract(
+ &priv->extract.tc_key_extract[group],
+ DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS Extract IP protocol to discriminate ICMP failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move IP addr before ICMP discrimination set failed");
+ return -1;
+ }
+
+ proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
+ proto.ip_proto = IPPROTO_ICMP;
+ ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
+ proto, group);
+ if (ret) {
+ DPAA2_PMD_ERR("ICMP discrimination rule set failed");
+ return -1;
+ }
+
+ (*device_configured) |= local_cfg;
+
+ return 0;
+ }
+
+ if (dpaa2_flow_extract_support((const uint8_t *)mask,
+ RTE_FLOW_ITEM_TYPE_ICMP)) {
+ DPAA2_PMD_WARN("Extract field(s) of ICMP not support.");
+
+ return -1;
+ }
+
+ if (mask->hdr.icmp_type) {
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_ICMP, NH_FLD_ICMP_TYPE);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.qos_key_extract,
+ NET_PROT_ICMP,
+ NH_FLD_ICMP_TYPE,
+ NH_FLD_ICMP_TYPE_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS Extract add ICMP_TYPE failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_ICMP, NH_FLD_ICMP_TYPE);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.tc_key_extract[group],
+ NET_PROT_ICMP,
+ NH_FLD_ICMP_TYPE,
+ NH_FLD_ICMP_TYPE_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("FS Extract add ICMP_TYPE failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move ipaddr before ICMP TYPE set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.qos_key_extract,
+ &flow->qos_rule,
+ NET_PROT_ICMP,
+ NH_FLD_ICMP_TYPE,
+ &spec->hdr.icmp_type,
+ &mask->hdr.icmp_type,
+ NH_FLD_ICMP_TYPE_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS NH_FLD_ICMP_TYPE rule data set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.tc_key_extract[group],
+ &flow->fs_rule,
+ NET_PROT_ICMP,
+ NH_FLD_ICMP_TYPE,
+ &spec->hdr.icmp_type,
+ &mask->hdr.icmp_type,
+ NH_FLD_ICMP_TYPE_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("FS NH_FLD_ICMP_TYPE rule data set failed");
+ return -1;
+ }
+ }
+
+ if (mask->hdr.icmp_code) {
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_ICMP, NH_FLD_ICMP_CODE);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.qos_key_extract,
+ NET_PROT_ICMP,
+ NH_FLD_ICMP_CODE,
+ NH_FLD_ICMP_CODE_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS Extract add ICMP_CODE failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_ICMP, NH_FLD_ICMP_CODE);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.tc_key_extract[group],
+ NET_PROT_ICMP,
+ NH_FLD_ICMP_CODE,
+ NH_FLD_ICMP_CODE_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("FS Extract add ICMP_CODE failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move ipaddr after ICMP CODE set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.qos_key_extract,
+ &flow->qos_rule,
+ NET_PROT_ICMP,
+ NH_FLD_ICMP_CODE,
+ &spec->hdr.icmp_code,
+ &mask->hdr.icmp_code,
+ NH_FLD_ICMP_CODE_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS NH_FLD_ICMP_CODE rule data set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.tc_key_extract[group],
+ &flow->fs_rule,
+ NET_PROT_ICMP,
+ NH_FLD_ICMP_CODE,
+ &spec->hdr.icmp_code,
+ &mask->hdr.icmp_code,
+ NH_FLD_ICMP_CODE_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("FS NH_FLD_ICMP_CODE rule data set failed");
+ return -1;
+ }
+ }
+
+ (*device_configured) |= local_cfg;
+
+ return 0;
+}
+
+static int
+dpaa2_configure_flow_udp(struct rte_flow *flow,
+ struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item *pattern,
+ const struct rte_flow_action actions[] __rte_unused,
+ struct rte_flow_error *error __rte_unused,
+ int *device_configured)
+{
+ int index, ret;
+ int local_cfg = 0;
+ uint32_t group;
+ const struct rte_flow_item_udp *spec, *mask;
+
+ const struct rte_flow_item_udp *last __rte_unused;
+ struct dpaa2_dev_priv *priv = dev->data->dev_private;
+
+ group = attr->group;
+
+ /* Parse pattern list to get the matching parameters */
+ spec = (const struct rte_flow_item_udp *)pattern->spec;
+ last = (const struct rte_flow_item_udp *)pattern->last;
+ mask = (const struct rte_flow_item_udp *)
+ (pattern->mask ? pattern->mask : &dpaa2_flow_item_udp_mask);
+
+ /* Get traffic class index and flow id to be configured */
+ flow->tc_id = group;
+ flow->tc_index = attr->priority;
+
+ if (!spec || !mc_l4_port_identification) {
+ struct proto_discrimination proto;
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_IP, NH_FLD_IP_PROTO);
+ if (index < 0) {
+ ret = dpaa2_flow_proto_discrimination_extract(
+ &priv->extract.qos_key_extract,
+ DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS Extract IP protocol to discriminate UDP failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_IP, NH_FLD_IP_PROTO);
+ if (index < 0) {
+ ret = dpaa2_flow_proto_discrimination_extract(
+ &priv->extract.tc_key_extract[group],
+ DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS Extract IP protocol to discriminate UDP failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move IP addr before UDP discrimination set failed");
+ return -1;
+ }
+
+ proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
+ proto.ip_proto = IPPROTO_UDP;
+ ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
+ proto, group);
+ if (ret) {
+ DPAA2_PMD_ERR("UDP discrimination rule set failed");
+ return -1;
+ }
+
+ (*device_configured) |= local_cfg;
+
+ if (!spec)
+ return 0;
+ }
+
+ if (dpaa2_flow_extract_support((const uint8_t *)mask,
+ RTE_FLOW_ITEM_TYPE_UDP)) {
+ DPAA2_PMD_WARN("Extract field(s) of UDP not support.");
+
+ return -1;
+ }
+
+ if (mask->hdr.src_port) {
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.qos_key_extract,
+ NET_PROT_UDP,
+ NH_FLD_UDP_PORT_SRC,
+ NH_FLD_UDP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS Extract add UDP_SRC failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.tc_key_extract[group],
+ NET_PROT_UDP,
+ NH_FLD_UDP_PORT_SRC,
+ NH_FLD_UDP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("FS Extract add UDP_SRC failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move ipaddr before UDP_PORT_SRC set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(&priv->extract.qos_key_extract,
+ &flow->qos_rule,
+ NET_PROT_UDP,
+ NH_FLD_UDP_PORT_SRC,
+ &spec->hdr.src_port,
+ &mask->hdr.src_port,
+ NH_FLD_UDP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS NH_FLD_UDP_PORT_SRC rule data set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.tc_key_extract[group],
+ &flow->fs_rule,
+ NET_PROT_UDP,
+ NH_FLD_UDP_PORT_SRC,
+ &spec->hdr.src_port,
+ &mask->hdr.src_port,
+ NH_FLD_UDP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS NH_FLD_UDP_PORT_SRC rule data set failed");
+ return -1;
+ }
+ }
+
+ if (mask->hdr.dst_port) {
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.qos_key_extract,
+ NET_PROT_UDP,
+ NH_FLD_UDP_PORT_DST,
+ NH_FLD_UDP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS Extract add UDP_DST failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.tc_key_extract[group],
+ NET_PROT_UDP,
+ NH_FLD_UDP_PORT_DST,
+ NH_FLD_UDP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("FS Extract add UDP_DST failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move ipaddr before UDP_PORT_DST set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.qos_key_extract,
+ &flow->qos_rule,
+ NET_PROT_UDP,
+ NH_FLD_UDP_PORT_DST,
+ &spec->hdr.dst_port,
+ &mask->hdr.dst_port,
+ NH_FLD_UDP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS NH_FLD_UDP_PORT_DST rule data set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.tc_key_extract[group],
+ &flow->fs_rule,
+ NET_PROT_UDP,
+ NH_FLD_UDP_PORT_DST,
+ &spec->hdr.dst_port,
+ &mask->hdr.dst_port,
+ NH_FLD_UDP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS NH_FLD_UDP_PORT_DST rule data set failed");
+ return -1;
+ }
+ }
+
+ (*device_configured) |= local_cfg;
+
+ return 0;
+}
+
+static int
+dpaa2_configure_flow_tcp(struct rte_flow *flow,
+ struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item *pattern,
+ const struct rte_flow_action actions[] __rte_unused,
+ struct rte_flow_error *error __rte_unused,
+ int *device_configured)
+{
+ int index, ret;
+ int local_cfg = 0;
+ uint32_t group;
+ const struct rte_flow_item_tcp *spec, *mask;
+
+ const struct rte_flow_item_tcp *last __rte_unused;
+ struct dpaa2_dev_priv *priv = dev->data->dev_private;
+
+ group = attr->group;
+
+ /* Parse pattern list to get the matching parameters */
+ spec = (const struct rte_flow_item_tcp *)pattern->spec;
+ last = (const struct rte_flow_item_tcp *)pattern->last;
+ mask = (const struct rte_flow_item_tcp *)
+ (pattern->mask ? pattern->mask : &dpaa2_flow_item_tcp_mask);
+
+ /* Get traffic class index and flow id to be configured */
+ flow->tc_id = group;
+ flow->tc_index = attr->priority;
+
+ if (!spec || !mc_l4_port_identification) {
+ struct proto_discrimination proto;
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_IP, NH_FLD_IP_PROTO);
+ if (index < 0) {
+ ret = dpaa2_flow_proto_discrimination_extract(
+ &priv->extract.qos_key_extract,
+ DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS Extract IP protocol to discriminate TCP failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_IP, NH_FLD_IP_PROTO);
+ if (index < 0) {
+ ret = dpaa2_flow_proto_discrimination_extract(
+ &priv->extract.tc_key_extract[group],
+ DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS Extract IP protocol to discriminate TCP failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move IP addr before TCP discrimination set failed");
+ return -1;
+ }
+
+ proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
+ proto.ip_proto = IPPROTO_TCP;
+ ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
+ proto, group);
+ if (ret) {
+ DPAA2_PMD_ERR("TCP discrimination rule set failed");
+ return -1;
+ }
+
+ (*device_configured) |= local_cfg;
+
+ if (!spec)
+ return 0;
+ }
+
+ if (dpaa2_flow_extract_support((const uint8_t *)mask,
+ RTE_FLOW_ITEM_TYPE_TCP)) {
+ DPAA2_PMD_WARN("Extract field(s) of TCP not support.");
+
+ return -1;
+ }
+
+ if (mask->hdr.src_port) {
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_TCP, NH_FLD_TCP_PORT_SRC);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.qos_key_extract,
+ NET_PROT_TCP,
+ NH_FLD_TCP_PORT_SRC,
+ NH_FLD_TCP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS Extract add TCP_SRC failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_TCP, NH_FLD_TCP_PORT_SRC);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.tc_key_extract[group],
+ NET_PROT_TCP,
+ NH_FLD_TCP_PORT_SRC,
+ NH_FLD_TCP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("FS Extract add TCP_SRC failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move ipaddr before TCP_PORT_SRC set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.qos_key_extract,
+ &flow->qos_rule,
+ NET_PROT_TCP,
+ NH_FLD_TCP_PORT_SRC,
+ &spec->hdr.src_port,
+ &mask->hdr.src_port,
+ NH_FLD_TCP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS NH_FLD_TCP_PORT_SRC rule data set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.tc_key_extract[group],
+ &flow->fs_rule,
+ NET_PROT_TCP,
+ NH_FLD_TCP_PORT_SRC,
+ &spec->hdr.src_port,
+ &mask->hdr.src_port,
+ NH_FLD_TCP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS NH_FLD_TCP_PORT_SRC rule data set failed");
+ return -1;
+ }
+ }
+
+ if (mask->hdr.dst_port) {
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_TCP, NH_FLD_TCP_PORT_DST);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.qos_key_extract,
+ NET_PROT_TCP,
+ NH_FLD_TCP_PORT_DST,
+ NH_FLD_TCP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS Extract add TCP_DST failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_TCP, NH_FLD_TCP_PORT_DST);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.tc_key_extract[group],
+ NET_PROT_TCP,
+ NH_FLD_TCP_PORT_DST,
+ NH_FLD_TCP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("FS Extract add TCP_DST failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move ipaddr before TCP_PORT_DST set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.qos_key_extract,
+ &flow->qos_rule,
+ NET_PROT_TCP,
+ NH_FLD_TCP_PORT_DST,
+ &spec->hdr.dst_port,
+ &mask->hdr.dst_port,
+ NH_FLD_TCP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS NH_FLD_TCP_PORT_DST rule data set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.tc_key_extract[group],
+ &flow->fs_rule,
+ NET_PROT_TCP,
+ NH_FLD_TCP_PORT_DST,
+ &spec->hdr.dst_port,
+ &mask->hdr.dst_port,
+ NH_FLD_TCP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS NH_FLD_TCP_PORT_DST rule data set failed");
+ return -1;
+ }
+ }
+
+ (*device_configured) |= local_cfg;
+
+ return 0;
+}
+
+static int
+dpaa2_configure_flow_sctp(struct rte_flow *flow,
+ struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item *pattern,
+ const struct rte_flow_action actions[] __rte_unused,
+ struct rte_flow_error *error __rte_unused,
+ int *device_configured)
+{
+ int index, ret;
+ int local_cfg = 0;
+ uint32_t group;
+ const struct rte_flow_item_sctp *spec, *mask;
+
+ const struct rte_flow_item_sctp *last __rte_unused;
+ struct dpaa2_dev_priv *priv = dev->data->dev_private;
+
+ group = attr->group;
+
+ /* Parse pattern list to get the matching parameters */
+ spec = (const struct rte_flow_item_sctp *)pattern->spec;
+ last = (const struct rte_flow_item_sctp *)pattern->last;
+ mask = (const struct rte_flow_item_sctp *)
+ (pattern->mask ? pattern->mask :
+ &dpaa2_flow_item_sctp_mask);
+
+ /* Get traffic class index and flow id to be configured */
+ flow->tc_id = group;
+ flow->tc_index = attr->priority;
+
+ if (!spec || !mc_l4_port_identification) {
+ struct proto_discrimination proto;
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_IP, NH_FLD_IP_PROTO);
+ if (index < 0) {
+ ret = dpaa2_flow_proto_discrimination_extract(
+ &priv->extract.qos_key_extract,
+ DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS Extract IP protocol to discriminate SCTP failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_IP, NH_FLD_IP_PROTO);
+ if (index < 0) {
+ ret = dpaa2_flow_proto_discrimination_extract(
+ &priv->extract.tc_key_extract[group],
+ DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS Extract IP protocol to discriminate SCTP failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move ipaddr before SCTP discrimination set failed");
+ return -1;
+ }
+
+ proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
+ proto.ip_proto = IPPROTO_SCTP;
+ ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
+ proto, group);
+ if (ret) {
+ DPAA2_PMD_ERR("SCTP discrimination rule set failed");
+ return -1;
+ }
+
+ (*device_configured) |= local_cfg;
+
+ if (!spec)
+ return 0;
+ }
+
+ if (dpaa2_flow_extract_support((const uint8_t *)mask,
+ RTE_FLOW_ITEM_TYPE_SCTP)) {
+ DPAA2_PMD_WARN("Extract field(s) of SCTP not support.");
+
+ return -1;
+ }
+
+ if (mask->hdr.src_port) {
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_SCTP, NH_FLD_SCTP_PORT_SRC);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.qos_key_extract,
+ NET_PROT_SCTP,
+ NH_FLD_SCTP_PORT_SRC,
+ NH_FLD_SCTP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS Extract add SCTP_SRC failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_SCTP, NH_FLD_SCTP_PORT_SRC);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.tc_key_extract[group],
+ NET_PROT_SCTP,
+ NH_FLD_SCTP_PORT_SRC,
+ NH_FLD_SCTP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("FS Extract add SCTP_SRC failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move ipaddr before SCTP_PORT_SRC set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.qos_key_extract,
+ &flow->qos_rule,
+ NET_PROT_SCTP,
+ NH_FLD_SCTP_PORT_SRC,
+ &spec->hdr.src_port,
+ &mask->hdr.src_port,
+ NH_FLD_SCTP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS NH_FLD_SCTP_PORT_SRC rule data set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.tc_key_extract[group],
+ &flow->fs_rule,
+ NET_PROT_SCTP,
+ NH_FLD_SCTP_PORT_SRC,
+ &spec->hdr.src_port,
+ &mask->hdr.src_port,
+ NH_FLD_SCTP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS NH_FLD_SCTP_PORT_SRC rule data set failed");
+ return -1;
+ }
+ }
+
+ if (mask->hdr.dst_port) {
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_SCTP, NH_FLD_SCTP_PORT_DST);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.qos_key_extract,
+ NET_PROT_SCTP,
+ NH_FLD_SCTP_PORT_DST,
+ NH_FLD_SCTP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS Extract add SCTP_DST failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_SCTP, NH_FLD_SCTP_PORT_DST);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.tc_key_extract[group],
+ NET_PROT_SCTP,
+ NH_FLD_SCTP_PORT_DST,
+ NH_FLD_SCTP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR("FS Extract add SCTP_DST failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move ipaddr before SCTP_PORT_DST set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.qos_key_extract,
+ &flow->qos_rule,
+ NET_PROT_SCTP,
+ NH_FLD_SCTP_PORT_DST,
+ &spec->hdr.dst_port,
+ &mask->hdr.dst_port,
+ NH_FLD_SCTP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS NH_FLD_SCTP_PORT_DST rule data set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.tc_key_extract[group],
+ &flow->fs_rule,
+ NET_PROT_SCTP,
+ NH_FLD_SCTP_PORT_DST,
+ &spec->hdr.dst_port,
+ &mask->hdr.dst_port,
+ NH_FLD_SCTP_PORT_SIZE);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS NH_FLD_SCTP_PORT_DST rule data set failed");
+ return -1;
+ }
+ }
+
+ (*device_configured) |= local_cfg;
+
+ return 0;
+}
+
+static int
+dpaa2_configure_flow_gre(struct rte_flow *flow,
+ struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item *pattern,
+ const struct rte_flow_action actions[] __rte_unused,
+ struct rte_flow_error *error __rte_unused,
+ int *device_configured)
+{
+ int index, ret;
+ int local_cfg = 0;
+ uint32_t group;
+ const struct rte_flow_item_gre *spec, *mask;
+
+ const struct rte_flow_item_gre *last __rte_unused;
+ struct dpaa2_dev_priv *priv = dev->data->dev_private;
+
+ group = attr->group;
+
+ /* Parse pattern list to get the matching parameters */
+ spec = (const struct rte_flow_item_gre *)pattern->spec;
+ last = (const struct rte_flow_item_gre *)pattern->last;
+ mask = (const struct rte_flow_item_gre *)
+ (pattern->mask ? pattern->mask : &dpaa2_flow_item_gre_mask);
+
+ /* Get traffic class index and flow id to be configured */
+ flow->tc_id = group;
+ flow->tc_index = attr->priority;
+
+ if (!spec) {
+ struct proto_discrimination proto;
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_IP, NH_FLD_IP_PROTO);
+ if (index < 0) {
+ ret = dpaa2_flow_proto_discrimination_extract(
+ &priv->extract.qos_key_extract,
+ DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS Extract IP protocol to discriminate GRE failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_IP, NH_FLD_IP_PROTO);
+ if (index < 0) {
+ ret = dpaa2_flow_proto_discrimination_extract(
+ &priv->extract.tc_key_extract[group],
+ DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS Extract IP protocol to discriminate GRE failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move IP addr before GRE discrimination set failed");
+ return -1;
+ }
+
+ proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
+ proto.ip_proto = IPPROTO_GRE;
+ ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
+ proto, group);
+ if (ret) {
+ DPAA2_PMD_ERR("GRE discrimination rule set failed");
+ return -1;
+ }
+
+ (*device_configured) |= local_cfg;
+
+ return 0;
+ }
+
+ if (dpaa2_flow_extract_support((const uint8_t *)mask,
+ RTE_FLOW_ITEM_TYPE_GRE)) {
+ DPAA2_PMD_WARN("Extract field(s) of GRE not support.");
+
+ return -1;
+ }
+
+ if (!mask->protocol)
+ return 0;
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.qos_key_extract.dpkg,
+ NET_PROT_GRE, NH_FLD_GRE_TYPE);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.qos_key_extract,
+ NET_PROT_GRE,
+ NH_FLD_GRE_TYPE,
+ sizeof(rte_be16_t));
+ if (ret) {
+ DPAA2_PMD_ERR("QoS Extract add GRE_TYPE failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+ }
+
+ index = dpaa2_flow_extract_search(
+ &priv->extract.tc_key_extract[group].dpkg,
+ NET_PROT_GRE, NH_FLD_GRE_TYPE);
+ if (index < 0) {
+ ret = dpaa2_flow_extract_add(
+ &priv->extract.tc_key_extract[group],
+ NET_PROT_GRE,
+ NH_FLD_GRE_TYPE,
+ sizeof(rte_be16_t));
+ if (ret) {
+ DPAA2_PMD_ERR("FS Extract add GRE_TYPE failed.");
+
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "Move ipaddr before GRE_TYPE set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.qos_key_extract,
+ &flow->qos_rule,
+ NET_PROT_GRE,
+ NH_FLD_GRE_TYPE,
+ &spec->protocol,
+ &mask->protocol,
+ sizeof(rte_be16_t));
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "QoS NH_FLD_GRE_TYPE rule data set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set(
+ &priv->extract.tc_key_extract[group],
+ &flow->fs_rule,
+ NET_PROT_GRE,
+ NH_FLD_GRE_TYPE,
+ &spec->protocol,
+ &mask->protocol,
+ sizeof(rte_be16_t));
+ if (ret) {
+ DPAA2_PMD_ERR(
+ "FS NH_FLD_GRE_TYPE rule data set failed");
+ return -1;
+ }
+
+ (*device_configured) |= local_cfg;
+
+ return 0;
+}
+
+static int
+dpaa2_configure_flow_raw(struct rte_flow *flow,
+ struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item *pattern,
+ const struct rte_flow_action actions[] __rte_unused,
+ struct rte_flow_error *error __rte_unused,
+ int *device_configured)
+{
+ struct dpaa2_dev_priv *priv = dev->data->dev_private;
+ const struct rte_flow_item_raw *spec = pattern->spec;
+ const struct rte_flow_item_raw *mask = pattern->mask;
+ int prev_key_size =
+ priv->extract.qos_key_extract.key_info.key_total_size;
+ int local_cfg = 0, ret;
+ uint32_t group;
+
+ /* Need both spec and mask */
+ if (!spec || !mask) {
+ DPAA2_PMD_ERR("spec or mask not present.");
+ return -EINVAL;
+ }
+ /* Only supports non-relative with offset 0 */
+ if (spec->relative || spec->offset != 0 ||
+ spec->search || spec->limit) {
+ DPAA2_PMD_ERR("relative and non zero offset not supported.");
+ return -EINVAL;
+ }
+ /* Spec len and mask len should be same */
+ if (spec->length != mask->length) {
+ DPAA2_PMD_ERR("Spec len and mask len mismatch.");
+ return -EINVAL;
+ }
+
+ /* Get traffic class index and flow id to be configured */
+ group = attr->group;
+ flow->tc_id = group;
+ flow->tc_index = attr->priority;
+
+ if (prev_key_size <= spec->length) {
+ ret = dpaa2_flow_extract_add_raw(&priv->extract.qos_key_extract,
+ spec->length);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS Extract RAW add failed.");
+ return -1;
+ }
+ local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
+
+ ret = dpaa2_flow_extract_add_raw(
+ &priv->extract.tc_key_extract[group],
+ spec->length);
+ if (ret) {
+ DPAA2_PMD_ERR("FS Extract RAW add failed.");
+ return -1;
+ }
+ local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
+ }
+
+ ret = dpaa2_flow_rule_data_set_raw(&flow->qos_rule, spec->pattern,
+ mask->pattern, spec->length);
+ if (ret) {
+ DPAA2_PMD_ERR("QoS RAW rule data set failed");
+ return -1;
+ }
+
+ ret = dpaa2_flow_rule_data_set_raw(&flow->fs_rule, spec->pattern,
+ mask->pattern, spec->length);
+ if (ret) {
+ DPAA2_PMD_ERR("FS RAW rule data set failed");
+ return -1;
+ }
+
+ (*device_configured) |= local_cfg;
+
+ return 0;
+}
+
+static inline int
+dpaa2_fs_action_supported(enum rte_flow_action_type action)
+{
+ int i;
+
+ for (i = 0; i < (int)(sizeof(dpaa2_supported_fs_action_type) /
+ sizeof(enum rte_flow_action_type)); i++) {
+ if (action == dpaa2_supported_fs_action_type[i])
+ return 1;
+ }
+
+ return 0;
+}
+/* The existing QoS/FS entry with IP address(es)
+ * needs update after
+ * new extract(s) are inserted before IP
+ * address(es) extract(s).
+ */
+static int
+dpaa2_flow_entry_update(
+ struct dpaa2_dev_priv *priv, uint8_t tc_id)
+{
+ struct rte_flow *curr = LIST_FIRST(&priv->flows);
+ struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+ int ret;
+ int qos_ipsrc_offset = -1, qos_ipdst_offset = -1;
+ int fs_ipsrc_offset = -1, fs_ipdst_offset = -1;
+ struct dpaa2_key_extract *qos_key_extract =
+ &priv->extract.qos_key_extract;
+ struct dpaa2_key_extract *tc_key_extract =
+ &priv->extract.tc_key_extract[tc_id];
+ char ipsrc_key[NH_FLD_IPV6_ADDR_SIZE];
+ char ipdst_key[NH_FLD_IPV6_ADDR_SIZE];
+ char ipsrc_mask[NH_FLD_IPV6_ADDR_SIZE];
+ char ipdst_mask[NH_FLD_IPV6_ADDR_SIZE];
+ int extend = -1, extend1, size = -1;
+ uint16_t qos_index;
+
+ while (curr) {
+ if (curr->ipaddr_rule.ipaddr_type ==
+ FLOW_NONE_IPADDR) {
+ curr = LIST_NEXT(curr, next);
+ continue;
+ }
+
+ if (curr->ipaddr_rule.ipaddr_type ==
+ FLOW_IPV4_ADDR) {
+ qos_ipsrc_offset =
+ qos_key_extract->key_info.ipv4_src_offset;
+ qos_ipdst_offset =
+ qos_key_extract->key_info.ipv4_dst_offset;
+ fs_ipsrc_offset =
+ tc_key_extract->key_info.ipv4_src_offset;
+ fs_ipdst_offset =
+ tc_key_extract->key_info.ipv4_dst_offset;
+ size = NH_FLD_IPV4_ADDR_SIZE;
+ } else {
+ qos_ipsrc_offset =
+ qos_key_extract->key_info.ipv6_src_offset;
+ qos_ipdst_offset =
+ qos_key_extract->key_info.ipv6_dst_offset;
+ fs_ipsrc_offset =
+ tc_key_extract->key_info.ipv6_src_offset;
+ fs_ipdst_offset =
+ tc_key_extract->key_info.ipv6_dst_offset;
+ size = NH_FLD_IPV6_ADDR_SIZE;
+ }
+
+ qos_index = curr->tc_id * priv->fs_entries +
+ curr->tc_index;
+
+ dpaa2_flow_qos_entry_log("Before update", curr, qos_index);
+
+ if (priv->num_rx_tc > 1) {
+ ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW,
+ priv->token, &curr->qos_rule);
+ if (ret) {
+ DPAA2_PMD_ERR("Qos entry remove failed.");
+ return -1;
+ }
+ }
+
+ extend = -1;
+
+ if (curr->ipaddr_rule.qos_ipsrc_offset >= 0) {
+ RTE_ASSERT(qos_ipsrc_offset >=
+ curr->ipaddr_rule.qos_ipsrc_offset);
+ extend1 = qos_ipsrc_offset -
+ curr->ipaddr_rule.qos_ipsrc_offset;
+ if (extend >= 0)
+ RTE_ASSERT(extend == extend1);
+ else
+ extend = extend1;
+
+ RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
+ (size == NH_FLD_IPV6_ADDR_SIZE));
+
+ memcpy(ipsrc_key,
+ (char *)(size_t)curr->qos_rule.key_iova +
+ curr->ipaddr_rule.qos_ipsrc_offset,
+ size);
+ memset((char *)(size_t)curr->qos_rule.key_iova +
+ curr->ipaddr_rule.qos_ipsrc_offset,
+ 0, size);
+
+ memcpy(ipsrc_mask,
+ (char *)(size_t)curr->qos_rule.mask_iova +
+ curr->ipaddr_rule.qos_ipsrc_offset,
+ size);
+ memset((char *)(size_t)curr->qos_rule.mask_iova +
+ curr->ipaddr_rule.qos_ipsrc_offset,
+ 0, size);
+
+ curr->ipaddr_rule.qos_ipsrc_offset = qos_ipsrc_offset;
+ }
+
+ if (curr->ipaddr_rule.qos_ipdst_offset >= 0) {
+ RTE_ASSERT(qos_ipdst_offset >=
+ curr->ipaddr_rule.qos_ipdst_offset);
+ extend1 = qos_ipdst_offset -
+ curr->ipaddr_rule.qos_ipdst_offset;
+ if (extend >= 0)
+ RTE_ASSERT(extend == extend1);
+ else
+ extend = extend1;
+
+ RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
+ (size == NH_FLD_IPV6_ADDR_SIZE));
+
+ memcpy(ipdst_key,
+ (char *)(size_t)curr->qos_rule.key_iova +
+ curr->ipaddr_rule.qos_ipdst_offset,
+ size);
+ memset((char *)(size_t)curr->qos_rule.key_iova +
+ curr->ipaddr_rule.qos_ipdst_offset,
+ 0, size);
+
+ memcpy(ipdst_mask,
+ (char *)(size_t)curr->qos_rule.mask_iova +
+ curr->ipaddr_rule.qos_ipdst_offset,
+ size);
+ memset((char *)(size_t)curr->qos_rule.mask_iova +
+ curr->ipaddr_rule.qos_ipdst_offset,
+ 0, size);
+
+ curr->ipaddr_rule.qos_ipdst_offset = qos_ipdst_offset;
+ }
+
+ if (curr->ipaddr_rule.qos_ipsrc_offset >= 0) {
+ RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
+ (size == NH_FLD_IPV6_ADDR_SIZE));
+ memcpy((char *)(size_t)curr->qos_rule.key_iova +
+ curr->ipaddr_rule.qos_ipsrc_offset,
+ ipsrc_key,
+ size);
+ memcpy((char *)(size_t)curr->qos_rule.mask_iova +
+ curr->ipaddr_rule.qos_ipsrc_offset,
+ ipsrc_mask,
+ size);
+ }
+ if (curr->ipaddr_rule.qos_ipdst_offset >= 0) {
+ RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
+ (size == NH_FLD_IPV6_ADDR_SIZE));
+ memcpy((char *)(size_t)curr->qos_rule.key_iova +
+ curr->ipaddr_rule.qos_ipdst_offset,
+ ipdst_key,
+ size);
+ memcpy((char *)(size_t)curr->qos_rule.mask_iova +
+ curr->ipaddr_rule.qos_ipdst_offset,
+ ipdst_mask,
+ size);
+ }
+
+ if (extend >= 0)
+ curr->qos_real_key_size += extend;
+
+ curr->qos_rule.key_size = FIXED_ENTRY_SIZE;
+
+ dpaa2_flow_qos_entry_log("Start update", curr, qos_index);
+
+ if (priv->num_rx_tc > 1) {
+ ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
+ priv->token, &curr->qos_rule,
+ curr->tc_id, qos_index,
+ 0, 0);
+ if (ret) {
+ DPAA2_PMD_ERR("Qos entry update failed.");
+ return -1;
+ }
+ }
+
+ if (!dpaa2_fs_action_supported(curr->action)) {
+ curr = LIST_NEXT(curr, next);