1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /**************************************************************************** 3 * Driver for Solarflare network controllers and boards 4 * Copyright 2019 Solarflare Communications Inc. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published 8 * by the Free Software Foundation, incorporated herein by reference. 9 */ 10 #ifndef EFX_MCDI_FILTERS_H 11 #define EFX_MCDI_FILTERS_H 12 13 #include "net_driver.h" 14 #include "filter.h" 15 #include "mcdi_pcol.h" 16 17 #define EFX_EF10_FILTER_DEV_UC_MAX 32 18 #define EFX_EF10_FILTER_DEV_MC_MAX 256 19 20 enum efx_mcdi_filter_default_filters { 21 EFX_EF10_BCAST, 22 EFX_EF10_UCDEF, 23 EFX_EF10_MCDEF, 24 EFX_EF10_VXLAN4_UCDEF, 25 EFX_EF10_VXLAN4_MCDEF, 26 EFX_EF10_VXLAN6_UCDEF, 27 EFX_EF10_VXLAN6_MCDEF, 28 EFX_EF10_NVGRE4_UCDEF, 29 EFX_EF10_NVGRE4_MCDEF, 30 EFX_EF10_NVGRE6_UCDEF, 31 EFX_EF10_NVGRE6_MCDEF, 32 EFX_EF10_GENEVE4_UCDEF, 33 EFX_EF10_GENEVE4_MCDEF, 34 EFX_EF10_GENEVE6_UCDEF, 35 EFX_EF10_GENEVE6_MCDEF, 36 37 EFX_EF10_NUM_DEFAULT_FILTERS 38 }; 39 40 /* Per-VLAN filters information */ 41 struct efx_mcdi_filter_vlan { 42 struct list_head list; 43 u16 vid; 44 u16 uc[EFX_EF10_FILTER_DEV_UC_MAX]; 45 u16 mc[EFX_EF10_FILTER_DEV_MC_MAX]; 46 u16 default_filters[EFX_EF10_NUM_DEFAULT_FILTERS]; 47 }; 48 49 struct efx_mcdi_dev_addr { 50 u8 addr[ETH_ALEN]; 51 }; 52 53 struct efx_mcdi_filter_table { 54 /* The MCDI match masks supported by this fw & hw, in order of priority */ 55 u32 rx_match_mcdi_flags[ 56 MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_MAXNUM * 2]; 57 unsigned int rx_match_count; 58 /* Our RSS context is exclusive (as opposed to shared) */ 59 bool rx_rss_context_exclusive; 60 61 struct rw_semaphore lock; /* Protects entries */ 62 struct { 63 unsigned long spec; /* pointer to spec plus flag bits */ 64 /* AUTO_OLD is used to mark and sweep MAC filters for the device address lists. */ 65 /* unused flag 1UL */ 66 #define EFX_EF10_FILTER_FLAG_AUTO_OLD 2UL 67 #define EFX_EF10_FILTER_FLAGS 3UL 68 u64 handle; /* firmware handle */ 69 } *entry; 70 /* Shadow of net_device address lists, guarded by mac_lock */ 71 struct efx_mcdi_dev_addr dev_uc_list[EFX_EF10_FILTER_DEV_UC_MAX]; 72 struct efx_mcdi_dev_addr dev_mc_list[EFX_EF10_FILTER_DEV_MC_MAX]; 73 int dev_uc_count; 74 int dev_mc_count; 75 bool uc_promisc; 76 bool mc_promisc; 77 /* Whether in multicast promiscuous mode when last changed */ 78 bool mc_promisc_last; 79 bool mc_overflow; /* Too many MC addrs; should always imply mc_promisc */ 80 /* RSS contexts have yet to be restored after MC reboot */ 81 bool must_restore_rss_contexts; 82 /* filters have yet to be restored after MC reboot */ 83 bool must_restore_filters; 84 /* Multicast filter chaining allows less-specific filters to receive 85 * multicast packets that matched more-specific filters. Early EF10 86 * firmware didn't support this (SF bug 26807); if mc_chaining == false 87 * then we still subscribe the dev_mc_list even when mc_promisc to 88 * prevent another VI stealing the traffic. 89 */ 90 bool mc_chaining; 91 bool vlan_filter; 92 /* Entries on the vlan_list are added/removed under filter_sem */ 93 struct list_head vlan_list; 94 }; 95 96 int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining); 97 void efx_mcdi_filter_table_down(struct efx_nic *efx); 98 void efx_mcdi_filter_table_remove(struct efx_nic *efx); 99 void efx_mcdi_filter_table_restore(struct efx_nic *efx); 100 101 void efx_mcdi_filter_table_reset_mc_allocations(struct efx_nic *efx); 102 103 /* 104 * The filter table(s) are managed by firmware and we have write-only 105 * access. When removing filters we must identify them to the 106 * firmware by a 64-bit handle, but this is too wide for Linux kernel 107 * interfaces (32-bit for RX NFC, 16-bit for RFS). Also, we need to 108 * be able to tell in advance whether a requested insertion will 109 * replace an existing filter. Therefore we maintain a software hash 110 * table, which should be at least as large as the hardware hash 111 * table. 112 * 113 * Huntington has a single 8K filter table shared between all filter 114 * types and both ports. 115 */ 116 #define EFX_MCDI_FILTER_TBL_ROWS 8192 117 118 bool efx_mcdi_filter_match_supported(struct efx_mcdi_filter_table *table, 119 bool encap, 120 enum efx_filter_match_flags match_flags); 121 122 void efx_mcdi_filter_sync_rx_mode(struct efx_nic *efx); 123 s32 efx_mcdi_filter_insert(struct efx_nic *efx, struct efx_filter_spec *spec, 124 bool replace_equal); 125 int efx_mcdi_filter_remove_safe(struct efx_nic *efx, 126 enum efx_filter_priority priority, 127 u32 filter_id); 128 int efx_mcdi_filter_get_safe(struct efx_nic *efx, 129 enum efx_filter_priority priority, 130 u32 filter_id, struct efx_filter_spec *spec); 131 132 u32 efx_mcdi_filter_count_rx_used(struct efx_nic *efx, 133 enum efx_filter_priority priority); 134 int efx_mcdi_filter_clear_rx(struct efx_nic *efx, 135 enum efx_filter_priority priority); 136 u32 efx_mcdi_filter_get_rx_id_limit(struct efx_nic *efx); 137 s32 efx_mcdi_filter_get_rx_ids(struct efx_nic *efx, 138 enum efx_filter_priority priority, 139 u32 *buf, u32 size); 140 141 void efx_mcdi_filter_cleanup_vlans(struct efx_nic *efx); 142 int efx_mcdi_filter_add_vlan(struct efx_nic *efx, u16 vid); 143 struct efx_mcdi_filter_vlan *efx_mcdi_filter_find_vlan(struct efx_nic *efx, u16 vid); 144 void efx_mcdi_filter_del_vlan(struct efx_nic *efx, u16 vid); 145 146 void efx_mcdi_rx_free_indir_table(struct efx_nic *efx); 147 int efx_mcdi_rx_push_rss_context_config(struct efx_nic *efx, 148 struct efx_rss_context *ctx, 149 const u32 *rx_indir_table, 150 const u8 *key); 151 int efx_mcdi_pf_rx_push_rss_config(struct efx_nic *efx, bool user, 152 const u32 *rx_indir_table, 153 const u8 *key); 154 int efx_mcdi_vf_rx_push_rss_config(struct efx_nic *efx, bool user, 155 const u32 *rx_indir_table 156 __attribute__ ((unused)), 157 const u8 *key 158 __attribute__ ((unused))); 159 int efx_mcdi_push_default_indir_table(struct efx_nic *efx, 160 unsigned int rss_spread); 161 int efx_mcdi_rx_pull_rss_config(struct efx_nic *efx); 162 int efx_mcdi_rx_pull_rss_context_config(struct efx_nic *efx, 163 struct efx_rss_context *ctx); 164 int efx_mcdi_get_rss_context_flags(struct efx_nic *efx, u32 context, 165 u32 *flags); 166 void efx_mcdi_set_rss_context_flags(struct efx_nic *efx, 167 struct efx_rss_context *ctx); 168 void efx_mcdi_rx_restore_rss_contexts(struct efx_nic *efx); 169 170 static inline void efx_mcdi_update_rx_scatter(struct efx_nic *efx) 171 { 172 /* no need to do anything here */ 173 } 174 175 bool efx_mcdi_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id, 176 unsigned int filter_idx); 177 178 #endif 179