// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2021-2023, Intel Corporation. */ #include "ice.h" #include "ice_base.h" #include "ice_lib.h" #include "ice_flow.h" #include "ice_vf_lib_private.h" #define to_fltr_conf_from_desc(p) … #define GTPU_TEID_OFFSET … #define GTPU_EH_QFI_OFFSET … #define GTPU_EH_QFI_MASK … #define PFCP_S_OFFSET … #define PFCP_S_MASK … #define PFCP_PORT_NR … #define FDIR_INSET_FLAG_ESP_S … #define FDIR_INSET_FLAG_ESP_M … #define FDIR_INSET_FLAG_ESP_UDP … #define FDIR_INSET_FLAG_ESP_IPSEC … enum ice_fdir_tunnel_type { … }; struct virtchnl_fdir_fltr_conf { … }; struct virtchnl_fdir_inset_map { … }; static const struct virtchnl_fdir_inset_map fdir_inset_map[] = …; /** * ice_vc_fdir_param_check * @vf: pointer to the VF structure * @vsi_id: VF relative VSI ID * * Check for the valid VSI ID, PF's state and VF's state * * Return: 0 on success, and -EINVAL on error. */ static int ice_vc_fdir_param_check(struct ice_vf *vf, u16 vsi_id) { … } /** * ice_vf_start_ctrl_vsi * @vf: pointer to the VF structure * * Allocate ctrl_vsi for the first time and open the ctrl_vsi port for VF * * Return: 0 on success, and other on error. */ static int ice_vf_start_ctrl_vsi(struct ice_vf *vf) { … } /** * ice_vc_fdir_alloc_prof - allocate profile for this filter flow type * @vf: pointer to the VF structure * @flow: filter flow type * * Return: 0 on success, and other on error. */ static int ice_vc_fdir_alloc_prof(struct ice_vf *vf, enum ice_fltr_ptype flow) { … } /** * ice_vc_fdir_free_prof - free profile for this filter flow type * @vf: pointer to the VF structure * @flow: filter flow type */ static void ice_vc_fdir_free_prof(struct ice_vf *vf, enum ice_fltr_ptype flow) { … } /** * ice_vc_fdir_free_prof_all - free all the profile for this VF * @vf: pointer to the VF structure */ static void ice_vc_fdir_free_prof_all(struct ice_vf *vf) { … } /** * ice_vc_fdir_parse_flow_fld * @proto_hdr: virtual channel protocol filter header * @conf: FDIR configuration for each filter * @fld: field type array * @fld_cnt: field counter * * Parse the virtual channel filter header and store them into field type array * * Return: 0 on success, and other on error. */ static int ice_vc_fdir_parse_flow_fld(struct virtchnl_proto_hdr *proto_hdr, struct virtchnl_fdir_fltr_conf *conf, enum ice_flow_field *fld, int *fld_cnt) { … } /** * ice_vc_fdir_set_flow_fld * @vf: pointer to the VF structure * @fltr: virtual channel add cmd buffer * @conf: FDIR configuration for each filter * @seg: array of one or more packet segments that describe the flow * * Parse the virtual channel add msg buffer's field vector and store them into * flow's packet segment field * * Return: 0 on success, and other on error. */ static int ice_vc_fdir_set_flow_fld(struct ice_vf *vf, struct virtchnl_fdir_add *fltr, struct virtchnl_fdir_fltr_conf *conf, struct ice_flow_seg_info *seg) { … } /** * ice_vc_fdir_set_flow_hdr - config the flow's packet segment header * @vf: pointer to the VF structure * @conf: FDIR configuration for each filter * @seg: array of one or more packet segments that describe the flow * * Return: 0 on success, and other on error. */ static int ice_vc_fdir_set_flow_hdr(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf, struct ice_flow_seg_info *seg) { … } /** * ice_vc_fdir_rem_prof - remove profile for this filter flow type * @vf: pointer to the VF structure * @flow: filter flow type * @tun: 0 implies non-tunnel type filter, 1 implies tunnel type filter */ static void ice_vc_fdir_rem_prof(struct ice_vf *vf, enum ice_fltr_ptype flow, int tun) { … } /** * ice_vc_fdir_rem_prof_all - remove profile for this VF * @vf: pointer to the VF structure */ static void ice_vc_fdir_rem_prof_all(struct ice_vf *vf) { … } /** * ice_vc_fdir_reset_cnt_all - reset all FDIR counters for this VF FDIR * @fdir: pointer to the VF FDIR structure */ static void ice_vc_fdir_reset_cnt_all(struct ice_vf_fdir *fdir) { … } /** * ice_vc_fdir_has_prof_conflict * @vf: pointer to the VF structure * @conf: FDIR configuration for each filter * * Check if @conf has conflicting profile with existing profiles * * Return: true on success, and false on error. */ static bool ice_vc_fdir_has_prof_conflict(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf) { … } /** * ice_vc_fdir_write_flow_prof * @vf: pointer to the VF structure * @flow: filter flow type * @seg: array of one or more packet segments that describe the flow * @tun: 0 implies non-tunnel type filter, 1 implies tunnel type filter * * Write the flow's profile config and packet segment into the hardware * * Return: 0 on success, and other on error. */ static int ice_vc_fdir_write_flow_prof(struct ice_vf *vf, enum ice_fltr_ptype flow, struct ice_flow_seg_info *seg, int tun) { … } /** * ice_vc_fdir_config_input_set * @vf: pointer to the VF structure * @fltr: virtual channel add cmd buffer * @conf: FDIR configuration for each filter * @tun: 0 implies non-tunnel type filter, 1 implies tunnel type filter * * Config the input set type and value for virtual channel add msg buffer * * Return: 0 on success, and other on error. */ static int ice_vc_fdir_config_input_set(struct ice_vf *vf, struct virtchnl_fdir_add *fltr, struct virtchnl_fdir_fltr_conf *conf, int tun) { … } /** * ice_vc_fdir_is_raw_flow - check if FDIR flow is raw (binary) * @proto: virtchnl protocol headers * * Check if the FDIR rule is raw flow (protocol agnostic flow) or not. Note * that common FDIR rule must have non-zero proto->count. Thus, we choose the * tunnel_level and count of proto as the indicators. If both tunnel_level and * count of proto are zero, this FDIR rule will be regarded as raw flow. * * Returns: true if headers describe raw flow, false otherwise. */ static bool ice_vc_fdir_is_raw_flow(struct virtchnl_proto_hdrs *proto) { … } /** * ice_vc_fdir_parse_raw - parse a virtchnl raw FDIR rule * @vf: pointer to the VF info * @proto: virtchnl protocol headers * @conf: FDIR configuration for each filter * * Parse the virtual channel filter's raw flow and store it in @conf * * Return: 0 on success or negative errno on failure. */ static int ice_vc_fdir_parse_raw(struct ice_vf *vf, struct virtchnl_proto_hdrs *proto, struct virtchnl_fdir_fltr_conf *conf) { … } /** * ice_vc_fdir_parse_pattern * @vf: pointer to the VF info * @fltr: virtual channel add cmd buffer * @conf: FDIR configuration for each filter * * Parse the virtual channel filter's pattern and store them into conf * * Return: 0 on success, and other on error. */ static int ice_vc_fdir_parse_pattern(struct ice_vf *vf, struct virtchnl_fdir_add *fltr, struct virtchnl_fdir_fltr_conf *conf) { … } /** * ice_vc_fdir_parse_action * @vf: pointer to the VF info * @fltr: virtual channel add cmd buffer * @conf: FDIR configuration for each filter * * Parse the virtual channel filter's action and store them into conf * * Return: 0 on success, and other on error. */ static int ice_vc_fdir_parse_action(struct ice_vf *vf, struct virtchnl_fdir_add *fltr, struct virtchnl_fdir_fltr_conf *conf) { … } /** * ice_vc_validate_fdir_fltr - validate the virtual channel filter * @vf: pointer to the VF info * @fltr: virtual channel add cmd buffer * @conf: FDIR configuration for each filter * * Return: 0 on success, and other on error. */ static int ice_vc_validate_fdir_fltr(struct ice_vf *vf, struct virtchnl_fdir_add *fltr, struct virtchnl_fdir_fltr_conf *conf) { … } /** * ice_vc_fdir_comp_rules - compare if two filter rules have the same value * @conf_a: FDIR configuration for filter a * @conf_b: FDIR configuration for filter b * * Return: 0 on success, and other on error. */ static bool ice_vc_fdir_comp_rules(struct virtchnl_fdir_fltr_conf *conf_a, struct virtchnl_fdir_fltr_conf *conf_b) { … } /** * ice_vc_fdir_is_dup_fltr * @vf: pointer to the VF info * @conf: FDIR configuration for each filter * * Check if there is duplicated rule with same conf value * * Return: 0 true success, and false on error. */ static bool ice_vc_fdir_is_dup_fltr(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf) { … } /** * ice_vc_fdir_insert_entry * @vf: pointer to the VF info * @conf: FDIR configuration for each filter * @id: pointer to ID value allocated by driver * * Insert FDIR conf entry into list and allocate ID for this filter * * Return: 0 true success, and other on error. */ static int ice_vc_fdir_insert_entry(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf, u32 *id) { … } /** * ice_vc_fdir_remove_entry - remove FDIR conf entry by ID value * @vf: pointer to the VF info * @conf: FDIR configuration for each filter * @id: filter rule's ID */ static void ice_vc_fdir_remove_entry(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf, u32 id) { … } /** * ice_vc_fdir_lookup_entry - lookup FDIR conf entry by ID value * @vf: pointer to the VF info * @id: filter rule's ID * * Return: NULL on error, and other on success. */ static struct virtchnl_fdir_fltr_conf * ice_vc_fdir_lookup_entry(struct ice_vf *vf, u32 id) { … } /** * ice_vc_fdir_flush_entry - remove all FDIR conf entry * @vf: pointer to the VF info */ static void ice_vc_fdir_flush_entry(struct ice_vf *vf) { … } /** * ice_vc_fdir_write_fltr - write filter rule into hardware * @vf: pointer to the VF info * @conf: FDIR configuration for each filter * @add: true implies add rule, false implies del rules * @is_tun: false implies non-tunnel type filter, true implies tunnel filter * * Return: 0 on success, and other on error. */ static int ice_vc_fdir_write_fltr(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf, bool add, bool is_tun) { … } /** * ice_vf_fdir_timer - FDIR program waiting timer interrupt handler * @t: pointer to timer_list */ static void ice_vf_fdir_timer(struct timer_list *t) { … } /** * ice_vc_fdir_irq_handler - ctrl_vsi Rx queue interrupt handler * @ctrl_vsi: pointer to a VF's CTRL VSI * @rx_desc: pointer to FDIR Rx queue descriptor */ void ice_vc_fdir_irq_handler(struct ice_vsi *ctrl_vsi, union ice_32b_rx_flex_desc *rx_desc) { … } /** * ice_vf_fdir_dump_info - dump FDIR information for diagnosis * @vf: pointer to the VF info */ static void ice_vf_fdir_dump_info(struct ice_vf *vf) { … } /** * ice_vf_verify_rx_desc - verify received FDIR programming status descriptor * @vf: pointer to the VF info * @ctx: FDIR context info for post processing * @status: virtchnl FDIR program status * * Return: 0 on success, and other on error. */ static int ice_vf_verify_rx_desc(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx, enum virtchnl_fdir_prgm_status *status) { … } static int ice_fdir_is_tunnel(enum ice_fdir_tunnel_type ttype) { … } /** * ice_vc_add_fdir_fltr_post * @vf: pointer to the VF structure * @ctx: FDIR context info for post processing * @status: virtchnl FDIR program status * @success: true implies success, false implies failure * * Post process for flow director add command. If success, then do post process * and send back success msg by virtchnl. Otherwise, do context reversion and * send back failure msg by virtchnl. * * Return: 0 on success, and other on error. */ static int ice_vc_add_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx, enum virtchnl_fdir_prgm_status status, bool success) { … } /** * ice_vc_del_fdir_fltr_post * @vf: pointer to the VF structure * @ctx: FDIR context info for post processing * @status: virtchnl FDIR program status * @success: true implies success, false implies failure * * Post process for flow director del command. If success, then do post process * and send back success msg by virtchnl. Otherwise, do context reversion and * send back failure msg by virtchnl. * * Return: 0 on success, and other on error. */ static int ice_vc_del_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx, enum virtchnl_fdir_prgm_status status, bool success) { … } /** * ice_flush_fdir_ctx * @pf: pointer to the PF structure * * Flush all the pending event on ctx_done list and process them. */ void ice_flush_fdir_ctx(struct ice_pf *pf) { … } /** * ice_vc_fdir_set_irq_ctx - set FDIR context info for later IRQ handler * @vf: pointer to the VF structure * @conf: FDIR configuration for each filter * @v_opcode: virtual channel operation code * * Return: 0 on success, and other on error. */ static int ice_vc_fdir_set_irq_ctx(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf, enum virtchnl_ops v_opcode) { … } /** * ice_vc_fdir_clear_irq_ctx - clear FDIR context info for IRQ handler * @vf: pointer to the VF structure * * Return: 0 on success, and other on error. */ static void ice_vc_fdir_clear_irq_ctx(struct ice_vf *vf) { … } /** * ice_vc_parser_fv_check_diff - check two parsed FDIR profile fv context * @fv_a: struct of parsed FDIR profile field vector * @fv_b: struct of parsed FDIR profile field vector * * Check if the two parsed FDIR profile field vector context are different, * including proto_id, offset and mask. * * Return: true on different, false on otherwise. */ static bool ice_vc_parser_fv_check_diff(struct ice_parser_fv *fv_a, struct ice_parser_fv *fv_b) { … } /** * ice_vc_parser_fv_save - save parsed FDIR profile fv context * @fv: struct of parsed FDIR profile field vector * @fv_src: parsed FDIR profile field vector context to save * * Save the parsed FDIR profile field vector context, including proto_id, * offset and mask. * * Return: Void. */ static void ice_vc_parser_fv_save(struct ice_parser_fv *fv, struct ice_parser_fv *fv_src) { … } /** * ice_vc_add_fdir_raw - add a raw FDIR filter for VF * @vf: pointer to the VF info * @conf: FDIR configuration for each filter * @v_ret: the final VIRTCHNL code * @stat: pointer to the VIRTCHNL_OP_ADD_FDIR_FILTER * @len: length of the stat * * Return: 0 on success or negative errno on failure. */ static int ice_vc_add_fdir_raw(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf, enum virtchnl_status_code *v_ret, struct virtchnl_fdir_add *stat, int len) { … } /** * ice_vc_add_fdir_fltr - add a FDIR filter for VF by the msg buffer * @vf: pointer to the VF info * @msg: pointer to the msg buffer * * Return: 0 on success, and other on error. */ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg) { … } /** * ice_vc_del_fdir_raw - delete a raw FDIR filter for VF * @vf: pointer to the VF info * @conf: FDIR configuration for each filter * @v_ret: the final VIRTCHNL code * @stat: pointer to the VIRTCHNL_OP_DEL_FDIR_FILTER * @len: length of the stat * * Return: 0 on success or negative errno on failure. */ static int ice_vc_del_fdir_raw(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf, enum virtchnl_status_code *v_ret, struct virtchnl_fdir_del *stat, int len) { … } /** * ice_vc_del_fdir_fltr - delete a FDIR filter for VF by the msg buffer * @vf: pointer to the VF info * @msg: pointer to the msg buffer * * Return: 0 on success, and other on error. */ int ice_vc_del_fdir_fltr(struct ice_vf *vf, u8 *msg) { … } /** * ice_vf_fdir_init - init FDIR resource for VF * @vf: pointer to the VF info */ void ice_vf_fdir_init(struct ice_vf *vf) { … } /** * ice_vf_fdir_exit - destroy FDIR resource for VF * @vf: pointer to the VF info */ void ice_vf_fdir_exit(struct ice_vf *vf) { … }