Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * 3 : : * Copyright(c) 2019-2021 Xilinx, Inc. 4 : : * Copyright(c) 2017-2019 Solarflare Communications Inc. 5 : : * 6 : : * This software was jointly developed between OKTET Labs (under contract 7 : : * for Solarflare) and Solarflare Communications, Inc. 8 : : */ 9 : : 10 : : #include <rte_common.h> 11 : : 12 : : #include "efx.h" 13 : : 14 : : #include "sfc.h" 15 : : #include "sfc_debug.h" 16 : : #include "sfc_log.h" 17 : : 18 : : boolean_t 19 : 0 : sfc_filter_is_match_supported(struct sfc_adapter *sa, uint32_t match) 20 : : { 21 : : struct sfc_filter *filter = &sa->filter; 22 : : size_t i; 23 : : 24 [ # # ]: 0 : for (i = 0; i < filter->supported_match_num; ++i) { 25 [ # # ]: 0 : if (match == filter->supported_match[i]) 26 : : return B_TRUE; 27 : : } 28 : : 29 : : return B_FALSE; 30 : : } 31 : : 32 : : static int 33 : 0 : sfc_filter_cache_match_supported(struct sfc_adapter *sa) 34 : : { 35 : : struct sfc_filter *filter = &sa->filter; 36 : 0 : size_t num = filter->supported_match_num; 37 : 0 : uint32_t *buf = filter->supported_match; 38 : : unsigned int retry; 39 : : int rc; 40 : : 41 : : /* Just a guess of possibly sufficient entries */ 42 [ # # ]: 0 : if (num == 0) 43 : 0 : num = 16; 44 : : 45 [ # # ]: 0 : for (retry = 0; retry < 2; ++retry) { 46 [ # # ]: 0 : if (num != filter->supported_match_num) { 47 : : rc = ENOMEM; 48 : 0 : buf = rte_realloc(buf, num * sizeof(*buf), 0); 49 [ # # ]: 0 : if (buf == NULL) 50 : 0 : goto fail_realloc; 51 : : } 52 : : 53 : 0 : rc = efx_filter_supported_filters(sa->nic, buf, num, &num); 54 [ # # ]: 0 : if (rc == 0) { 55 : 0 : filter->supported_match_num = num; 56 : 0 : filter->supported_match = buf; 57 : : 58 : 0 : return 0; 59 [ # # ]: 0 : } else if (rc != ENOSPC) { 60 : 0 : goto fail_efx_filter_supported_filters; 61 : : } 62 : : } 63 : : 64 : : SFC_ASSERT(rc == ENOSPC); 65 : : 66 : 0 : fail_efx_filter_supported_filters: 67 : 0 : fail_realloc: 68 : : /* Original pointer is not freed by rte_realloc() on failure */ 69 : 0 : rte_free(buf); 70 : 0 : filter->supported_match = NULL; 71 : 0 : filter->supported_match_num = 0; 72 : 0 : return rc; 73 : : } 74 : : 75 : : int 76 : 0 : sfc_filter_attach(struct sfc_adapter *sa) 77 : : { 78 : : int rc; 79 : : unsigned int i; 80 : : 81 : 0 : sfc_log_init(sa, "entry"); 82 : : 83 : 0 : rc = efx_filter_init(sa->nic); 84 [ # # ]: 0 : if (rc != 0) 85 : 0 : goto fail_filter_init; 86 : : 87 : 0 : rc = sfc_filter_cache_match_supported(sa); 88 [ # # ]: 0 : if (rc != 0) 89 : 0 : goto fail_cache_match_supported; 90 : : 91 : 0 : efx_filter_fini(sa->nic); 92 : : 93 : 0 : sa->filter.supports_ip_proto_or_addr_filter = B_FALSE; 94 : 0 : sa->filter.supports_rem_or_local_port_filter = B_FALSE; 95 [ # # ]: 0 : for (i = 0; i < sa->filter.supported_match_num; ++i) { 96 [ # # ]: 0 : if (sa->filter.supported_match[i] & 97 : : (EFX_FILTER_MATCH_IP_PROTO | EFX_FILTER_MATCH_LOC_HOST | 98 : : EFX_FILTER_MATCH_REM_HOST)) 99 : 0 : sa->filter.supports_ip_proto_or_addr_filter = B_TRUE; 100 : : 101 [ # # ]: 0 : if (sa->filter.supported_match[i] & 102 : : (EFX_FILTER_MATCH_LOC_PORT | EFX_FILTER_MATCH_REM_PORT)) 103 : 0 : sa->filter.supports_rem_or_local_port_filter = B_TRUE; 104 : : } 105 : : 106 : 0 : sfc_log_init(sa, "done"); 107 : : 108 : 0 : return 0; 109 : : 110 : : fail_cache_match_supported: 111 : 0 : efx_filter_fini(sa->nic); 112 : : 113 : 0 : fail_filter_init: 114 : 0 : sfc_log_init(sa, "failed %d", rc); 115 : 0 : return rc; 116 : : } 117 : : 118 : : void 119 : 0 : sfc_filter_detach(struct sfc_adapter *sa) 120 : : { 121 : : struct sfc_filter *filter = &sa->filter; 122 : : 123 : 0 : sfc_log_init(sa, "entry"); 124 : : 125 : 0 : rte_free(filter->supported_match); 126 : 0 : filter->supported_match = NULL; 127 : 0 : filter->supported_match_num = 0; 128 : : 129 : 0 : sfc_log_init(sa, "done"); 130 : 0 : }