@@ -157,6 +157,220 @@ static inline void mlxsw_reg_sspr_pack(char *payload, u8 local_port)
157
157
mlxsw_reg_sspr_system_port_set (payload , local_port );
158
158
}
159
159
160
+ /* SFD - Switch Filtering Database
161
+ * -------------------------------
162
+ * The following register defines the access to the filtering database.
163
+ * The register supports querying, adding, removing and modifying the database.
164
+ * The access is optimized for bulk updates in which case more than one
165
+ * FDB record is present in the same command.
166
+ */
167
+ #define MLXSW_REG_SFD_ID 0x200A
168
+ #define MLXSW_REG_SFD_BASE_LEN 0x10 /* base length, without records */
169
+ #define MLXSW_REG_SFD_REC_LEN 0x10 /* record length */
170
+ #define MLXSW_REG_SFD_REC_MAX_COUNT 64
171
+ #define MLXSW_REG_SFD_LEN (MLXSW_REG_SFD_BASE_LEN + \
172
+ MLXSW_REG_SFD_REC_LEN * MLXSW_REG_SFD_REC_MAX_COUNT)
173
+
174
+ static const struct mlxsw_reg_info mlxsw_reg_sfd = {
175
+ .id = MLXSW_REG_SFD_ID ,
176
+ .len = MLXSW_REG_SFD_LEN ,
177
+ };
178
+
179
+ /* reg_sfd_swid
180
+ * Switch partition ID for queries. Reserved on Write.
181
+ * Access: Index
182
+ */
183
+ MLXSW_ITEM32 (reg , sfd , swid , 0x00 , 24 , 8 );
184
+
185
+ enum mlxsw_reg_sfd_op {
186
+ /* Dump entire FDB a (process according to record_locator) */
187
+ MLXSW_REG_SFD_OP_QUERY_DUMP = 0 ,
188
+ /* Query records by {MAC, VID/FID} value */
189
+ MLXSW_REG_SFD_OP_QUERY_QUERY = 1 ,
190
+ /* Query and clear activity. Query records by {MAC, VID/FID} value */
191
+ MLXSW_REG_SFD_OP_QUERY_QUERY_AND_CLEAR_ACTIVITY = 2 ,
192
+ /* Test. Response indicates if each of the records could be
193
+ * added to the FDB.
194
+ */
195
+ MLXSW_REG_SFD_OP_WRITE_TEST = 0 ,
196
+ /* Add/modify. Aged-out records cannot be added. This command removes
197
+ * the learning notification of the {MAC, VID/FID}. Response includes
198
+ * the entries that were added to the FDB.
199
+ */
200
+ MLXSW_REG_SFD_OP_WRITE_EDIT = 1 ,
201
+ /* Remove record by {MAC, VID/FID}. This command also removes
202
+ * the learning notification and aged-out notifications
203
+ * of the {MAC, VID/FID}. The response provides current (pre-removal)
204
+ * entries as non-aged-out.
205
+ */
206
+ MLXSW_REG_SFD_OP_WRITE_REMOVE = 2 ,
207
+ /* Remove learned notification by {MAC, VID/FID}. The response provides
208
+ * the removed learning notification.
209
+ */
210
+ MLXSW_REG_SFD_OP_WRITE_REMOVE_NOTIFICATION = 2 ,
211
+ };
212
+
213
+ /* reg_sfd_op
214
+ * Operation.
215
+ * Access: OP
216
+ */
217
+ MLXSW_ITEM32 (reg , sfd , op , 0x04 , 30 , 2 );
218
+
219
+ /* reg_sfd_record_locator
220
+ * Used for querying the FDB. Use record_locator=0 to initiate the
221
+ * query. When a record is returned, a new record_locator is
222
+ * returned to be used in the subsequent query.
223
+ * Reserved for database update.
224
+ * Access: Index
225
+ */
226
+ MLXSW_ITEM32 (reg , sfd , record_locator , 0x04 , 0 , 30 );
227
+
228
+ /* reg_sfd_num_rec
229
+ * Request: Number of records to read/add/modify/remove
230
+ * Response: Number of records read/added/replaced/removed
231
+ * See above description for more details.
232
+ * Ranges 0..64
233
+ * Access: RW
234
+ */
235
+ MLXSW_ITEM32 (reg , sfd , num_rec , 0x08 , 0 , 8 );
236
+
237
+ static inline void mlxsw_reg_sfd_pack (char * payload , enum mlxsw_reg_sfd_op op ,
238
+ u32 record_locator )
239
+ {
240
+ MLXSW_REG_ZERO (sfd , payload );
241
+ mlxsw_reg_sfd_op_set (payload , op );
242
+ mlxsw_reg_sfd_record_locator_set (payload , record_locator );
243
+ }
244
+
245
+ /* reg_sfd_rec_swid
246
+ * Switch partition ID.
247
+ * Access: Index
248
+ */
249
+ MLXSW_ITEM32_INDEXED (reg , sfd , rec_swid , MLXSW_REG_SFD_BASE_LEN , 24 , 8 ,
250
+ MLXSW_REG_SFD_REC_LEN , 0x00 , false);
251
+
252
+ enum mlxsw_reg_sfd_rec_type {
253
+ MLXSW_REG_SFD_REC_TYPE_UNICAST = 0x0 ,
254
+ };
255
+
256
+ /* reg_sfd_rec_type
257
+ * FDB record type.
258
+ * Access: RW
259
+ */
260
+ MLXSW_ITEM32_INDEXED (reg , sfd , rec_type , MLXSW_REG_SFD_BASE_LEN , 20 , 4 ,
261
+ MLXSW_REG_SFD_REC_LEN , 0x00 , false);
262
+
263
+ enum mlxsw_reg_sfd_rec_policy {
264
+ /* Replacement disabled, aging disabled. */
265
+ MLXSW_REG_SFD_REC_POLICY_STATIC_ENTRY = 0 ,
266
+ /* (mlag remote): Replacement enabled, aging disabled,
267
+ * learning notification enabled on this port.
268
+ */
269
+ MLXSW_REG_SFD_REC_POLICY_DYNAMIC_ENTRY_MLAG = 1 ,
270
+ /* (ingress device): Replacement enabled, aging enabled. */
271
+ MLXSW_REG_SFD_REC_POLICY_DYNAMIC_ENTRY_INGRESS = 3 ,
272
+ };
273
+
274
+ /* reg_sfd_rec_policy
275
+ * Policy.
276
+ * Access: RW
277
+ */
278
+ MLXSW_ITEM32_INDEXED (reg , sfd , rec_policy , MLXSW_REG_SFD_BASE_LEN , 18 , 2 ,
279
+ MLXSW_REG_SFD_REC_LEN , 0x00 , false);
280
+
281
+ /* reg_sfd_rec_a
282
+ * Activity. Set for new static entries. Set for static entries if a frame SMAC
283
+ * lookup hits on the entry.
284
+ * To clear the a bit, use "query and clear activity" op.
285
+ * Access: RO
286
+ */
287
+ MLXSW_ITEM32_INDEXED (reg , sfd , rec_a , MLXSW_REG_SFD_BASE_LEN , 16 , 1 ,
288
+ MLXSW_REG_SFD_REC_LEN , 0x00 , false);
289
+
290
+ /* reg_sfd_rec_mac
291
+ * MAC address.
292
+ * Access: Index
293
+ */
294
+ MLXSW_ITEM_BUF_INDEXED (reg , sfd , rec_mac , MLXSW_REG_SFD_BASE_LEN , 6 ,
295
+ MLXSW_REG_SFD_REC_LEN , 0x02 );
296
+
297
+ enum mlxsw_reg_sfd_rec_action {
298
+ /* forward */
299
+ MLXSW_REG_SFD_REC_ACTION_NOP = 0 ,
300
+ /* forward and trap, trap_id is FDB_TRAP */
301
+ MLXSW_REG_SFD_REC_ACTION_MIRROR_TO_CPU = 1 ,
302
+ /* trap and do not forward, trap_id is FDB_TRAP */
303
+ MLXSW_REG_SFD_REC_ACTION_TRAP = 3 ,
304
+ MLXSW_REG_SFD_REC_ACTION_DISCARD_ERROR = 15 ,
305
+ };
306
+
307
+ /* reg_sfd_rec_action
308
+ * Action to apply on the packet.
309
+ * Note: Dynamic entries can only be configured with NOP action.
310
+ * Access: RW
311
+ */
312
+ MLXSW_ITEM32_INDEXED (reg , sfd , rec_action , MLXSW_REG_SFD_BASE_LEN , 28 , 4 ,
313
+ MLXSW_REG_SFD_REC_LEN , 0x0C , false);
314
+
315
+ /* reg_sfd_uc_sub_port
316
+ * LAG sub port.
317
+ * Must be 0 if multichannel VEPA is not enabled.
318
+ * Access: RW
319
+ */
320
+ MLXSW_ITEM32_INDEXED (reg , sfd , uc_sub_port , MLXSW_REG_SFD_BASE_LEN , 16 , 8 ,
321
+ MLXSW_REG_SFD_REC_LEN , 0x08 , false);
322
+
323
+ /* reg_sfd_uc_fid_vid
324
+ * Filtering ID or VLAN ID
325
+ * For SwitchX and SwitchX-2:
326
+ * - Dynamic entries (policy 2,3) use FID
327
+ * - Static entries (policy 0) use VID
328
+ * - When independent learning is configured, VID=FID
329
+ * For Spectrum: use FID for both Dynamic and Static entries.
330
+ * VID should not be used.
331
+ * Access: Index
332
+ */
333
+ MLXSW_ITEM32_INDEXED (reg , sfd , uc_fid_vid , MLXSW_REG_SFD_BASE_LEN , 0 , 16 ,
334
+ MLXSW_REG_SFD_REC_LEN , 0x08 , false);
335
+
336
+ /* reg_sfd_uc_system_port
337
+ * Unique port identifier for the final destination of the packet.
338
+ * Access: RW
339
+ */
340
+ MLXSW_ITEM32_INDEXED (reg , sfd , uc_system_port , MLXSW_REG_SFD_BASE_LEN , 0 , 16 ,
341
+ MLXSW_REG_SFD_REC_LEN , 0x0C , false);
342
+
343
+ static inline void mlxsw_reg_sfd_uc_pack (char * payload , int rec_index ,
344
+ enum mlxsw_reg_sfd_rec_policy policy ,
345
+ const char * mac , u16 vid ,
346
+ enum mlxsw_reg_sfd_rec_action action ,
347
+ u8 local_port )
348
+ {
349
+ u8 num_rec = mlxsw_reg_sfd_num_rec_get (payload );
350
+
351
+ if (rec_index >= num_rec )
352
+ mlxsw_reg_sfd_num_rec_set (payload , rec_index + 1 );
353
+ mlxsw_reg_sfd_rec_swid_set (payload , rec_index , 0 );
354
+ mlxsw_reg_sfd_rec_type_set (payload , rec_index ,
355
+ MLXSW_REG_SFD_REC_TYPE_UNICAST );
356
+ mlxsw_reg_sfd_rec_policy_set (payload , rec_index , policy );
357
+ mlxsw_reg_sfd_rec_mac_memcpy_to (payload , rec_index , mac );
358
+ mlxsw_reg_sfd_uc_sub_port_set (payload , rec_index , 0 );
359
+ mlxsw_reg_sfd_uc_fid_vid_set (payload , rec_index , vid );
360
+ mlxsw_reg_sfd_rec_action_set (payload , rec_index , action );
361
+ mlxsw_reg_sfd_uc_system_port_set (payload , rec_index , local_port );
362
+ }
363
+
364
+ static inline void
365
+ mlxsw_reg_sfd_uc_unpack (char * payload , int rec_index ,
366
+ char * mac , u16 * p_vid ,
367
+ u8 * p_local_port )
368
+ {
369
+ mlxsw_reg_sfd_rec_mac_memcpy_from (payload , rec_index , mac );
370
+ * p_vid = mlxsw_reg_sfd_uc_fid_vid_get (payload , rec_index );
371
+ * p_local_port = mlxsw_reg_sfd_uc_system_port_get (payload , rec_index );
372
+ }
373
+
160
374
/* SPMS - Switch Port MSTP/RSTP State Register
161
375
* -------------------------------------------
162
376
* Configures the spanning tree state of a physical port.
@@ -1251,6 +1465,8 @@ static inline const char *mlxsw_reg_id_str(u16 reg_id)
1251
1465
return "SPAD" ;
1252
1466
case MLXSW_REG_SSPR_ID :
1253
1467
return "SSPR" ;
1468
+ case MLXSW_REG_SFD_ID :
1469
+ return "SFD" ;
1254
1470
case MLXSW_REG_SPMS_ID :
1255
1471
return "SPMS" ;
1256
1472
case MLXSW_REG_SFGC_ID :
0 commit comments