xref: /linux/drivers/net/ethernet/sfc/mcdi_filters.h (revision 06ed6aa56ffac9241e03a24649e8d048f8f1b10c)
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 
59 	struct rw_semaphore lock; /* Protects entries */
60 	struct {
61 		unsigned long spec;	/* pointer to spec plus flag bits */
62 /* AUTO_OLD is used to mark and sweep MAC filters for the device address lists. */
63 /* unused flag	1UL */
64 #define EFX_EF10_FILTER_FLAG_AUTO_OLD	2UL
65 #define EFX_EF10_FILTER_FLAGS		3UL
66 		u64 handle;		/* firmware handle */
67 	} *entry;
68 /* Shadow of net_device address lists, guarded by mac_lock */
69 	struct efx_mcdi_dev_addr dev_uc_list[EFX_EF10_FILTER_DEV_UC_MAX];
70 	struct efx_mcdi_dev_addr dev_mc_list[EFX_EF10_FILTER_DEV_MC_MAX];
71 	int dev_uc_count;
72 	int dev_mc_count;
73 	bool uc_promisc;
74 	bool mc_promisc;
75 /* Whether in multicast promiscuous mode when last changed */
76 	bool mc_promisc_last;
77 	bool mc_overflow; /* Too many MC addrs; should always imply mc_promisc */
78 	bool vlan_filter;
79 	struct list_head vlan_list;
80 };
81 
82 int efx_mcdi_filter_table_probe(struct efx_nic *efx);
83 void efx_mcdi_filter_table_remove(struct efx_nic *efx);
84 void efx_mcdi_filter_table_restore(struct efx_nic *efx);
85 
86 /*
87  * The filter table(s) are managed by firmware and we have write-only
88  * access.  When removing filters we must identify them to the
89  * firmware by a 64-bit handle, but this is too wide for Linux kernel
90  * interfaces (32-bit for RX NFC, 16-bit for RFS).  Also, we need to
91  * be able to tell in advance whether a requested insertion will
92  * replace an existing filter.  Therefore we maintain a software hash
93  * table, which should be at least as large as the hardware hash
94  * table.
95  *
96  * Huntington has a single 8K filter table shared between all filter
97  * types and both ports.
98  */
99 #define EFX_MCDI_FILTER_TBL_ROWS 8192
100 
101 bool efx_mcdi_filter_match_supported(struct efx_mcdi_filter_table *table,
102 				     bool encap,
103 				     enum efx_filter_match_flags match_flags);
104 
105 void efx_mcdi_filter_sync_rx_mode(struct efx_nic *efx);
106 s32 efx_mcdi_filter_insert(struct efx_nic *efx, struct efx_filter_spec *spec,
107 			   bool replace_equal);
108 int efx_mcdi_filter_remove_safe(struct efx_nic *efx,
109 				enum efx_filter_priority priority,
110 				u32 filter_id);
111 int efx_mcdi_filter_get_safe(struct efx_nic *efx,
112 			     enum efx_filter_priority priority,
113 			     u32 filter_id, struct efx_filter_spec *spec);
114 
115 u32 efx_mcdi_filter_count_rx_used(struct efx_nic *efx,
116 				  enum efx_filter_priority priority);
117 int efx_mcdi_filter_clear_rx(struct efx_nic *efx,
118 			     enum efx_filter_priority priority);
119 u32 efx_mcdi_filter_get_rx_id_limit(struct efx_nic *efx);
120 s32 efx_mcdi_filter_get_rx_ids(struct efx_nic *efx,
121 			       enum efx_filter_priority priority,
122 			       u32 *buf, u32 size);
123 
124 void efx_mcdi_filter_cleanup_vlans(struct efx_nic *efx);
125 int efx_mcdi_filter_add_vlan(struct efx_nic *efx, u16 vid);
126 struct efx_mcdi_filter_vlan *efx_mcdi_filter_find_vlan(struct efx_nic *efx, u16 vid);
127 void efx_mcdi_filter_del_vlan(struct efx_nic *efx, u16 vid);
128 
129 void efx_mcdi_rx_free_indir_table(struct efx_nic *efx);
130 int efx_mcdi_rx_push_rss_context_config(struct efx_nic *efx,
131 					struct efx_rss_context *ctx,
132 					const u32 *rx_indir_table,
133 					const u8 *key);
134 int efx_mcdi_pf_rx_push_rss_config(struct efx_nic *efx, bool user,
135 				   const u32 *rx_indir_table,
136 				   const u8 *key);
137 int efx_mcdi_vf_rx_push_rss_config(struct efx_nic *efx, bool user,
138 				   const u32 *rx_indir_table
139 				   __attribute__ ((unused)),
140 				   const u8 *key
141 				   __attribute__ ((unused)));
142 int efx_mcdi_rx_pull_rss_config(struct efx_nic *efx);
143 int efx_mcdi_rx_pull_rss_context_config(struct efx_nic *efx,
144 					struct efx_rss_context *ctx);
145 int efx_mcdi_get_rss_context_flags(struct efx_nic *efx, u32 context,
146 				   u32 *flags);
147 void efx_mcdi_set_rss_context_flags(struct efx_nic *efx,
148 				    struct efx_rss_context *ctx);
149 void efx_mcdi_rx_restore_rss_contexts(struct efx_nic *efx);
150 
151 static inline void efx_mcdi_update_rx_scatter(struct efx_nic *efx)
152 {
153 	/* no need to do anything here */
154 }
155 
156 bool efx_mcdi_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
157 				    unsigned int filter_idx);
158 
159 #endif
160