Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(C) 2024 Marvell. 3 : : */ 4 : : 5 : : #include "cn20k_ethdev.h" 6 : : #include "cn20k_rx.h" 7 : : #include "cnxk_ethdev_mcs.h" 8 : : #include "cnxk_flow_common.h" 9 : : #include <cn20k_flow.h> 10 : : #include <cnxk_flow.h> 11 : : 12 : : struct rte_flow * 13 : 0 : cn20k_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, 14 : : const struct rte_flow_item pattern[], const struct rte_flow_action actions[], 15 : : struct rte_flow_error *error) 16 : : { 17 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); 18 : 0 : struct roc_npc *npc = &dev->npc; 19 : : struct roc_npc_flow *flow; 20 : : int vtag_actions = 0; 21 : : int mark_actions; 22 : : 23 : 0 : flow = cnxk_flow_create(eth_dev, attr, pattern, actions, error); 24 : : 25 [ # # ]: 0 : if (!flow) 26 : : return NULL; 27 : : 28 : 0 : mark_actions = roc_npc_mark_actions_get(npc); 29 [ # # ]: 0 : if (mark_actions) { 30 : 0 : dev->rx_offload_flags |= NIX_RX_OFFLOAD_MARK_UPDATE_F; 31 : 0 : cn20k_eth_set_rx_function(eth_dev); 32 : : } 33 : : 34 : 0 : vtag_actions = roc_npc_vtag_actions_get(npc); 35 : : 36 [ # # ]: 0 : if (vtag_actions) { 37 : 0 : dev->rx_offload_flags |= NIX_RX_OFFLOAD_VLAN_STRIP_F; 38 : 0 : cn20k_eth_set_rx_function(eth_dev); 39 : : } 40 : : 41 : : return (struct rte_flow *)flow; 42 : : } 43 : : 44 : : int 45 : 0 : cn20k_flow_info_get(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info, 46 : : struct rte_flow_queue_info *queue_info, struct rte_flow_error *err) 47 : : { 48 : 0 : return cnxk_flow_info_get_common(dev, port_info, queue_info, err); 49 : : } 50 : : 51 : : int 52 : 0 : cn20k_flow_push(struct rte_eth_dev *eth_dev, uint32_t queue, struct rte_flow_error *error) 53 : : { 54 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); 55 : 0 : struct roc_npc *npc = &dev->npc; 56 : : bool reset_rx = false; 57 : : int rc; 58 : : 59 : : /* Flush the pending async ops to hardware first. */ 60 : 0 : rc = cnxk_flow_push(eth_dev, queue, error); 61 [ # # ]: 0 : if (rc) 62 : : return rc; 63 : : 64 : : /* Async push, unlike sync create/destroy, does not toggle the MARK and 65 : : * VLAN-strip RX offloads; reconcile each with its refcount so the Rx 66 : : * function matches the live rules. 67 : : */ 68 [ # # ]: 0 : if (roc_npc_mark_actions_get(npc) && 69 [ # # ]: 0 : !(dev->rx_offload_flags & NIX_RX_OFFLOAD_MARK_UPDATE_F)) { 70 : 0 : dev->rx_offload_flags |= NIX_RX_OFFLOAD_MARK_UPDATE_F; 71 : 0 : reset_rx = true; 72 [ # # ]: 0 : } else if (!roc_npc_mark_actions_get(npc) && 73 [ # # ]: 0 : (dev->rx_offload_flags & NIX_RX_OFFLOAD_MARK_UPDATE_F)) { 74 : 0 : dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_MARK_UPDATE_F; 75 : : reset_rx = true; 76 : : } 77 : : 78 [ # # ]: 0 : if (roc_npc_vtag_actions_get(npc) && 79 [ # # ]: 0 : !(dev->rx_offload_flags & NIX_RX_OFFLOAD_VLAN_STRIP_F)) { 80 : 0 : dev->rx_offload_flags |= NIX_RX_OFFLOAD_VLAN_STRIP_F; 81 : : reset_rx = true; 82 [ # # ]: 0 : } else if (!roc_npc_vtag_actions_get(npc) && 83 [ # # ]: 0 : (dev->rx_offload_flags & NIX_RX_OFFLOAD_VLAN_STRIP_F)) { 84 : 0 : dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_VLAN_STRIP_F; 85 : : reset_rx = true; 86 : : } 87 : : 88 [ # # ]: 0 : if (reset_rx) 89 : 0 : cn20k_eth_set_rx_function(eth_dev); 90 : : 91 : : return 0; 92 : : } 93 : : 94 : : int 95 [ # # ]: 0 : cn20k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow, 96 : : struct rte_flow_error *error) 97 : : { 98 : : struct roc_npc_flow *flow = (struct roc_npc_flow *)rte_flow; 99 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); 100 : 0 : struct roc_npc *npc = &dev->npc; 101 : : int vtag_actions = 0, rc = 0; 102 : : int mark_actions; 103 : : uint16_t match_id; 104 : : uint32_t mtr_id; 105 : : 106 : 0 : match_id = (flow->npc_action >> NPC_RX_ACT_MATCH_OFFSET) & NPC_RX_ACT_MATCH_MASK; 107 [ # # ]: 0 : if (match_id) { 108 : 0 : mark_actions = roc_npc_mark_actions_sub_return(npc, 1); 109 [ # # ]: 0 : if (mark_actions == 0) { 110 : 0 : dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_MARK_UPDATE_F; 111 : 0 : cn20k_eth_set_rx_function(eth_dev); 112 : : } 113 : : } 114 : : 115 : 0 : vtag_actions = roc_npc_vtag_actions_get(npc); 116 [ # # ]: 0 : if (vtag_actions) { 117 [ # # ]: 0 : if (flow->nix_intf == ROC_NPC_INTF_RX) { 118 : 0 : vtag_actions = roc_npc_vtag_actions_sub_return(npc, 1); 119 [ # # ]: 0 : if (vtag_actions == 0) { 120 : 0 : dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_VLAN_STRIP_F; 121 : 0 : cn20k_eth_set_rx_function(eth_dev); 122 : : } 123 : : } 124 : : } 125 : : 126 [ # # ]: 0 : if (cnxk_eth_macsec_sess_get_by_sess(dev, (void *)flow) != NULL) { 127 : 0 : rc = cnxk_mcs_flow_destroy(dev, (void *)flow); 128 [ # # ]: 0 : if (rc < 0) 129 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 130 : : "Failed to free mcs flow"); 131 : 0 : return rc; 132 : : } 133 : : 134 : 0 : mtr_id = flow->mtr_id; 135 : 0 : rc = cnxk_flow_destroy(eth_dev, flow, error); 136 [ # # ]: 0 : if (!rc && mtr_id != ROC_NIX_MTR_ID_INVALID) { 137 : 0 : rc = cnxk_mtr_destroy(eth_dev, mtr_id); 138 [ # # ]: 0 : if (rc) { 139 : 0 : rte_flow_error_set(error, ENXIO, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 140 : : "Meter attached to this flow does not exist"); 141 : : } 142 : : } 143 : : return rc; 144 : : }