1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /****************************************************************************
3 * Driver for Solarflare network controllers and boards
4 * Copyright 2019 Solarflare Communications Inc.
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.
10 #ifndef EFX_MCDI_FILTERS_H
11 #define EFX_MCDI_FILTERS_H
13 #include "net_driver.h"
15 #include "mcdi_pcol.h"
17 #define EFX_EF10_FILTER_DEV_UC_MAX 32
18 #define EFX_EF10_FILTER_DEV_MC_MAX 256
20 enum efx_mcdi_filter_default_filters {
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,
37 EFX_EF10_NUM_DEFAULT_FILTERS
40 /* Per-VLAN filters information */
41 struct efx_mcdi_filter_vlan {
42 struct list_head list;
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];
49 struct efx_mcdi_dev_addr {
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;
61 struct rw_semaphore lock; /* Protects entries */
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. */
66 #define EFX_EF10_FILTER_FLAG_AUTO_OLD 2UL
67 #define EFX_EF10_FILTER_FLAGS 3UL
68 u64 handle; /* firmware handle */
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];
77 /* Whether in multicast promiscuous mode when last changed */
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.
92 struct list_head vlan_list;
95 int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining);
96 void efx_mcdi_filter_table_down(struct efx_nic *efx);
97 void efx_mcdi_filter_table_remove(struct efx_nic *efx);
98 void efx_mcdi_filter_table_restore(struct efx_nic *efx);
100 void efx_mcdi_filter_table_reset_mc_allocations(struct efx_nic *efx);
103 * The filter table(s) are managed by firmware and we have write-only
104 * access. When removing filters we must identify them to the
105 * firmware by a 64-bit handle, but this is too wide for Linux kernel
106 * interfaces (32-bit for RX NFC, 16-bit for RFS). Also, we need to
107 * be able to tell in advance whether a requested insertion will
108 * replace an existing filter. Therefore we maintain a software hash
109 * table, which should be at least as large as the hardware hash
112 * Huntington has a single 8K filter table shared between all filter
113 * types and both ports.
115 #define EFX_MCDI_FILTER_TBL_ROWS 8192
117 bool efx_mcdi_filter_match_supported(struct efx_mcdi_filter_table *table,
119 enum efx_filter_match_flags match_flags);
121 void efx_mcdi_filter_sync_rx_mode(struct efx_nic *efx);
122 s32 efx_mcdi_filter_insert(struct efx_nic *efx, struct efx_filter_spec *spec,
124 int efx_mcdi_filter_remove_safe(struct efx_nic *efx,
125 enum efx_filter_priority priority,
127 int efx_mcdi_filter_get_safe(struct efx_nic *efx,
128 enum efx_filter_priority priority,
129 u32 filter_id, struct efx_filter_spec *spec);
131 u32 efx_mcdi_filter_count_rx_used(struct efx_nic *efx,
132 enum efx_filter_priority priority);
133 int efx_mcdi_filter_clear_rx(struct efx_nic *efx,
134 enum efx_filter_priority priority);
135 u32 efx_mcdi_filter_get_rx_id_limit(struct efx_nic *efx);
136 s32 efx_mcdi_filter_get_rx_ids(struct efx_nic *efx,
137 enum efx_filter_priority priority,
140 void efx_mcdi_filter_cleanup_vlans(struct efx_nic *efx);
141 int efx_mcdi_filter_add_vlan(struct efx_nic *efx, u16 vid);
142 struct efx_mcdi_filter_vlan *efx_mcdi_filter_find_vlan(struct efx_nic *efx, u16 vid);
143 void efx_mcdi_filter_del_vlan(struct efx_nic *efx, u16 vid);
145 void efx_mcdi_rx_free_indir_table(struct efx_nic *efx);
146 int efx_mcdi_rx_push_rss_context_config(struct efx_nic *efx,
147 struct efx_rss_context *ctx,
148 const u32 *rx_indir_table,
150 int efx_mcdi_pf_rx_push_rss_config(struct efx_nic *efx, bool user,
151 const u32 *rx_indir_table,
153 int efx_mcdi_vf_rx_push_rss_config(struct efx_nic *efx, bool user,
154 const u32 *rx_indir_table
155 __attribute__ ((unused)),
157 __attribute__ ((unused)));
158 int efx_mcdi_push_default_indir_table(struct efx_nic *efx,
159 unsigned int rss_spread);
160 int efx_mcdi_rx_pull_rss_config(struct efx_nic *efx);
161 int efx_mcdi_rx_pull_rss_context_config(struct efx_nic *efx,
162 struct efx_rss_context *ctx);
163 int efx_mcdi_get_rss_context_flags(struct efx_nic *efx, u32 context,
165 void efx_mcdi_set_rss_context_flags(struct efx_nic *efx,
166 struct efx_rss_context *ctx);
167 void efx_mcdi_rx_restore_rss_contexts(struct efx_nic *efx);
169 static inline void efx_mcdi_update_rx_scatter(struct efx_nic *efx)
171 /* no need to do anything here */
174 bool efx_mcdi_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
175 unsigned int filter_idx);