1 | /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ |
2 | /* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */ |
3 | |
4 | #ifndef _MLXSW_REG_H |
5 | #define _MLXSW_REG_H |
6 | |
7 | #include <linux/kernel.h> |
8 | #include <linux/string.h> |
9 | #include <linux/bitops.h> |
10 | #include <linux/if_vlan.h> |
11 | |
12 | #include "item.h" |
13 | #include "port.h" |
14 | |
15 | struct mlxsw_reg_info { |
16 | u16 id; |
17 | u16 len; /* In u8 */ |
18 | const char *name; |
19 | }; |
20 | |
21 | #define MLXSW_REG_DEFINE(_name, _id, _len) \ |
22 | static const struct mlxsw_reg_info mlxsw_reg_##_name = { \ |
23 | .id = _id, \ |
24 | .len = _len, \ |
25 | .name = #_name, \ |
26 | } |
27 | |
28 | #define MLXSW_REG(type) (&mlxsw_reg_##type) |
29 | #define MLXSW_REG_LEN(type) MLXSW_REG(type)->len |
30 | #define MLXSW_REG_ZERO(type, payload) memset(payload, 0, MLXSW_REG(type)->len) |
31 | |
32 | /* SGCR - Switch General Configuration Register |
33 | * -------------------------------------------- |
34 | * This register is used for configuration of the switch capabilities. |
35 | */ |
36 | #define MLXSW_REG_SGCR_ID 0x2000 |
37 | #define MLXSW_REG_SGCR_LEN 0x10 |
38 | |
39 | MLXSW_REG_DEFINE(sgcr, MLXSW_REG_SGCR_ID, MLXSW_REG_SGCR_LEN); |
40 | |
41 | /* reg_sgcr_llb |
42 | * Link Local Broadcast (Default=0) |
43 | * When set, all Link Local packets (224.0.0.X) will be treated as broadcast |
44 | * packets and ignore the IGMP snooping entries. |
45 | * Access: RW |
46 | */ |
47 | MLXSW_ITEM32(reg, sgcr, llb, 0x04, 0, 1); |
48 | |
49 | static inline void mlxsw_reg_sgcr_pack(char *payload, bool llb) |
50 | { |
51 | MLXSW_REG_ZERO(sgcr, payload); |
52 | mlxsw_reg_sgcr_llb_set(buf: payload, val: !!llb); |
53 | } |
54 | |
55 | /* SPAD - Switch Physical Address Register |
56 | * --------------------------------------- |
57 | * The SPAD register configures the switch physical MAC address. |
58 | */ |
59 | #define MLXSW_REG_SPAD_ID 0x2002 |
60 | #define MLXSW_REG_SPAD_LEN 0x10 |
61 | |
62 | MLXSW_REG_DEFINE(spad, MLXSW_REG_SPAD_ID, MLXSW_REG_SPAD_LEN); |
63 | |
64 | /* reg_spad_base_mac |
65 | * Base MAC address for the switch partitions. |
66 | * Per switch partition MAC address is equal to: |
67 | * base_mac + swid |
68 | * Access: RW |
69 | */ |
70 | MLXSW_ITEM_BUF(reg, spad, base_mac, 0x02, 6); |
71 | |
72 | /* SSPR - Switch System Port Record Register |
73 | * ----------------------------------------- |
74 | * Configures the system port to local port mapping. |
75 | */ |
76 | #define MLXSW_REG_SSPR_ID 0x2008 |
77 | #define MLXSW_REG_SSPR_LEN 0x8 |
78 | |
79 | MLXSW_REG_DEFINE(sspr, MLXSW_REG_SSPR_ID, MLXSW_REG_SSPR_LEN); |
80 | |
81 | /* reg_sspr_m |
82 | * Master - if set, then the record describes the master system port. |
83 | * This is needed in case a local port is mapped into several system ports |
84 | * (for multipathing). That number will be reported as the source system |
85 | * port when packets are forwarded to the CPU. Only one master port is allowed |
86 | * per local port. |
87 | * |
88 | * Note: Must be set for Spectrum. |
89 | * Access: RW |
90 | */ |
91 | MLXSW_ITEM32(reg, sspr, m, 0x00, 31, 1); |
92 | |
93 | /* reg_sspr_local_port |
94 | * Local port number. |
95 | * |
96 | * Access: RW |
97 | */ |
98 | MLXSW_ITEM32_LP(reg, sspr, 0x00, 16, 0x00, 12); |
99 | |
100 | /* reg_sspr_sub_port |
101 | * Virtual port within the physical port. |
102 | * Should be set to 0 when virtual ports are not enabled on the port. |
103 | * |
104 | * Access: RW |
105 | */ |
106 | MLXSW_ITEM32(reg, sspr, sub_port, 0x00, 8, 8); |
107 | |
108 | /* reg_sspr_system_port |
109 | * Unique identifier within the stacking domain that represents all the ports |
110 | * that are available in the system (external ports). |
111 | * |
112 | * Currently, only single-ASIC configurations are supported, so we default to |
113 | * 1:1 mapping between system ports and local ports. |
114 | * Access: Index |
115 | */ |
116 | MLXSW_ITEM32(reg, sspr, system_port, 0x04, 0, 16); |
117 | |
118 | static inline void mlxsw_reg_sspr_pack(char *payload, u16 local_port) |
119 | { |
120 | MLXSW_REG_ZERO(sspr, payload); |
121 | mlxsw_reg_sspr_m_set(buf: payload, val: 1); |
122 | mlxsw_reg_sspr_local_port_set(buf: payload, val: local_port); |
123 | mlxsw_reg_sspr_sub_port_set(buf: payload, val: 0); |
124 | mlxsw_reg_sspr_system_port_set(buf: payload, val: local_port); |
125 | } |
126 | |
127 | /* SFDAT - Switch Filtering Database Aging Time |
128 | * -------------------------------------------- |
129 | * Controls the Switch aging time. Aging time is able to be set per Switch |
130 | * Partition. |
131 | */ |
132 | #define MLXSW_REG_SFDAT_ID 0x2009 |
133 | #define MLXSW_REG_SFDAT_LEN 0x8 |
134 | |
135 | MLXSW_REG_DEFINE(sfdat, MLXSW_REG_SFDAT_ID, MLXSW_REG_SFDAT_LEN); |
136 | |
137 | /* reg_sfdat_swid |
138 | * Switch partition ID. |
139 | * Access: Index |
140 | */ |
141 | MLXSW_ITEM32(reg, sfdat, swid, 0x00, 24, 8); |
142 | |
143 | /* reg_sfdat_age_time |
144 | * Aging time in seconds |
145 | * Min - 10 seconds |
146 | * Max - 1,000,000 seconds |
147 | * Default is 300 seconds. |
148 | * Access: RW |
149 | */ |
150 | MLXSW_ITEM32(reg, sfdat, age_time, 0x04, 0, 20); |
151 | |
152 | static inline void mlxsw_reg_sfdat_pack(char *payload, u32 age_time) |
153 | { |
154 | MLXSW_REG_ZERO(sfdat, payload); |
155 | mlxsw_reg_sfdat_swid_set(buf: payload, val: 0); |
156 | mlxsw_reg_sfdat_age_time_set(buf: payload, val: age_time); |
157 | } |
158 | |
159 | /* SFD - Switch Filtering Database |
160 | * ------------------------------- |
161 | * The following register defines the access to the filtering database. |
162 | * The register supports querying, adding, removing and modifying the database. |
163 | * The access is optimized for bulk updates in which case more than one |
164 | * FDB record is present in the same command. |
165 | */ |
166 | #define MLXSW_REG_SFD_ID 0x200A |
167 | #define MLXSW_REG_SFD_BASE_LEN 0x10 /* base length, without records */ |
168 | #define MLXSW_REG_SFD_REC_LEN 0x10 /* record length */ |
169 | #define MLXSW_REG_SFD_REC_MAX_COUNT 64 |
170 | #define MLXSW_REG_SFD_LEN (MLXSW_REG_SFD_BASE_LEN + \ |
171 | MLXSW_REG_SFD_REC_LEN * MLXSW_REG_SFD_REC_MAX_COUNT) |
172 | |
173 | MLXSW_REG_DEFINE(sfd, MLXSW_REG_SFD_ID, MLXSW_REG_SFD_LEN); |
174 | |
175 | /* reg_sfd_swid |
176 | * Switch partition ID for queries. Reserved on Write. |
177 | * Access: Index |
178 | */ |
179 | MLXSW_ITEM32(reg, sfd, swid, 0x00, 24, 8); |
180 | |
181 | enum mlxsw_reg_sfd_op { |
182 | /* Dump entire FDB a (process according to record_locator) */ |
183 | MLXSW_REG_SFD_OP_QUERY_DUMP = 0, |
184 | /* Query records by {MAC, VID/FID} value */ |
185 | MLXSW_REG_SFD_OP_QUERY_QUERY = 1, |
186 | /* Query and clear activity. Query records by {MAC, VID/FID} value */ |
187 | MLXSW_REG_SFD_OP_QUERY_QUERY_AND_CLEAR_ACTIVITY = 2, |
188 | /* Test. Response indicates if each of the records could be |
189 | * added to the FDB. |
190 | */ |
191 | MLXSW_REG_SFD_OP_WRITE_TEST = 0, |
192 | /* Add/modify. Aged-out records cannot be added. This command removes |
193 | * the learning notification of the {MAC, VID/FID}. Response includes |
194 | * the entries that were added to the FDB. |
195 | */ |
196 | MLXSW_REG_SFD_OP_WRITE_EDIT = 1, |
197 | /* Remove record by {MAC, VID/FID}. This command also removes |
198 | * the learning notification and aged-out notifications |
199 | * of the {MAC, VID/FID}. The response provides current (pre-removal) |
200 | * entries as non-aged-out. |
201 | */ |
202 | MLXSW_REG_SFD_OP_WRITE_REMOVE = 2, |
203 | /* Remove learned notification by {MAC, VID/FID}. The response provides |
204 | * the removed learning notification. |
205 | */ |
206 | MLXSW_REG_SFD_OP_WRITE_REMOVE_NOTIFICATION = 2, |
207 | }; |
208 | |
209 | /* reg_sfd_op |
210 | * Operation. |
211 | * Access: OP |
212 | */ |
213 | MLXSW_ITEM32(reg, sfd, op, 0x04, 30, 2); |
214 | |
215 | /* reg_sfd_record_locator |
216 | * Used for querying the FDB. Use record_locator=0 to initiate the |
217 | * query. When a record is returned, a new record_locator is |
218 | * returned to be used in the subsequent query. |
219 | * Reserved for database update. |
220 | * Access: Index |
221 | */ |
222 | MLXSW_ITEM32(reg, sfd, record_locator, 0x04, 0, 30); |
223 | |
224 | /* reg_sfd_num_rec |
225 | * Request: Number of records to read/add/modify/remove |
226 | * Response: Number of records read/added/replaced/removed |
227 | * See above description for more details. |
228 | * Ranges 0..64 |
229 | * Access: RW |
230 | */ |
231 | MLXSW_ITEM32(reg, sfd, num_rec, 0x08, 0, 8); |
232 | |
233 | static inline void mlxsw_reg_sfd_pack(char *payload, enum mlxsw_reg_sfd_op op, |
234 | u32 record_locator) |
235 | { |
236 | MLXSW_REG_ZERO(sfd, payload); |
237 | mlxsw_reg_sfd_op_set(buf: payload, val: op); |
238 | mlxsw_reg_sfd_record_locator_set(buf: payload, val: record_locator); |
239 | } |
240 | |
241 | /* reg_sfd_rec_swid |
242 | * Switch partition ID. |
243 | * Access: Index |
244 | */ |
245 | MLXSW_ITEM32_INDEXED(reg, sfd, rec_swid, MLXSW_REG_SFD_BASE_LEN, 24, 8, |
246 | MLXSW_REG_SFD_REC_LEN, 0x00, false); |
247 | |
248 | enum mlxsw_reg_sfd_rec_type { |
249 | MLXSW_REG_SFD_REC_TYPE_UNICAST = 0x0, |
250 | MLXSW_REG_SFD_REC_TYPE_UNICAST_LAG = 0x1, |
251 | MLXSW_REG_SFD_REC_TYPE_MULTICAST = 0x2, |
252 | MLXSW_REG_SFD_REC_TYPE_UNICAST_TUNNEL = 0xC, |
253 | }; |
254 | |
255 | /* reg_sfd_rec_type |
256 | * FDB record type. |
257 | * Access: RW |
258 | */ |
259 | MLXSW_ITEM32_INDEXED(reg, sfd, rec_type, MLXSW_REG_SFD_BASE_LEN, 20, 4, |
260 | MLXSW_REG_SFD_REC_LEN, 0x00, false); |
261 | |
262 | enum mlxsw_reg_sfd_rec_policy { |
263 | /* Replacement disabled, aging disabled. */ |
264 | MLXSW_REG_SFD_REC_POLICY_STATIC_ENTRY = 0, |
265 | /* (mlag remote): Replacement enabled, aging disabled, |
266 | * learning notification enabled on this port. |
267 | */ |
268 | MLXSW_REG_SFD_REC_POLICY_DYNAMIC_ENTRY_MLAG = 1, |
269 | /* (ingress device): Replacement enabled, aging enabled. */ |
270 | MLXSW_REG_SFD_REC_POLICY_DYNAMIC_ENTRY_INGRESS = 3, |
271 | }; |
272 | |
273 | /* reg_sfd_rec_policy |
274 | * Policy. |
275 | * Access: RW |
276 | */ |
277 | MLXSW_ITEM32_INDEXED(reg, sfd, rec_policy, MLXSW_REG_SFD_BASE_LEN, 18, 2, |
278 | MLXSW_REG_SFD_REC_LEN, 0x00, false); |
279 | |
280 | /* reg_sfd_rec_a |
281 | * Activity. Set for new static entries. Set for static entries if a frame SMAC |
282 | * lookup hits on the entry. |
283 | * To clear the a bit, use "query and clear activity" op. |
284 | * Access: RO |
285 | */ |
286 | MLXSW_ITEM32_INDEXED(reg, sfd, rec_a, MLXSW_REG_SFD_BASE_LEN, 16, 1, |
287 | MLXSW_REG_SFD_REC_LEN, 0x00, false); |
288 | |
289 | /* reg_sfd_rec_mac |
290 | * MAC address. |
291 | * Access: Index |
292 | */ |
293 | MLXSW_ITEM_BUF_INDEXED(reg, sfd, rec_mac, MLXSW_REG_SFD_BASE_LEN, 6, |
294 | MLXSW_REG_SFD_REC_LEN, 0x02); |
295 | |
296 | enum mlxsw_reg_sfd_rec_action { |
297 | /* forward */ |
298 | MLXSW_REG_SFD_REC_ACTION_NOP = 0, |
299 | /* forward and trap, trap_id is FDB_TRAP */ |
300 | MLXSW_REG_SFD_REC_ACTION_MIRROR_TO_CPU = 1, |
301 | /* trap and do not forward, trap_id is FDB_TRAP */ |
302 | MLXSW_REG_SFD_REC_ACTION_TRAP = 2, |
303 | /* forward to IP router */ |
304 | MLXSW_REG_SFD_REC_ACTION_FORWARD_IP_ROUTER = 3, |
305 | MLXSW_REG_SFD_REC_ACTION_DISCARD_ERROR = 15, |
306 | }; |
307 | |
308 | /* reg_sfd_rec_action |
309 | * Action to apply on the packet. |
310 | * Note: Dynamic entries can only be configured with NOP action. |
311 | * Access: RW |
312 | */ |
313 | MLXSW_ITEM32_INDEXED(reg, sfd, rec_action, MLXSW_REG_SFD_BASE_LEN, 28, 4, |
314 | MLXSW_REG_SFD_REC_LEN, 0x0C, false); |
315 | |
316 | /* reg_sfd_uc_sub_port |
317 | * VEPA channel on local port. |
318 | * Valid only if local port is a non-stacking port. Must be 0 if multichannel |
319 | * VEPA is not enabled. |
320 | * Access: RW |
321 | */ |
322 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_sub_port, MLXSW_REG_SFD_BASE_LEN, 16, 8, |
323 | MLXSW_REG_SFD_REC_LEN, 0x08, false); |
324 | |
325 | /* reg_sfd_uc_set_vid |
326 | * Set VID. |
327 | * 0 - Do not update VID. |
328 | * 1 - Set VID. |
329 | * For Spectrum-2 when set_vid=0 and smpe_valid=1, the smpe will modify the vid. |
330 | * Access: RW |
331 | * |
332 | * Note: Reserved when legacy bridge model is used. |
333 | */ |
334 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_set_vid, MLXSW_REG_SFD_BASE_LEN, 31, 1, |
335 | MLXSW_REG_SFD_REC_LEN, 0x08, false); |
336 | |
337 | /* reg_sfd_uc_fid_vid |
338 | * Filtering ID or VLAN ID |
339 | * For SwitchX and SwitchX-2: |
340 | * - Dynamic entries (policy 2,3) use FID |
341 | * - Static entries (policy 0) use VID |
342 | * - When independent learning is configured, VID=FID |
343 | * For Spectrum: use FID for both Dynamic and Static entries. |
344 | * VID should not be used. |
345 | * Access: Index |
346 | */ |
347 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_fid_vid, MLXSW_REG_SFD_BASE_LEN, 0, 16, |
348 | MLXSW_REG_SFD_REC_LEN, 0x08, false); |
349 | |
350 | /* reg_sfd_uc_vid |
351 | * New VID when set_vid=1. |
352 | * Access: RW |
353 | * |
354 | * Note: Reserved when legacy bridge model is used and when set_vid=0. |
355 | */ |
356 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_vid, MLXSW_REG_SFD_BASE_LEN, 16, 12, |
357 | MLXSW_REG_SFD_REC_LEN, 0x0C, false); |
358 | |
359 | /* reg_sfd_uc_system_port |
360 | * Unique port identifier for the final destination of the packet. |
361 | * Access: RW |
362 | */ |
363 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_system_port, MLXSW_REG_SFD_BASE_LEN, 0, 16, |
364 | MLXSW_REG_SFD_REC_LEN, 0x0C, false); |
365 | |
366 | static inline void mlxsw_reg_sfd_rec_pack(char *payload, int rec_index, |
367 | enum mlxsw_reg_sfd_rec_type rec_type, |
368 | const char *mac, |
369 | enum mlxsw_reg_sfd_rec_action action) |
370 | { |
371 | u8 num_rec = mlxsw_reg_sfd_num_rec_get(payload); |
372 | |
373 | if (rec_index >= num_rec) |
374 | mlxsw_reg_sfd_num_rec_set(buf: payload, val: rec_index + 1); |
375 | mlxsw_reg_sfd_rec_swid_set(buf: payload, index: rec_index, val: 0); |
376 | mlxsw_reg_sfd_rec_type_set(buf: payload, index: rec_index, val: rec_type); |
377 | mlxsw_reg_sfd_rec_mac_memcpy_to(buf: payload, index: rec_index, src: mac); |
378 | mlxsw_reg_sfd_rec_action_set(buf: payload, index: rec_index, val: action); |
379 | } |
380 | |
381 | static inline void mlxsw_reg_sfd_uc_pack(char *payload, int rec_index, |
382 | enum mlxsw_reg_sfd_rec_policy policy, |
383 | const char *mac, u16 fid_vid, u16 vid, |
384 | enum mlxsw_reg_sfd_rec_action action, |
385 | u16 local_port) |
386 | { |
387 | mlxsw_reg_sfd_rec_pack(payload, rec_index, |
388 | rec_type: MLXSW_REG_SFD_REC_TYPE_UNICAST, mac, action); |
389 | mlxsw_reg_sfd_rec_policy_set(buf: payload, index: rec_index, val: policy); |
390 | mlxsw_reg_sfd_uc_sub_port_set(buf: payload, index: rec_index, val: 0); |
391 | mlxsw_reg_sfd_uc_fid_vid_set(buf: payload, index: rec_index, val: fid_vid); |
392 | mlxsw_reg_sfd_uc_set_vid_set(buf: payload, index: rec_index, val: vid ? true : false); |
393 | mlxsw_reg_sfd_uc_vid_set(buf: payload, index: rec_index, val: vid); |
394 | mlxsw_reg_sfd_uc_system_port_set(buf: payload, index: rec_index, val: local_port); |
395 | } |
396 | |
397 | /* reg_sfd_uc_lag_sub_port |
398 | * LAG sub port. |
399 | * Must be 0 if multichannel VEPA is not enabled. |
400 | * Access: RW |
401 | */ |
402 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_lag_sub_port, MLXSW_REG_SFD_BASE_LEN, 16, 8, |
403 | MLXSW_REG_SFD_REC_LEN, 0x08, false); |
404 | |
405 | /* reg_sfd_uc_lag_set_vid |
406 | * Set VID. |
407 | * 0 - Do not update VID. |
408 | * 1 - Set VID. |
409 | * For Spectrum-2 when set_vid=0 and smpe_valid=1, the smpe will modify the vid. |
410 | * Access: RW |
411 | * |
412 | * Note: Reserved when legacy bridge model is used. |
413 | */ |
414 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_lag_set_vid, MLXSW_REG_SFD_BASE_LEN, 31, 1, |
415 | MLXSW_REG_SFD_REC_LEN, 0x08, false); |
416 | |
417 | /* reg_sfd_uc_lag_fid_vid |
418 | * Filtering ID or VLAN ID |
419 | * For SwitchX and SwitchX-2: |
420 | * - Dynamic entries (policy 2,3) use FID |
421 | * - Static entries (policy 0) use VID |
422 | * - When independent learning is configured, VID=FID |
423 | * For Spectrum: use FID for both Dynamic and Static entries. |
424 | * VID should not be used. |
425 | * Access: Index |
426 | */ |
427 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_lag_fid_vid, MLXSW_REG_SFD_BASE_LEN, 0, 16, |
428 | MLXSW_REG_SFD_REC_LEN, 0x08, false); |
429 | |
430 | /* reg_sfd_uc_lag_lag_vid |
431 | * New vlan ID. |
432 | * Access: RW |
433 | * |
434 | * Note: Reserved when legacy bridge model is used and set_vid=0. |
435 | */ |
436 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_lag_lag_vid, MLXSW_REG_SFD_BASE_LEN, 16, 12, |
437 | MLXSW_REG_SFD_REC_LEN, 0x0C, false); |
438 | |
439 | /* reg_sfd_uc_lag_lag_id |
440 | * LAG Identifier - pointer into the LAG descriptor table. |
441 | * Access: RW |
442 | */ |
443 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_lag_lag_id, MLXSW_REG_SFD_BASE_LEN, 0, 10, |
444 | MLXSW_REG_SFD_REC_LEN, 0x0C, false); |
445 | |
446 | static inline void |
447 | mlxsw_reg_sfd_uc_lag_pack(char *payload, int rec_index, |
448 | enum mlxsw_reg_sfd_rec_policy policy, |
449 | const char *mac, u16 fid_vid, |
450 | enum mlxsw_reg_sfd_rec_action action, u16 lag_vid, |
451 | u16 lag_id) |
452 | { |
453 | mlxsw_reg_sfd_rec_pack(payload, rec_index, |
454 | rec_type: MLXSW_REG_SFD_REC_TYPE_UNICAST_LAG, |
455 | mac, action); |
456 | mlxsw_reg_sfd_rec_policy_set(buf: payload, index: rec_index, val: policy); |
457 | mlxsw_reg_sfd_uc_lag_sub_port_set(buf: payload, index: rec_index, val: 0); |
458 | mlxsw_reg_sfd_uc_lag_fid_vid_set(buf: payload, index: rec_index, val: fid_vid); |
459 | mlxsw_reg_sfd_uc_lag_set_vid_set(buf: payload, index: rec_index, val: true); |
460 | mlxsw_reg_sfd_uc_lag_lag_vid_set(buf: payload, index: rec_index, val: lag_vid); |
461 | mlxsw_reg_sfd_uc_lag_lag_id_set(buf: payload, index: rec_index, val: lag_id); |
462 | } |
463 | |
464 | /* reg_sfd_mc_pgi |
465 | * |
466 | * Multicast port group index - index into the port group table. |
467 | * Value 0x1FFF indicates the pgi should point to the MID entry. |
468 | * For Spectrum this value must be set to 0x1FFF |
469 | * Access: RW |
470 | */ |
471 | MLXSW_ITEM32_INDEXED(reg, sfd, mc_pgi, MLXSW_REG_SFD_BASE_LEN, 16, 13, |
472 | MLXSW_REG_SFD_REC_LEN, 0x08, false); |
473 | |
474 | /* reg_sfd_mc_fid_vid |
475 | * |
476 | * Filtering ID or VLAN ID |
477 | * Access: Index |
478 | */ |
479 | MLXSW_ITEM32_INDEXED(reg, sfd, mc_fid_vid, MLXSW_REG_SFD_BASE_LEN, 0, 16, |
480 | MLXSW_REG_SFD_REC_LEN, 0x08, false); |
481 | |
482 | /* reg_sfd_mc_mid |
483 | * |
484 | * Multicast identifier - global identifier that represents the multicast |
485 | * group across all devices. |
486 | * Access: RW |
487 | */ |
488 | MLXSW_ITEM32_INDEXED(reg, sfd, mc_mid, MLXSW_REG_SFD_BASE_LEN, 0, 16, |
489 | MLXSW_REG_SFD_REC_LEN, 0x0C, false); |
490 | |
491 | static inline void |
492 | mlxsw_reg_sfd_mc_pack(char *payload, int rec_index, |
493 | const char *mac, u16 fid_vid, |
494 | enum mlxsw_reg_sfd_rec_action action, u16 mid) |
495 | { |
496 | mlxsw_reg_sfd_rec_pack(payload, rec_index, |
497 | rec_type: MLXSW_REG_SFD_REC_TYPE_MULTICAST, mac, action); |
498 | mlxsw_reg_sfd_mc_pgi_set(buf: payload, index: rec_index, val: 0x1FFF); |
499 | mlxsw_reg_sfd_mc_fid_vid_set(buf: payload, index: rec_index, val: fid_vid); |
500 | mlxsw_reg_sfd_mc_mid_set(buf: payload, index: rec_index, val: mid); |
501 | } |
502 | |
503 | /* reg_sfd_uc_tunnel_uip_msb |
504 | * When protocol is IPv4, the most significant byte of the underlay IPv4 |
505 | * destination IP. |
506 | * When protocol is IPv6, reserved. |
507 | * Access: RW |
508 | */ |
509 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_tunnel_uip_msb, MLXSW_REG_SFD_BASE_LEN, 24, |
510 | 8, MLXSW_REG_SFD_REC_LEN, 0x08, false); |
511 | |
512 | /* reg_sfd_uc_tunnel_fid |
513 | * Filtering ID. |
514 | * Access: Index |
515 | */ |
516 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_tunnel_fid, MLXSW_REG_SFD_BASE_LEN, 0, 16, |
517 | MLXSW_REG_SFD_REC_LEN, 0x08, false); |
518 | |
519 | enum mlxsw_reg_sfd_uc_tunnel_protocol { |
520 | MLXSW_REG_SFD_UC_TUNNEL_PROTOCOL_IPV4, |
521 | MLXSW_REG_SFD_UC_TUNNEL_PROTOCOL_IPV6, |
522 | }; |
523 | |
524 | /* reg_sfd_uc_tunnel_protocol |
525 | * IP protocol. |
526 | * Access: RW |
527 | */ |
528 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_tunnel_protocol, MLXSW_REG_SFD_BASE_LEN, 27, |
529 | 1, MLXSW_REG_SFD_REC_LEN, 0x0C, false); |
530 | |
531 | /* reg_sfd_uc_tunnel_uip_lsb |
532 | * When protocol is IPv4, the least significant bytes of the underlay |
533 | * IPv4 destination IP. |
534 | * When protocol is IPv6, pointer to the underlay IPv6 destination IP |
535 | * which is configured by RIPS. |
536 | * Access: RW |
537 | */ |
538 | MLXSW_ITEM32_INDEXED(reg, sfd, uc_tunnel_uip_lsb, MLXSW_REG_SFD_BASE_LEN, 0, |
539 | 24, MLXSW_REG_SFD_REC_LEN, 0x0C, false); |
540 | |
541 | static inline void |
542 | mlxsw_reg_sfd_uc_tunnel_pack(char *payload, int rec_index, |
543 | enum mlxsw_reg_sfd_rec_policy policy, |
544 | const char *mac, u16 fid, |
545 | enum mlxsw_reg_sfd_rec_action action, |
546 | enum mlxsw_reg_sfd_uc_tunnel_protocol proto) |
547 | { |
548 | mlxsw_reg_sfd_rec_pack(payload, rec_index, |
549 | rec_type: MLXSW_REG_SFD_REC_TYPE_UNICAST_TUNNEL, mac, |
550 | action); |
551 | mlxsw_reg_sfd_rec_policy_set(buf: payload, index: rec_index, val: policy); |
552 | mlxsw_reg_sfd_uc_tunnel_fid_set(buf: payload, index: rec_index, val: fid); |
553 | mlxsw_reg_sfd_uc_tunnel_protocol_set(buf: payload, index: rec_index, val: proto); |
554 | } |
555 | |
556 | static inline void |
557 | mlxsw_reg_sfd_uc_tunnel_pack4(char *payload, int rec_index, |
558 | enum mlxsw_reg_sfd_rec_policy policy, |
559 | const char *mac, u16 fid, |
560 | enum mlxsw_reg_sfd_rec_action action, u32 uip) |
561 | { |
562 | mlxsw_reg_sfd_uc_tunnel_uip_msb_set(buf: payload, index: rec_index, val: uip >> 24); |
563 | mlxsw_reg_sfd_uc_tunnel_uip_lsb_set(buf: payload, index: rec_index, val: uip); |
564 | mlxsw_reg_sfd_uc_tunnel_pack(payload, rec_index, policy, mac, fid, |
565 | action, |
566 | proto: MLXSW_REG_SFD_UC_TUNNEL_PROTOCOL_IPV4); |
567 | } |
568 | |
569 | static inline void |
570 | mlxsw_reg_sfd_uc_tunnel_pack6(char *payload, int rec_index, const char *mac, |
571 | u16 fid, enum mlxsw_reg_sfd_rec_action action, |
572 | u32 uip_ptr) |
573 | { |
574 | mlxsw_reg_sfd_uc_tunnel_uip_lsb_set(buf: payload, index: rec_index, val: uip_ptr); |
575 | /* Only static policy is supported for IPv6 unicast tunnel entry. */ |
576 | mlxsw_reg_sfd_uc_tunnel_pack(payload, rec_index, |
577 | policy: MLXSW_REG_SFD_REC_POLICY_STATIC_ENTRY, |
578 | mac, fid, action, |
579 | proto: MLXSW_REG_SFD_UC_TUNNEL_PROTOCOL_IPV6); |
580 | } |
581 | |
582 | enum mlxsw_reg_tunnel_port { |
583 | MLXSW_REG_TUNNEL_PORT_NVE, |
584 | MLXSW_REG_TUNNEL_PORT_VPLS, |
585 | MLXSW_REG_TUNNEL_PORT_FLEX_TUNNEL0, |
586 | MLXSW_REG_TUNNEL_PORT_FLEX_TUNNEL1, |
587 | }; |
588 | |
589 | /* SFN - Switch FDB Notification Register |
590 | * ------------------------------------------- |
591 | * The switch provides notifications on newly learned FDB entries and |
592 | * aged out entries. The notifications can be polled by software. |
593 | */ |
594 | #define MLXSW_REG_SFN_ID 0x200B |
595 | #define MLXSW_REG_SFN_BASE_LEN 0x10 /* base length, without records */ |
596 | #define MLXSW_REG_SFN_REC_LEN 0x10 /* record length */ |
597 | #define MLXSW_REG_SFN_REC_MAX_COUNT 64 |
598 | #define MLXSW_REG_SFN_LEN (MLXSW_REG_SFN_BASE_LEN + \ |
599 | MLXSW_REG_SFN_REC_LEN * MLXSW_REG_SFN_REC_MAX_COUNT) |
600 | |
601 | MLXSW_REG_DEFINE(sfn, MLXSW_REG_SFN_ID, MLXSW_REG_SFN_LEN); |
602 | |
603 | /* reg_sfn_swid |
604 | * Switch partition ID. |
605 | * Access: Index |
606 | */ |
607 | MLXSW_ITEM32(reg, sfn, swid, 0x00, 24, 8); |
608 | |
609 | /* reg_sfn_end |
610 | * Forces the current session to end. |
611 | * Access: OP |
612 | */ |
613 | MLXSW_ITEM32(reg, sfn, end, 0x04, 20, 1); |
614 | |
615 | /* reg_sfn_num_rec |
616 | * Request: Number of learned notifications and aged-out notification |
617 | * records requested. |
618 | * Response: Number of notification records returned (must be smaller |
619 | * than or equal to the value requested) |
620 | * Ranges 0..64 |
621 | * Access: OP |
622 | */ |
623 | MLXSW_ITEM32(reg, sfn, num_rec, 0x04, 0, 8); |
624 | |
625 | static inline void mlxsw_reg_sfn_pack(char *payload) |
626 | { |
627 | MLXSW_REG_ZERO(sfn, payload); |
628 | mlxsw_reg_sfn_swid_set(buf: payload, val: 0); |
629 | mlxsw_reg_sfn_end_set(buf: payload, val: 0); |
630 | mlxsw_reg_sfn_num_rec_set(buf: payload, MLXSW_REG_SFN_REC_MAX_COUNT); |
631 | } |
632 | |
633 | /* reg_sfn_rec_swid |
634 | * Switch partition ID. |
635 | * Access: RO |
636 | */ |
637 | MLXSW_ITEM32_INDEXED(reg, sfn, rec_swid, MLXSW_REG_SFN_BASE_LEN, 24, 8, |
638 | MLXSW_REG_SFN_REC_LEN, 0x00, false); |
639 | |
640 | enum mlxsw_reg_sfn_rec_type { |
641 | /* MAC addresses learned on a regular port. */ |
642 | MLXSW_REG_SFN_REC_TYPE_LEARNED_MAC = 0x5, |
643 | /* MAC addresses learned on a LAG port. */ |
644 | MLXSW_REG_SFN_REC_TYPE_LEARNED_MAC_LAG = 0x6, |
645 | /* Aged-out MAC address on a regular port. */ |
646 | MLXSW_REG_SFN_REC_TYPE_AGED_OUT_MAC = 0x7, |
647 | /* Aged-out MAC address on a LAG port. */ |
648 | MLXSW_REG_SFN_REC_TYPE_AGED_OUT_MAC_LAG = 0x8, |
649 | /* Learned unicast tunnel record. */ |
650 | MLXSW_REG_SFN_REC_TYPE_LEARNED_UNICAST_TUNNEL = 0xD, |
651 | /* Aged-out unicast tunnel record. */ |
652 | MLXSW_REG_SFN_REC_TYPE_AGED_OUT_UNICAST_TUNNEL = 0xE, |
653 | }; |
654 | |
655 | /* reg_sfn_rec_type |
656 | * Notification record type. |
657 | * Access: RO |
658 | */ |
659 | MLXSW_ITEM32_INDEXED(reg, sfn, rec_type, MLXSW_REG_SFN_BASE_LEN, 20, 4, |
660 | MLXSW_REG_SFN_REC_LEN, 0x00, false); |
661 | |
662 | /* reg_sfn_rec_mac |
663 | * MAC address. |
664 | * Access: RO |
665 | */ |
666 | MLXSW_ITEM_BUF_INDEXED(reg, sfn, rec_mac, MLXSW_REG_SFN_BASE_LEN, 6, |
667 | MLXSW_REG_SFN_REC_LEN, 0x02); |
668 | |
669 | /* reg_sfn_mac_sub_port |
670 | * VEPA channel on the local port. |
671 | * 0 if multichannel VEPA is not enabled. |
672 | * Access: RO |
673 | */ |
674 | MLXSW_ITEM32_INDEXED(reg, sfn, mac_sub_port, MLXSW_REG_SFN_BASE_LEN, 16, 8, |
675 | MLXSW_REG_SFN_REC_LEN, 0x08, false); |
676 | |
677 | /* reg_sfn_mac_fid |
678 | * Filtering identifier. |
679 | * Access: RO |
680 | */ |
681 | MLXSW_ITEM32_INDEXED(reg, sfn, mac_fid, MLXSW_REG_SFN_BASE_LEN, 0, 16, |
682 | MLXSW_REG_SFN_REC_LEN, 0x08, false); |
683 | |
684 | /* reg_sfn_mac_system_port |
685 | * Unique port identifier for the final destination of the packet. |
686 | * Access: RO |
687 | */ |
688 | MLXSW_ITEM32_INDEXED(reg, sfn, mac_system_port, MLXSW_REG_SFN_BASE_LEN, 0, 16, |
689 | MLXSW_REG_SFN_REC_LEN, 0x0C, false); |
690 | |
691 | static inline void mlxsw_reg_sfn_mac_unpack(char *payload, int rec_index, |
692 | char *mac, u16 *p_vid, |
693 | u16 *p_local_port) |
694 | { |
695 | mlxsw_reg_sfn_rec_mac_memcpy_from(buf: payload, index: rec_index, dst: mac); |
696 | *p_vid = mlxsw_reg_sfn_mac_fid_get(payload, rec_index); |
697 | *p_local_port = mlxsw_reg_sfn_mac_system_port_get(payload, rec_index); |
698 | } |
699 | |
700 | /* reg_sfn_mac_lag_lag_id |
701 | * LAG ID (pointer into the LAG descriptor table). |
702 | * Access: RO |
703 | */ |
704 | MLXSW_ITEM32_INDEXED(reg, sfn, mac_lag_lag_id, MLXSW_REG_SFN_BASE_LEN, 0, 10, |
705 | MLXSW_REG_SFN_REC_LEN, 0x0C, false); |
706 | |
707 | static inline void mlxsw_reg_sfn_mac_lag_unpack(char *payload, int rec_index, |
708 | char *mac, u16 *p_vid, |
709 | u16 *p_lag_id) |
710 | { |
711 | mlxsw_reg_sfn_rec_mac_memcpy_from(buf: payload, index: rec_index, dst: mac); |
712 | *p_vid = mlxsw_reg_sfn_mac_fid_get(payload, rec_index); |
713 | *p_lag_id = mlxsw_reg_sfn_mac_lag_lag_id_get(payload, rec_index); |
714 | } |
715 | |
716 | /* reg_sfn_uc_tunnel_uip_msb |
717 | * When protocol is IPv4, the most significant byte of the underlay IPv4 |
718 | * address of the remote VTEP. |
719 | * When protocol is IPv6, reserved. |
720 | * Access: RO |
721 | */ |
722 | MLXSW_ITEM32_INDEXED(reg, sfn, uc_tunnel_uip_msb, MLXSW_REG_SFN_BASE_LEN, 24, |
723 | 8, MLXSW_REG_SFN_REC_LEN, 0x08, false); |
724 | |
725 | enum mlxsw_reg_sfn_uc_tunnel_protocol { |
726 | MLXSW_REG_SFN_UC_TUNNEL_PROTOCOL_IPV4, |
727 | MLXSW_REG_SFN_UC_TUNNEL_PROTOCOL_IPV6, |
728 | }; |
729 | |
730 | /* reg_sfn_uc_tunnel_protocol |
731 | * IP protocol. |
732 | * Access: RO |
733 | */ |
734 | MLXSW_ITEM32_INDEXED(reg, sfn, uc_tunnel_protocol, MLXSW_REG_SFN_BASE_LEN, 27, |
735 | 1, MLXSW_REG_SFN_REC_LEN, 0x0C, false); |
736 | |
737 | /* reg_sfn_uc_tunnel_uip_lsb |
738 | * When protocol is IPv4, the least significant bytes of the underlay |
739 | * IPv4 address of the remote VTEP. |
740 | * When protocol is IPv6, ipv6_id to be queried from TNIPSD. |
741 | * Access: RO |
742 | */ |
743 | MLXSW_ITEM32_INDEXED(reg, sfn, uc_tunnel_uip_lsb, MLXSW_REG_SFN_BASE_LEN, 0, |
744 | 24, MLXSW_REG_SFN_REC_LEN, 0x0C, false); |
745 | |
746 | /* reg_sfn_uc_tunnel_port |
747 | * Tunnel port. |
748 | * Reserved on Spectrum. |
749 | * Access: RO |
750 | */ |
751 | MLXSW_ITEM32_INDEXED(reg, sfn, tunnel_port, MLXSW_REG_SFN_BASE_LEN, 0, 4, |
752 | MLXSW_REG_SFN_REC_LEN, 0x10, false); |
753 | |
754 | static inline void |
755 | mlxsw_reg_sfn_uc_tunnel_unpack(char *payload, int rec_index, char *mac, |
756 | u16 *p_fid, u32 *p_uip, |
757 | enum mlxsw_reg_sfn_uc_tunnel_protocol *p_proto) |
758 | { |
759 | u32 uip_msb, uip_lsb; |
760 | |
761 | mlxsw_reg_sfn_rec_mac_memcpy_from(buf: payload, index: rec_index, dst: mac); |
762 | *p_fid = mlxsw_reg_sfn_mac_fid_get(payload, rec_index); |
763 | uip_msb = mlxsw_reg_sfn_uc_tunnel_uip_msb_get(payload, rec_index); |
764 | uip_lsb = mlxsw_reg_sfn_uc_tunnel_uip_lsb_get(payload, rec_index); |
765 | *p_uip = uip_msb << 24 | uip_lsb; |
766 | *p_proto = mlxsw_reg_sfn_uc_tunnel_protocol_get(payload, rec_index); |
767 | } |
768 | |
769 | /* SPMS - Switch Port MSTP/RSTP State Register |
770 | * ------------------------------------------- |
771 | * Configures the spanning tree state of a physical port. |
772 | */ |
773 | #define MLXSW_REG_SPMS_ID 0x200D |
774 | #define MLXSW_REG_SPMS_LEN 0x404 |
775 | |
776 | MLXSW_REG_DEFINE(spms, MLXSW_REG_SPMS_ID, MLXSW_REG_SPMS_LEN); |
777 | |
778 | /* reg_spms_local_port |
779 | * Local port number. |
780 | * Access: Index |
781 | */ |
782 | MLXSW_ITEM32_LP(reg, spms, 0x00, 16, 0x00, 12); |
783 | |
784 | enum mlxsw_reg_spms_state { |
785 | MLXSW_REG_SPMS_STATE_NO_CHANGE, |
786 | MLXSW_REG_SPMS_STATE_DISCARDING, |
787 | MLXSW_REG_SPMS_STATE_LEARNING, |
788 | MLXSW_REG_SPMS_STATE_FORWARDING, |
789 | }; |
790 | |
791 | /* reg_spms_state |
792 | * Spanning tree state of each VLAN ID (VID) of the local port. |
793 | * 0 - Do not change spanning tree state (used only when writing). |
794 | * 1 - Discarding. No learning or forwarding to/from this port (default). |
795 | * 2 - Learning. Port is learning, but not forwarding. |
796 | * 3 - Forwarding. Port is learning and forwarding. |
797 | * Access: RW |
798 | */ |
799 | MLXSW_ITEM_BIT_ARRAY(reg, spms, state, 0x04, 0x400, 2); |
800 | |
801 | static inline void mlxsw_reg_spms_pack(char *payload, u16 local_port) |
802 | { |
803 | MLXSW_REG_ZERO(spms, payload); |
804 | mlxsw_reg_spms_local_port_set(buf: payload, val: local_port); |
805 | } |
806 | |
807 | static inline void mlxsw_reg_spms_vid_pack(char *payload, u16 vid, |
808 | enum mlxsw_reg_spms_state state) |
809 | { |
810 | mlxsw_reg_spms_state_set(payload, vid, state); |
811 | } |
812 | |
813 | /* SPVID - Switch Port VID |
814 | * ----------------------- |
815 | * The switch port VID configures the default VID for a port. |
816 | */ |
817 | #define MLXSW_REG_SPVID_ID 0x200E |
818 | #define MLXSW_REG_SPVID_LEN 0x08 |
819 | |
820 | MLXSW_REG_DEFINE(spvid, MLXSW_REG_SPVID_ID, MLXSW_REG_SPVID_LEN); |
821 | |
822 | /* reg_spvid_tport |
823 | * Port is tunnel port. |
824 | * Reserved when SwitchX/-2 or Spectrum-1. |
825 | * Access: Index |
826 | */ |
827 | MLXSW_ITEM32(reg, spvid, tport, 0x00, 24, 1); |
828 | |
829 | /* reg_spvid_local_port |
830 | * When tport = 0: Local port number. Not supported for CPU port. |
831 | * When tport = 1: Tunnel port. |
832 | * Access: Index |
833 | */ |
834 | MLXSW_ITEM32_LP(reg, spvid, 0x00, 16, 0x00, 12); |
835 | |
836 | /* reg_spvid_sub_port |
837 | * Virtual port within the physical port. |
838 | * Should be set to 0 when virtual ports are not enabled on the port. |
839 | * Access: Index |
840 | */ |
841 | MLXSW_ITEM32(reg, spvid, sub_port, 0x00, 8, 8); |
842 | |
843 | /* reg_spvid_egr_et_set |
844 | * When VLAN is pushed at ingress (for untagged packets or for |
845 | * QinQ push mode) then the EtherType is decided at the egress port. |
846 | * Reserved when Spectrum-1. |
847 | * Access: RW |
848 | */ |
849 | MLXSW_ITEM32(reg, spvid, egr_et_set, 0x04, 24, 1); |
850 | |
851 | /* reg_spvid_et_vlan |
852 | * EtherType used for when VLAN is pushed at ingress (for untagged |
853 | * packets or for QinQ push mode). |
854 | * 0: ether_type0 - (default) |
855 | * 1: ether_type1 |
856 | * 2: ether_type2 - Reserved when Spectrum-1, supported by Spectrum-2 |
857 | * Ethertype IDs are configured by SVER. |
858 | * Reserved when egr_et_set = 1. |
859 | * Access: RW |
860 | */ |
861 | MLXSW_ITEM32(reg, spvid, et_vlan, 0x04, 16, 2); |
862 | |
863 | /* reg_spvid_pvid |
864 | * Port default VID |
865 | * Access: RW |
866 | */ |
867 | MLXSW_ITEM32(reg, spvid, pvid, 0x04, 0, 12); |
868 | |
869 | static inline void mlxsw_reg_spvid_pack(char *payload, u16 local_port, u16 pvid, |
870 | u8 et_vlan) |
871 | { |
872 | MLXSW_REG_ZERO(spvid, payload); |
873 | mlxsw_reg_spvid_local_port_set(buf: payload, val: local_port); |
874 | mlxsw_reg_spvid_pvid_set(buf: payload, val: pvid); |
875 | mlxsw_reg_spvid_et_vlan_set(payload, et_vlan); |
876 | } |
877 | |
878 | /* SPVM - Switch Port VLAN Membership |
879 | * ---------------------------------- |
880 | * The Switch Port VLAN Membership register configures the VLAN membership |
881 | * of a port in a VLAN denoted by VID. VLAN membership is managed per |
882 | * virtual port. The register can be used to add and remove VID(s) from a port. |
883 | */ |
884 | #define MLXSW_REG_SPVM_ID 0x200F |
885 | #define MLXSW_REG_SPVM_BASE_LEN 0x04 /* base length, without records */ |
886 | #define MLXSW_REG_SPVM_REC_LEN 0x04 /* record length */ |
887 | #define MLXSW_REG_SPVM_REC_MAX_COUNT 255 |
888 | #define MLXSW_REG_SPVM_LEN (MLXSW_REG_SPVM_BASE_LEN + \ |
889 | MLXSW_REG_SPVM_REC_LEN * MLXSW_REG_SPVM_REC_MAX_COUNT) |
890 | |
891 | MLXSW_REG_DEFINE(spvm, MLXSW_REG_SPVM_ID, MLXSW_REG_SPVM_LEN); |
892 | |
893 | /* reg_spvm_pt |
894 | * Priority tagged. If this bit is set, packets forwarded to the port with |
895 | * untagged VLAN membership (u bit is set) will be tagged with priority tag |
896 | * (VID=0) |
897 | * Access: RW |
898 | */ |
899 | MLXSW_ITEM32(reg, spvm, pt, 0x00, 31, 1); |
900 | |
901 | /* reg_spvm_pte |
902 | * Priority Tagged Update Enable. On Write operations, if this bit is cleared, |
903 | * the pt bit will NOT be updated. To update the pt bit, pte must be set. |
904 | * Access: WO |
905 | */ |
906 | MLXSW_ITEM32(reg, spvm, pte, 0x00, 30, 1); |
907 | |
908 | /* reg_spvm_local_port |
909 | * Local port number. |
910 | * Access: Index |
911 | */ |
912 | MLXSW_ITEM32_LP(reg, spvm, 0x00, 16, 0x00, 12); |
913 | |
914 | /* reg_spvm_sub_port |
915 | * Virtual port within the physical port. |
916 | * Should be set to 0 when virtual ports are not enabled on the port. |
917 | * Access: Index |
918 | */ |
919 | MLXSW_ITEM32(reg, spvm, sub_port, 0x00, 8, 8); |
920 | |
921 | /* reg_spvm_num_rec |
922 | * Number of records to update. Each record contains: i, e, u, vid. |
923 | * Access: OP |
924 | */ |
925 | MLXSW_ITEM32(reg, spvm, num_rec, 0x00, 0, 8); |
926 | |
927 | /* reg_spvm_rec_i |
928 | * Ingress membership in VLAN ID. |
929 | * Access: Index |
930 | */ |
931 | MLXSW_ITEM32_INDEXED(reg, spvm, rec_i, |
932 | MLXSW_REG_SPVM_BASE_LEN, 14, 1, |
933 | MLXSW_REG_SPVM_REC_LEN, 0, false); |
934 | |
935 | /* reg_spvm_rec_e |
936 | * Egress membership in VLAN ID. |
937 | * Access: Index |
938 | */ |
939 | MLXSW_ITEM32_INDEXED(reg, spvm, rec_e, |
940 | MLXSW_REG_SPVM_BASE_LEN, 13, 1, |
941 | MLXSW_REG_SPVM_REC_LEN, 0, false); |
942 | |
943 | /* reg_spvm_rec_u |
944 | * Untagged - port is an untagged member - egress transmission uses untagged |
945 | * frames on VID<n> |
946 | * Access: Index |
947 | */ |
948 | MLXSW_ITEM32_INDEXED(reg, spvm, rec_u, |
949 | MLXSW_REG_SPVM_BASE_LEN, 12, 1, |
950 | MLXSW_REG_SPVM_REC_LEN, 0, false); |
951 | |
952 | /* reg_spvm_rec_vid |
953 | * Egress membership in VLAN ID. |
954 | * Access: Index |
955 | */ |
956 | MLXSW_ITEM32_INDEXED(reg, spvm, rec_vid, |
957 | MLXSW_REG_SPVM_BASE_LEN, 0, 12, |
958 | MLXSW_REG_SPVM_REC_LEN, 0, false); |
959 | |
960 | static inline void mlxsw_reg_spvm_pack(char *payload, u16 local_port, |
961 | u16 vid_begin, u16 vid_end, |
962 | bool is_member, bool untagged) |
963 | { |
964 | int size = vid_end - vid_begin + 1; |
965 | int i; |
966 | |
967 | MLXSW_REG_ZERO(spvm, payload); |
968 | mlxsw_reg_spvm_local_port_set(buf: payload, val: local_port); |
969 | mlxsw_reg_spvm_num_rec_set(buf: payload, val: size); |
970 | |
971 | for (i = 0; i < size; i++) { |
972 | mlxsw_reg_spvm_rec_i_set(buf: payload, index: i, val: is_member); |
973 | mlxsw_reg_spvm_rec_e_set(buf: payload, index: i, val: is_member); |
974 | mlxsw_reg_spvm_rec_u_set(buf: payload, index: i, val: untagged); |
975 | mlxsw_reg_spvm_rec_vid_set(buf: payload, index: i, val: vid_begin + i); |
976 | } |
977 | } |
978 | |
979 | /* SPAFT - Switch Port Acceptable Frame Types |
980 | * ------------------------------------------ |
981 | * The Switch Port Acceptable Frame Types register configures the frame |
982 | * admittance of the port. |
983 | */ |
984 | #define MLXSW_REG_SPAFT_ID 0x2010 |
985 | #define MLXSW_REG_SPAFT_LEN 0x08 |
986 | |
987 | MLXSW_REG_DEFINE(spaft, MLXSW_REG_SPAFT_ID, MLXSW_REG_SPAFT_LEN); |
988 | |
989 | /* reg_spaft_local_port |
990 | * Local port number. |
991 | * Access: Index |
992 | * |
993 | * Note: CPU port is not supported (all tag types are allowed). |
994 | */ |
995 | MLXSW_ITEM32_LP(reg, spaft, 0x00, 16, 0x00, 12); |
996 | |
997 | /* reg_spaft_sub_port |
998 | * Virtual port within the physical port. |
999 | * Should be set to 0 when virtual ports are not enabled on the port. |
1000 | * Access: RW |
1001 | */ |
1002 | MLXSW_ITEM32(reg, spaft, sub_port, 0x00, 8, 8); |
1003 | |
1004 | /* reg_spaft_allow_untagged |
1005 | * When set, untagged frames on the ingress are allowed (default). |
1006 | * Access: RW |
1007 | */ |
1008 | MLXSW_ITEM32(reg, spaft, allow_untagged, 0x04, 31, 1); |
1009 | |
1010 | /* reg_spaft_allow_prio_tagged |
1011 | * When set, priority tagged frames on the ingress are allowed (default). |
1012 | * Access: RW |
1013 | */ |
1014 | MLXSW_ITEM32(reg, spaft, allow_prio_tagged, 0x04, 30, 1); |
1015 | |
1016 | /* reg_spaft_allow_tagged |
1017 | * When set, tagged frames on the ingress are allowed (default). |
1018 | * Access: RW |
1019 | */ |
1020 | MLXSW_ITEM32(reg, spaft, allow_tagged, 0x04, 29, 1); |
1021 | |
1022 | static inline void mlxsw_reg_spaft_pack(char *payload, u16 local_port, |
1023 | bool allow_untagged) |
1024 | { |
1025 | MLXSW_REG_ZERO(spaft, payload); |
1026 | mlxsw_reg_spaft_local_port_set(buf: payload, val: local_port); |
1027 | mlxsw_reg_spaft_allow_untagged_set(buf: payload, val: allow_untagged); |
1028 | mlxsw_reg_spaft_allow_prio_tagged_set(buf: payload, val: allow_untagged); |
1029 | mlxsw_reg_spaft_allow_tagged_set(buf: payload, val: true); |
1030 | } |
1031 | |
1032 | /* SFGC - Switch Flooding Group Configuration |
1033 | * ------------------------------------------ |
1034 | * The following register controls the association of flooding tables and MIDs |
1035 | * to packet types used for flooding. |
1036 | */ |
1037 | #define MLXSW_REG_SFGC_ID 0x2011 |
1038 | #define MLXSW_REG_SFGC_LEN 0x14 |
1039 | |
1040 | MLXSW_REG_DEFINE(sfgc, MLXSW_REG_SFGC_ID, MLXSW_REG_SFGC_LEN); |
1041 | |
1042 | enum mlxsw_reg_sfgc_type { |
1043 | MLXSW_REG_SFGC_TYPE_BROADCAST, |
1044 | MLXSW_REG_SFGC_TYPE_UNKNOWN_UNICAST, |
1045 | MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV4, |
1046 | MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV6, |
1047 | MLXSW_REG_SFGC_TYPE_RESERVED, |
1048 | MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_NON_IP, |
1049 | MLXSW_REG_SFGC_TYPE_IPV4_LINK_LOCAL, |
1050 | MLXSW_REG_SFGC_TYPE_IPV6_ALL_HOST, |
1051 | MLXSW_REG_SFGC_TYPE_MAX, |
1052 | }; |
1053 | |
1054 | /* reg_sfgc_type |
1055 | * The traffic type to reach the flooding table. |
1056 | * Access: Index |
1057 | */ |
1058 | MLXSW_ITEM32(reg, sfgc, type, 0x00, 0, 4); |
1059 | |
1060 | /* bridge_type is used in SFGC and SFMR. */ |
1061 | enum mlxsw_reg_bridge_type { |
1062 | MLXSW_REG_BRIDGE_TYPE_0 = 0, /* Used for .1q FIDs. */ |
1063 | MLXSW_REG_BRIDGE_TYPE_1 = 1, /* Used for .1d FIDs. */ |
1064 | }; |
1065 | |
1066 | /* reg_sfgc_bridge_type |
1067 | * Access: Index |
1068 | * |
1069 | * Note: SwitchX-2 only supports 802.1Q mode. |
1070 | */ |
1071 | MLXSW_ITEM32(reg, sfgc, bridge_type, 0x04, 24, 3); |
1072 | |
1073 | enum mlxsw_flood_table_type { |
1074 | MLXSW_REG_SFGC_TABLE_TYPE_VID = 1, |
1075 | MLXSW_REG_SFGC_TABLE_TYPE_SINGLE = 2, |
1076 | MLXSW_REG_SFGC_TABLE_TYPE_ANY = 0, |
1077 | MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFSET = 3, |
1078 | MLXSW_REG_SFGC_TABLE_TYPE_FID = 4, |
1079 | }; |
1080 | |
1081 | /* reg_sfgc_table_type |
1082 | * See mlxsw_flood_table_type |
1083 | * Access: RW |
1084 | * |
1085 | * Note: FID offset and FID types are not supported in SwitchX-2. |
1086 | */ |
1087 | MLXSW_ITEM32(reg, sfgc, table_type, 0x04, 16, 3); |
1088 | |
1089 | /* reg_sfgc_flood_table |
1090 | * Flooding table index to associate with the specific type on the specific |
1091 | * switch partition. |
1092 | * Access: RW |
1093 | */ |
1094 | MLXSW_ITEM32(reg, sfgc, flood_table, 0x04, 0, 6); |
1095 | |
1096 | /* reg_sfgc_counter_set_type |
1097 | * Counter Set Type for flow counters. |
1098 | * Access: RW |
1099 | */ |
1100 | MLXSW_ITEM32(reg, sfgc, counter_set_type, 0x0C, 24, 8); |
1101 | |
1102 | /* reg_sfgc_counter_index |
1103 | * Counter Index for flow counters. |
1104 | * Access: RW |
1105 | */ |
1106 | MLXSW_ITEM32(reg, sfgc, counter_index, 0x0C, 0, 24); |
1107 | |
1108 | /* reg_sfgc_mid_base |
1109 | * MID Base. |
1110 | * Access: RW |
1111 | * |
1112 | * Note: Reserved when legacy bridge model is used. |
1113 | */ |
1114 | MLXSW_ITEM32(reg, sfgc, mid_base, 0x10, 0, 16); |
1115 | |
1116 | static inline void |
1117 | mlxsw_reg_sfgc_pack(char *payload, enum mlxsw_reg_sfgc_type type, |
1118 | enum mlxsw_reg_bridge_type bridge_type, |
1119 | enum mlxsw_flood_table_type table_type, |
1120 | unsigned int flood_table, u16 mid_base) |
1121 | { |
1122 | MLXSW_REG_ZERO(sfgc, payload); |
1123 | mlxsw_reg_sfgc_type_set(buf: payload, val: type); |
1124 | mlxsw_reg_sfgc_bridge_type_set(buf: payload, val: bridge_type); |
1125 | mlxsw_reg_sfgc_table_type_set(buf: payload, val: table_type); |
1126 | mlxsw_reg_sfgc_flood_table_set(buf: payload, val: flood_table); |
1127 | mlxsw_reg_sfgc_mid_base_set(buf: payload, val: mid_base); |
1128 | } |
1129 | |
1130 | /* SFDF - Switch Filtering DB Flush |
1131 | * -------------------------------- |
1132 | * The switch filtering DB flush register is used to flush the FDB. |
1133 | * Note that FDB notifications are flushed as well. |
1134 | */ |
1135 | #define MLXSW_REG_SFDF_ID 0x2013 |
1136 | #define MLXSW_REG_SFDF_LEN 0x14 |
1137 | |
1138 | MLXSW_REG_DEFINE(sfdf, MLXSW_REG_SFDF_ID, MLXSW_REG_SFDF_LEN); |
1139 | |
1140 | /* reg_sfdf_swid |
1141 | * Switch partition ID. |
1142 | * Access: Index |
1143 | */ |
1144 | MLXSW_ITEM32(reg, sfdf, swid, 0x00, 24, 8); |
1145 | |
1146 | enum mlxsw_reg_sfdf_flush_type { |
1147 | MLXSW_REG_SFDF_FLUSH_PER_SWID, |
1148 | MLXSW_REG_SFDF_FLUSH_PER_FID, |
1149 | MLXSW_REG_SFDF_FLUSH_PER_PORT, |
1150 | MLXSW_REG_SFDF_FLUSH_PER_PORT_AND_FID, |
1151 | MLXSW_REG_SFDF_FLUSH_PER_LAG, |
1152 | MLXSW_REG_SFDF_FLUSH_PER_LAG_AND_FID, |
1153 | MLXSW_REG_SFDF_FLUSH_PER_NVE, |
1154 | MLXSW_REG_SFDF_FLUSH_PER_NVE_AND_FID, |
1155 | }; |
1156 | |
1157 | /* reg_sfdf_flush_type |
1158 | * Flush type. |
1159 | * 0 - All SWID dynamic entries are flushed. |
1160 | * 1 - All FID dynamic entries are flushed. |
1161 | * 2 - All dynamic entries pointing to port are flushed. |
1162 | * 3 - All FID dynamic entries pointing to port are flushed. |
1163 | * 4 - All dynamic entries pointing to LAG are flushed. |
1164 | * 5 - All FID dynamic entries pointing to LAG are flushed. |
1165 | * 6 - All entries of type "Unicast Tunnel" or "Multicast Tunnel" are |
1166 | * flushed. |
1167 | * 7 - All entries of type "Unicast Tunnel" or "Multicast Tunnel" are |
1168 | * flushed, per FID. |
1169 | * Access: RW |
1170 | */ |
1171 | MLXSW_ITEM32(reg, sfdf, flush_type, 0x04, 28, 4); |
1172 | |
1173 | /* reg_sfdf_flush_static |
1174 | * Static. |
1175 | * 0 - Flush only dynamic entries. |
1176 | * 1 - Flush both dynamic and static entries. |
1177 | * Access: RW |
1178 | */ |
1179 | MLXSW_ITEM32(reg, sfdf, flush_static, 0x04, 24, 1); |
1180 | |
1181 | static inline void mlxsw_reg_sfdf_pack(char *payload, |
1182 | enum mlxsw_reg_sfdf_flush_type type) |
1183 | { |
1184 | MLXSW_REG_ZERO(sfdf, payload); |
1185 | mlxsw_reg_sfdf_flush_type_set(buf: payload, val: type); |
1186 | mlxsw_reg_sfdf_flush_static_set(buf: payload, val: true); |
1187 | } |
1188 | |
1189 | /* reg_sfdf_fid |
1190 | * FID to flush. |
1191 | * Access: RW |
1192 | */ |
1193 | MLXSW_ITEM32(reg, sfdf, fid, 0x0C, 0, 16); |
1194 | |
1195 | /* reg_sfdf_system_port |
1196 | * Port to flush. |
1197 | * Access: RW |
1198 | */ |
1199 | MLXSW_ITEM32(reg, sfdf, system_port, 0x0C, 0, 16); |
1200 | |
1201 | /* reg_sfdf_port_fid_system_port |
1202 | * Port to flush, pointed to by FID. |
1203 | * Access: RW |
1204 | */ |
1205 | MLXSW_ITEM32(reg, sfdf, port_fid_system_port, 0x08, 0, 16); |
1206 | |
1207 | /* reg_sfdf_lag_id |
1208 | * LAG ID to flush. |
1209 | * Access: RW |
1210 | */ |
1211 | MLXSW_ITEM32(reg, sfdf, lag_id, 0x0C, 0, 10); |
1212 | |
1213 | /* reg_sfdf_lag_fid_lag_id |
1214 | * LAG ID to flush, pointed to by FID. |
1215 | * Access: RW |
1216 | */ |
1217 | MLXSW_ITEM32(reg, sfdf, lag_fid_lag_id, 0x08, 0, 10); |
1218 | |
1219 | /* SLDR - Switch LAG Descriptor Register |
1220 | * ----------------------------------------- |
1221 | * The switch LAG descriptor register is populated by LAG descriptors. |
1222 | * Each LAG descriptor is indexed by lag_id. The LAG ID runs from 0 to |
1223 | * max_lag-1. |
1224 | */ |
1225 | #define MLXSW_REG_SLDR_ID 0x2014 |
1226 | #define MLXSW_REG_SLDR_LEN 0x0C /* counting in only one port in list */ |
1227 | |
1228 | MLXSW_REG_DEFINE(sldr, MLXSW_REG_SLDR_ID, MLXSW_REG_SLDR_LEN); |
1229 | |
1230 | enum mlxsw_reg_sldr_op { |
1231 | /* Indicates a creation of a new LAG-ID, lag_id must be valid */ |
1232 | MLXSW_REG_SLDR_OP_LAG_CREATE, |
1233 | MLXSW_REG_SLDR_OP_LAG_DESTROY, |
1234 | /* Ports that appear in the list have the Distributor enabled */ |
1235 | MLXSW_REG_SLDR_OP_LAG_ADD_PORT_LIST, |
1236 | /* Removes ports from the disributor list */ |
1237 | MLXSW_REG_SLDR_OP_LAG_REMOVE_PORT_LIST, |
1238 | }; |
1239 | |
1240 | /* reg_sldr_op |
1241 | * Operation. |
1242 | * Access: RW |
1243 | */ |
1244 | MLXSW_ITEM32(reg, sldr, op, 0x00, 29, 3); |
1245 | |
1246 | /* reg_sldr_lag_id |
1247 | * LAG identifier. The lag_id is the index into the LAG descriptor table. |
1248 | * Access: Index |
1249 | */ |
1250 | MLXSW_ITEM32(reg, sldr, lag_id, 0x00, 0, 10); |
1251 | |
1252 | static inline void mlxsw_reg_sldr_lag_create_pack(char *payload, u8 lag_id) |
1253 | { |
1254 | MLXSW_REG_ZERO(sldr, payload); |
1255 | mlxsw_reg_sldr_op_set(buf: payload, val: MLXSW_REG_SLDR_OP_LAG_CREATE); |
1256 | mlxsw_reg_sldr_lag_id_set(payload, lag_id); |
1257 | } |
1258 | |
1259 | static inline void mlxsw_reg_sldr_lag_destroy_pack(char *payload, u8 lag_id) |
1260 | { |
1261 | MLXSW_REG_ZERO(sldr, payload); |
1262 | mlxsw_reg_sldr_op_set(buf: payload, val: MLXSW_REG_SLDR_OP_LAG_DESTROY); |
1263 | mlxsw_reg_sldr_lag_id_set(payload, lag_id); |
1264 | } |
1265 | |
1266 | /* reg_sldr_num_ports |
1267 | * The number of member ports of the LAG. |
1268 | * Reserved for Create / Destroy operations |
1269 | * For Add / Remove operations - indicates the number of ports in the list. |
1270 | * Access: RW |
1271 | */ |
1272 | MLXSW_ITEM32(reg, sldr, num_ports, 0x04, 24, 8); |
1273 | |
1274 | /* reg_sldr_system_port |
1275 | * System port. |
1276 | * Access: RW |
1277 | */ |
1278 | MLXSW_ITEM32_INDEXED(reg, sldr, system_port, 0x08, 0, 16, 4, 0, false); |
1279 | |
1280 | static inline void mlxsw_reg_sldr_lag_add_port_pack(char *payload, u8 lag_id, |
1281 | u16 local_port) |
1282 | { |
1283 | MLXSW_REG_ZERO(sldr, payload); |
1284 | mlxsw_reg_sldr_op_set(buf: payload, val: MLXSW_REG_SLDR_OP_LAG_ADD_PORT_LIST); |
1285 | mlxsw_reg_sldr_lag_id_set(payload, lag_id); |
1286 | mlxsw_reg_sldr_num_ports_set(buf: payload, val: 1); |
1287 | mlxsw_reg_sldr_system_port_set(buf: payload, index: 0, val: local_port); |
1288 | } |
1289 | |
1290 | static inline void mlxsw_reg_sldr_lag_remove_port_pack(char *payload, u8 lag_id, |
1291 | u16 local_port) |
1292 | { |
1293 | MLXSW_REG_ZERO(sldr, payload); |
1294 | mlxsw_reg_sldr_op_set(buf: payload, val: MLXSW_REG_SLDR_OP_LAG_REMOVE_PORT_LIST); |
1295 | mlxsw_reg_sldr_lag_id_set(payload, lag_id); |
1296 | mlxsw_reg_sldr_num_ports_set(buf: payload, val: 1); |
1297 | mlxsw_reg_sldr_system_port_set(buf: payload, index: 0, val: local_port); |
1298 | } |
1299 | |
1300 | /* SLCR - Switch LAG Configuration 2 Register |
1301 | * ------------------------------------------- |
1302 | * The Switch LAG Configuration register is used for configuring the |
1303 | * LAG properties of the switch. |
1304 | */ |
1305 | #define MLXSW_REG_SLCR_ID 0x2015 |
1306 | #define MLXSW_REG_SLCR_LEN 0x10 |
1307 | |
1308 | MLXSW_REG_DEFINE(slcr, MLXSW_REG_SLCR_ID, MLXSW_REG_SLCR_LEN); |
1309 | |
1310 | enum mlxsw_reg_slcr_pp { |
1311 | /* Global Configuration (for all ports) */ |
1312 | MLXSW_REG_SLCR_PP_GLOBAL, |
1313 | /* Per port configuration, based on local_port field */ |
1314 | MLXSW_REG_SLCR_PP_PER_PORT, |
1315 | }; |
1316 | |
1317 | /* reg_slcr_pp |
1318 | * Per Port Configuration |
1319 | * Note: Reading at Global mode results in reading port 1 configuration. |
1320 | * Access: Index |
1321 | */ |
1322 | MLXSW_ITEM32(reg, slcr, pp, 0x00, 24, 1); |
1323 | |
1324 | /* reg_slcr_local_port |
1325 | * Local port number |
1326 | * Supported from CPU port |
1327 | * Not supported from router port |
1328 | * Reserved when pp = Global Configuration |
1329 | * Access: Index |
1330 | */ |
1331 | MLXSW_ITEM32_LP(reg, slcr, 0x00, 16, 0x00, 12); |
1332 | |
1333 | enum mlxsw_reg_slcr_type { |
1334 | MLXSW_REG_SLCR_TYPE_CRC, /* default */ |
1335 | MLXSW_REG_SLCR_TYPE_XOR, |
1336 | MLXSW_REG_SLCR_TYPE_RANDOM, |
1337 | }; |
1338 | |
1339 | /* reg_slcr_type |
1340 | * Hash type |
1341 | * Access: RW |
1342 | */ |
1343 | MLXSW_ITEM32(reg, slcr, type, 0x00, 0, 4); |
1344 | |
1345 | /* Ingress port */ |
1346 | #define MLXSW_REG_SLCR_LAG_HASH_IN_PORT BIT(0) |
1347 | /* SMAC - for IPv4 and IPv6 packets */ |
1348 | #define MLXSW_REG_SLCR_LAG_HASH_SMAC_IP BIT(1) |
1349 | /* SMAC - for non-IP packets */ |
1350 | #define MLXSW_REG_SLCR_LAG_HASH_SMAC_NONIP BIT(2) |
1351 | #define MLXSW_REG_SLCR_LAG_HASH_SMAC \ |
1352 | (MLXSW_REG_SLCR_LAG_HASH_SMAC_IP | \ |
1353 | MLXSW_REG_SLCR_LAG_HASH_SMAC_NONIP) |
1354 | /* DMAC - for IPv4 and IPv6 packets */ |
1355 | #define MLXSW_REG_SLCR_LAG_HASH_DMAC_IP BIT(3) |
1356 | /* DMAC - for non-IP packets */ |
1357 | #define MLXSW_REG_SLCR_LAG_HASH_DMAC_NONIP BIT(4) |
1358 | #define MLXSW_REG_SLCR_LAG_HASH_DMAC \ |
1359 | (MLXSW_REG_SLCR_LAG_HASH_DMAC_IP | \ |
1360 | MLXSW_REG_SLCR_LAG_HASH_DMAC_NONIP) |
1361 | /* Ethertype - for IPv4 and IPv6 packets */ |
1362 | #define MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE_IP BIT(5) |
1363 | /* Ethertype - for non-IP packets */ |
1364 | #define MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE_NONIP BIT(6) |
1365 | #define MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE \ |
1366 | (MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE_IP | \ |
1367 | MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE_NONIP) |
1368 | /* VLAN ID - for IPv4 and IPv6 packets */ |
1369 | #define MLXSW_REG_SLCR_LAG_HASH_VLANID_IP BIT(7) |
1370 | /* VLAN ID - for non-IP packets */ |
1371 | #define MLXSW_REG_SLCR_LAG_HASH_VLANID_NONIP BIT(8) |
1372 | #define MLXSW_REG_SLCR_LAG_HASH_VLANID \ |
1373 | (MLXSW_REG_SLCR_LAG_HASH_VLANID_IP | \ |
1374 | MLXSW_REG_SLCR_LAG_HASH_VLANID_NONIP) |
1375 | /* Source IP address (can be IPv4 or IPv6) */ |
1376 | #define MLXSW_REG_SLCR_LAG_HASH_SIP BIT(9) |
1377 | /* Destination IP address (can be IPv4 or IPv6) */ |
1378 | #define MLXSW_REG_SLCR_LAG_HASH_DIP BIT(10) |
1379 | /* TCP/UDP source port */ |
1380 | #define MLXSW_REG_SLCR_LAG_HASH_SPORT BIT(11) |
1381 | /* TCP/UDP destination port*/ |
1382 | #define MLXSW_REG_SLCR_LAG_HASH_DPORT BIT(12) |
1383 | /* IPv4 Protocol/IPv6 Next Header */ |
1384 | #define MLXSW_REG_SLCR_LAG_HASH_IPPROTO BIT(13) |
1385 | /* IPv6 Flow label */ |
1386 | #define MLXSW_REG_SLCR_LAG_HASH_FLOWLABEL BIT(14) |
1387 | /* SID - FCoE source ID */ |
1388 | #define MLXSW_REG_SLCR_LAG_HASH_FCOE_SID BIT(15) |
1389 | /* DID - FCoE destination ID */ |
1390 | #define MLXSW_REG_SLCR_LAG_HASH_FCOE_DID BIT(16) |
1391 | /* OXID - FCoE originator exchange ID */ |
1392 | #define MLXSW_REG_SLCR_LAG_HASH_FCOE_OXID BIT(17) |
1393 | /* Destination QP number - for RoCE packets */ |
1394 | #define MLXSW_REG_SLCR_LAG_HASH_ROCE_DQP BIT(19) |
1395 | |
1396 | /* reg_slcr_lag_hash |
1397 | * LAG hashing configuration. This is a bitmask, in which each set |
1398 | * bit includes the corresponding item in the LAG hash calculation. |
1399 | * The default lag_hash contains SMAC, DMAC, VLANID and |
1400 | * Ethertype (for all packet types). |
1401 | * Access: RW |
1402 | */ |
1403 | MLXSW_ITEM32(reg, slcr, lag_hash, 0x04, 0, 20); |
1404 | |
1405 | /* reg_slcr_seed |
1406 | * LAG seed value. The seed is the same for all ports. |
1407 | * Access: RW |
1408 | */ |
1409 | MLXSW_ITEM32(reg, slcr, seed, 0x08, 0, 32); |
1410 | |
1411 | static inline void mlxsw_reg_slcr_pack(char *payload, u16 lag_hash, u32 seed) |
1412 | { |
1413 | MLXSW_REG_ZERO(slcr, payload); |
1414 | mlxsw_reg_slcr_pp_set(buf: payload, val: MLXSW_REG_SLCR_PP_GLOBAL); |
1415 | mlxsw_reg_slcr_type_set(buf: payload, val: MLXSW_REG_SLCR_TYPE_CRC); |
1416 | mlxsw_reg_slcr_lag_hash_set(buf: payload, val: lag_hash); |
1417 | mlxsw_reg_slcr_seed_set(buf: payload, val: seed); |
1418 | } |
1419 | |
1420 | /* SLCOR - Switch LAG Collector Register |
1421 | * ------------------------------------- |
1422 | * The Switch LAG Collector register controls the Local Port membership |
1423 | * in a LAG and enablement of the collector. |
1424 | */ |
1425 | #define MLXSW_REG_SLCOR_ID 0x2016 |
1426 | #define MLXSW_REG_SLCOR_LEN 0x10 |
1427 | |
1428 | MLXSW_REG_DEFINE(slcor, MLXSW_REG_SLCOR_ID, MLXSW_REG_SLCOR_LEN); |
1429 | |
1430 | enum mlxsw_reg_slcor_col { |
1431 | /* Port is added with collector disabled */ |
1432 | MLXSW_REG_SLCOR_COL_LAG_ADD_PORT, |
1433 | MLXSW_REG_SLCOR_COL_LAG_COLLECTOR_ENABLED, |
1434 | MLXSW_REG_SLCOR_COL_LAG_COLLECTOR_DISABLED, |
1435 | MLXSW_REG_SLCOR_COL_LAG_REMOVE_PORT, |
1436 | }; |
1437 | |
1438 | /* reg_slcor_col |
1439 | * Collector configuration |
1440 | * Access: RW |
1441 | */ |
1442 | MLXSW_ITEM32(reg, slcor, col, 0x00, 30, 2); |
1443 | |
1444 | /* reg_slcor_local_port |
1445 | * Local port number |
1446 | * Not supported for CPU port |
1447 | * Access: Index |
1448 | */ |
1449 | MLXSW_ITEM32_LP(reg, slcor, 0x00, 16, 0x00, 12); |
1450 | |
1451 | /* reg_slcor_lag_id |
1452 | * LAG Identifier. Index into the LAG descriptor table. |
1453 | * Access: Index |
1454 | */ |
1455 | MLXSW_ITEM32(reg, slcor, lag_id, 0x00, 0, 10); |
1456 | |
1457 | /* reg_slcor_port_index |
1458 | * Port index in the LAG list. Only valid on Add Port to LAG col. |
1459 | * Valid range is from 0 to cap_max_lag_members-1 |
1460 | * Access: RW |
1461 | */ |
1462 | MLXSW_ITEM32(reg, slcor, port_index, 0x04, 0, 10); |
1463 | |
1464 | static inline void mlxsw_reg_slcor_pack(char *payload, |
1465 | u16 local_port, u16 lag_id, |
1466 | enum mlxsw_reg_slcor_col col) |
1467 | { |
1468 | MLXSW_REG_ZERO(slcor, payload); |
1469 | mlxsw_reg_slcor_col_set(buf: payload, val: col); |
1470 | mlxsw_reg_slcor_local_port_set(buf: payload, val: local_port); |
1471 | mlxsw_reg_slcor_lag_id_set(buf: payload, val: lag_id); |
1472 | } |
1473 | |
1474 | static inline void mlxsw_reg_slcor_port_add_pack(char *payload, |
1475 | u16 local_port, u16 lag_id, |
1476 | u8 port_index) |
1477 | { |
1478 | mlxsw_reg_slcor_pack(payload, local_port, lag_id, |
1479 | col: MLXSW_REG_SLCOR_COL_LAG_ADD_PORT); |
1480 | mlxsw_reg_slcor_port_index_set(payload, port_index); |
1481 | } |
1482 | |
1483 | static inline void mlxsw_reg_slcor_port_remove_pack(char *payload, |
1484 | u16 local_port, u16 lag_id) |
1485 | { |
1486 | mlxsw_reg_slcor_pack(payload, local_port, lag_id, |
1487 | col: MLXSW_REG_SLCOR_COL_LAG_REMOVE_PORT); |
1488 | } |
1489 | |
1490 | static inline void mlxsw_reg_slcor_col_enable_pack(char *payload, |
1491 | u16 local_port, u16 lag_id) |
1492 | { |
1493 | mlxsw_reg_slcor_pack(payload, local_port, lag_id, |
1494 | col: MLXSW_REG_SLCOR_COL_LAG_COLLECTOR_ENABLED); |
1495 | } |
1496 | |
1497 | static inline void mlxsw_reg_slcor_col_disable_pack(char *payload, |
1498 | u16 local_port, u16 lag_id) |
1499 | { |
1500 | mlxsw_reg_slcor_pack(payload, local_port, lag_id, |
1501 | col: MLXSW_REG_SLCOR_COL_LAG_COLLECTOR_ENABLED); |
1502 | } |
1503 | |
1504 | /* SPMLR - Switch Port MAC Learning Register |
1505 | * ----------------------------------------- |
1506 | * Controls the Switch MAC learning policy per port. |
1507 | */ |
1508 | #define MLXSW_REG_SPMLR_ID 0x2018 |
1509 | #define MLXSW_REG_SPMLR_LEN 0x8 |
1510 | |
1511 | MLXSW_REG_DEFINE(spmlr, MLXSW_REG_SPMLR_ID, MLXSW_REG_SPMLR_LEN); |
1512 | |
1513 | /* reg_spmlr_local_port |
1514 | * Local port number. |
1515 | * Access: Index |
1516 | */ |
1517 | MLXSW_ITEM32_LP(reg, spmlr, 0x00, 16, 0x00, 12); |
1518 | |
1519 | /* reg_spmlr_sub_port |
1520 | * Virtual port within the physical port. |
1521 | * Should be set to 0 when virtual ports are not enabled on the port. |
1522 | * Access: Index |
1523 | */ |
1524 | MLXSW_ITEM32(reg, spmlr, sub_port, 0x00, 8, 8); |
1525 | |
1526 | enum mlxsw_reg_spmlr_learn_mode { |
1527 | MLXSW_REG_SPMLR_LEARN_MODE_DISABLE = 0, |
1528 | MLXSW_REG_SPMLR_LEARN_MODE_ENABLE = 2, |
1529 | MLXSW_REG_SPMLR_LEARN_MODE_SEC = 3, |
1530 | }; |
1531 | |
1532 | /* reg_spmlr_learn_mode |
1533 | * Learning mode on the port. |
1534 | * 0 - Learning disabled. |
1535 | * 2 - Learning enabled. |
1536 | * 3 - Security mode. |
1537 | * |
1538 | * In security mode the switch does not learn MACs on the port, but uses the |
1539 | * SMAC to see if it exists on another ingress port. If so, the packet is |
1540 | * classified as a bad packet and is discarded unless the software registers |
1541 | * to receive port security error packets usign HPKT. |
1542 | */ |
1543 | MLXSW_ITEM32(reg, spmlr, learn_mode, 0x04, 30, 2); |
1544 | |
1545 | static inline void mlxsw_reg_spmlr_pack(char *payload, u16 local_port, |
1546 | enum mlxsw_reg_spmlr_learn_mode mode) |
1547 | { |
1548 | MLXSW_REG_ZERO(spmlr, payload); |
1549 | mlxsw_reg_spmlr_local_port_set(buf: payload, val: local_port); |
1550 | mlxsw_reg_spmlr_sub_port_set(buf: payload, val: 0); |
1551 | mlxsw_reg_spmlr_learn_mode_set(buf: payload, val: mode); |
1552 | } |
1553 | |
1554 | /* SVFA - Switch VID to FID Allocation Register |
1555 | * -------------------------------------------- |
1556 | * Controls the VID to FID mapping and {Port, VID} to FID mapping for |
1557 | * virtualized ports. |
1558 | */ |
1559 | #define MLXSW_REG_SVFA_ID 0x201C |
1560 | #define MLXSW_REG_SVFA_LEN 0x18 |
1561 | |
1562 | MLXSW_REG_DEFINE(svfa, MLXSW_REG_SVFA_ID, MLXSW_REG_SVFA_LEN); |
1563 | |
1564 | /* reg_svfa_swid |
1565 | * Switch partition ID. |
1566 | * Access: Index |
1567 | */ |
1568 | MLXSW_ITEM32(reg, svfa, swid, 0x00, 24, 8); |
1569 | |
1570 | /* reg_svfa_local_port |
1571 | * Local port number. |
1572 | * Access: Index |
1573 | * |
1574 | * Note: Reserved for 802.1Q FIDs. |
1575 | */ |
1576 | MLXSW_ITEM32_LP(reg, svfa, 0x00, 16, 0x00, 12); |
1577 | |
1578 | enum mlxsw_reg_svfa_mt { |
1579 | MLXSW_REG_SVFA_MT_VID_TO_FID, |
1580 | MLXSW_REG_SVFA_MT_PORT_VID_TO_FID, |
1581 | MLXSW_REG_SVFA_MT_VNI_TO_FID, |
1582 | }; |
1583 | |
1584 | /* reg_svfa_mapping_table |
1585 | * Mapping table: |
1586 | * 0 - VID to FID |
1587 | * 1 - {Port, VID} to FID |
1588 | * Access: Index |
1589 | * |
1590 | * Note: Reserved for SwitchX-2. |
1591 | */ |
1592 | MLXSW_ITEM32(reg, svfa, mapping_table, 0x00, 8, 3); |
1593 | |
1594 | /* reg_svfa_v |
1595 | * Valid. |
1596 | * Valid if set. |
1597 | * Access: RW |
1598 | * |
1599 | * Note: Reserved for SwitchX-2. |
1600 | */ |
1601 | MLXSW_ITEM32(reg, svfa, v, 0x00, 0, 1); |
1602 | |
1603 | /* reg_svfa_fid |
1604 | * Filtering ID. |
1605 | * Access: RW |
1606 | */ |
1607 | MLXSW_ITEM32(reg, svfa, fid, 0x04, 16, 16); |
1608 | |
1609 | /* reg_svfa_vid |
1610 | * VLAN ID. |
1611 | * Access: Index |
1612 | */ |
1613 | MLXSW_ITEM32(reg, svfa, vid, 0x04, 0, 12); |
1614 | |
1615 | /* reg_svfa_counter_set_type |
1616 | * Counter set type for flow counters. |
1617 | * Access: RW |
1618 | * |
1619 | * Note: Reserved for SwitchX-2. |
1620 | */ |
1621 | MLXSW_ITEM32(reg, svfa, counter_set_type, 0x08, 24, 8); |
1622 | |
1623 | /* reg_svfa_counter_index |
1624 | * Counter index for flow counters. |
1625 | * Access: RW |
1626 | * |
1627 | * Note: Reserved for SwitchX-2. |
1628 | */ |
1629 | MLXSW_ITEM32(reg, svfa, counter_index, 0x08, 0, 24); |
1630 | |
1631 | /* reg_svfa_vni |
1632 | * Virtual Network Identifier. |
1633 | * Access: Index |
1634 | * |
1635 | * Note: Reserved when mapping_table is not 2 (VNI mapping table). |
1636 | */ |
1637 | MLXSW_ITEM32(reg, svfa, vni, 0x10, 0, 24); |
1638 | |
1639 | /* reg_svfa_irif_v |
1640 | * Ingress RIF valid. |
1641 | * 0 - Ingress RIF is not valid, no ingress RIF assigned. |
1642 | * 1 - Ingress RIF valid. |
1643 | * Must not be set for a non enabled RIF. |
1644 | * Access: RW |
1645 | * |
1646 | * Note: Reserved when legacy bridge model is used. |
1647 | */ |
1648 | MLXSW_ITEM32(reg, svfa, irif_v, 0x14, 24, 1); |
1649 | |
1650 | /* reg_svfa_irif |
1651 | * Ingress RIF (Router Interface). |
1652 | * Range is 0..cap_max_router_interfaces-1. |
1653 | * Access: RW |
1654 | * |
1655 | * Note: Reserved when legacy bridge model is used and when irif_v=0. |
1656 | */ |
1657 | MLXSW_ITEM32(reg, svfa, irif, 0x14, 0, 16); |
1658 | |
1659 | static inline void __mlxsw_reg_svfa_pack(char *payload, |
1660 | enum mlxsw_reg_svfa_mt mt, bool valid, |
1661 | u16 fid, bool irif_v, u16 irif) |
1662 | { |
1663 | MLXSW_REG_ZERO(svfa, payload); |
1664 | mlxsw_reg_svfa_swid_set(buf: payload, val: 0); |
1665 | mlxsw_reg_svfa_mapping_table_set(buf: payload, val: mt); |
1666 | mlxsw_reg_svfa_v_set(buf: payload, val: valid); |
1667 | mlxsw_reg_svfa_fid_set(buf: payload, val: fid); |
1668 | mlxsw_reg_svfa_irif_v_set(buf: payload, val: irif_v); |
1669 | mlxsw_reg_svfa_irif_set(buf: payload, val: irif_v ? irif : 0); |
1670 | } |
1671 | |
1672 | static inline void mlxsw_reg_svfa_port_vid_pack(char *payload, u16 local_port, |
1673 | bool valid, u16 fid, u16 vid, |
1674 | bool irif_v, u16 irif) |
1675 | { |
1676 | enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID; |
1677 | |
1678 | __mlxsw_reg_svfa_pack(payload, mt, valid, fid, irif_v, irif); |
1679 | mlxsw_reg_svfa_local_port_set(buf: payload, val: local_port); |
1680 | mlxsw_reg_svfa_vid_set(buf: payload, val: vid); |
1681 | } |
1682 | |
1683 | static inline void mlxsw_reg_svfa_vid_pack(char *payload, bool valid, u16 fid, |
1684 | u16 vid, bool irif_v, u16 irif) |
1685 | { |
1686 | enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_VID_TO_FID; |
1687 | |
1688 | __mlxsw_reg_svfa_pack(payload, mt, valid, fid, irif_v, irif); |
1689 | mlxsw_reg_svfa_vid_set(buf: payload, val: vid); |
1690 | } |
1691 | |
1692 | static inline void mlxsw_reg_svfa_vni_pack(char *payload, bool valid, u16 fid, |
1693 | u32 vni, bool irif_v, u16 irif) |
1694 | { |
1695 | enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_VNI_TO_FID; |
1696 | |
1697 | __mlxsw_reg_svfa_pack(payload, mt, valid, fid, irif_v, irif); |
1698 | mlxsw_reg_svfa_vni_set(buf: payload, val: vni); |
1699 | } |
1700 | |
1701 | /* SPVTR - Switch Port VLAN Stacking Register |
1702 | * ------------------------------------------ |
1703 | * The Switch Port VLAN Stacking register configures the VLAN mode of the port |
1704 | * to enable VLAN stacking. |
1705 | */ |
1706 | #define MLXSW_REG_SPVTR_ID 0x201D |
1707 | #define MLXSW_REG_SPVTR_LEN 0x10 |
1708 | |
1709 | MLXSW_REG_DEFINE(spvtr, MLXSW_REG_SPVTR_ID, MLXSW_REG_SPVTR_LEN); |
1710 | |
1711 | /* reg_spvtr_tport |
1712 | * Port is tunnel port. |
1713 | * Access: Index |
1714 | * |
1715 | * Note: Reserved when SwitchX/-2 or Spectrum-1. |
1716 | */ |
1717 | MLXSW_ITEM32(reg, spvtr, tport, 0x00, 24, 1); |
1718 | |
1719 | /* reg_spvtr_local_port |
1720 | * When tport = 0: local port number (Not supported from/to CPU). |
1721 | * When tport = 1: tunnel port. |
1722 | * Access: Index |
1723 | */ |
1724 | MLXSW_ITEM32_LP(reg, spvtr, 0x00, 16, 0x00, 12); |
1725 | |
1726 | /* reg_spvtr_ippe |
1727 | * Ingress Port Prio Mode Update Enable. |
1728 | * When set, the Port Prio Mode is updated with the provided ipprio_mode field. |
1729 | * Reserved on Get operations. |
1730 | * Access: OP |
1731 | */ |
1732 | MLXSW_ITEM32(reg, spvtr, ippe, 0x04, 31, 1); |
1733 | |
1734 | /* reg_spvtr_ipve |
1735 | * Ingress Port VID Mode Update Enable. |
1736 | * When set, the Ingress Port VID Mode is updated with the provided ipvid_mode |
1737 | * field. |
1738 | * Reserved on Get operations. |
1739 | * Access: OP |
1740 | */ |
1741 | MLXSW_ITEM32(reg, spvtr, ipve, 0x04, 30, 1); |
1742 | |
1743 | /* reg_spvtr_epve |
1744 | * Egress Port VID Mode Update Enable. |
1745 | * When set, the Egress Port VID Mode is updated with the provided epvid_mode |
1746 | * field. |
1747 | * Access: OP |
1748 | */ |
1749 | MLXSW_ITEM32(reg, spvtr, epve, 0x04, 29, 1); |
1750 | |
1751 | /* reg_spvtr_ipprio_mode |
1752 | * Ingress Port Priority Mode. |
1753 | * This controls the PCP and DEI of the new outer VLAN |
1754 | * Note: for SwitchX/-2 the DEI is not affected. |
1755 | * 0: use port default PCP and DEI (configured by QPDPC). |
1756 | * 1: use C-VLAN PCP and DEI. |
1757 | * Has no effect when ipvid_mode = 0. |
1758 | * Reserved when tport = 1. |
1759 | * Access: RW |
1760 | */ |
1761 | MLXSW_ITEM32(reg, spvtr, ipprio_mode, 0x04, 20, 4); |
1762 | |
1763 | enum mlxsw_reg_spvtr_ipvid_mode { |
1764 | /* IEEE Compliant PVID (default) */ |
1765 | MLXSW_REG_SPVTR_IPVID_MODE_IEEE_COMPLIANT_PVID, |
1766 | /* Push VLAN (for VLAN stacking, except prio tagged packets) */ |
1767 | MLXSW_REG_SPVTR_IPVID_MODE_PUSH_VLAN_FOR_UNTAGGED_PACKET, |
1768 | /* Always push VLAN (also for prio tagged packets) */ |
1769 | MLXSW_REG_SPVTR_IPVID_MODE_ALWAYS_PUSH_VLAN, |
1770 | }; |
1771 | |
1772 | /* reg_spvtr_ipvid_mode |
1773 | * Ingress Port VLAN-ID Mode. |
1774 | * For Spectrum family, this affects the values of SPVM.i |
1775 | * Access: RW |
1776 | */ |
1777 | MLXSW_ITEM32(reg, spvtr, ipvid_mode, 0x04, 16, 4); |
1778 | |
1779 | enum mlxsw_reg_spvtr_epvid_mode { |
1780 | /* IEEE Compliant VLAN membership */ |
1781 | MLXSW_REG_SPVTR_EPVID_MODE_IEEE_COMPLIANT_VLAN_MEMBERSHIP, |
1782 | /* Pop VLAN (for VLAN stacking) */ |
1783 | MLXSW_REG_SPVTR_EPVID_MODE_POP_VLAN, |
1784 | }; |
1785 | |
1786 | /* reg_spvtr_epvid_mode |
1787 | * Egress Port VLAN-ID Mode. |
1788 | * For Spectrum family, this affects the values of SPVM.e,u,pt. |
1789 | * Access: WO |
1790 | */ |
1791 | MLXSW_ITEM32(reg, spvtr, epvid_mode, 0x04, 0, 4); |
1792 | |
1793 | static inline void mlxsw_reg_spvtr_pack(char *payload, bool tport, |
1794 | u16 local_port, |
1795 | enum mlxsw_reg_spvtr_ipvid_mode ipvid_mode) |
1796 | { |
1797 | MLXSW_REG_ZERO(spvtr, payload); |
1798 | mlxsw_reg_spvtr_tport_set(buf: payload, val: tport); |
1799 | mlxsw_reg_spvtr_local_port_set(buf: payload, val: local_port); |
1800 | mlxsw_reg_spvtr_ipvid_mode_set(buf: payload, val: ipvid_mode); |
1801 | mlxsw_reg_spvtr_ipve_set(buf: payload, val: true); |
1802 | } |
1803 | |
1804 | /* SVPE - Switch Virtual-Port Enabling Register |
1805 | * -------------------------------------------- |
1806 | * Enables port virtualization. |
1807 | */ |
1808 | #define MLXSW_REG_SVPE_ID 0x201E |
1809 | #define MLXSW_REG_SVPE_LEN 0x4 |
1810 | |
1811 | MLXSW_REG_DEFINE(svpe, MLXSW_REG_SVPE_ID, MLXSW_REG_SVPE_LEN); |
1812 | |
1813 | /* reg_svpe_local_port |
1814 | * Local port number |
1815 | * Access: Index |
1816 | * |
1817 | * Note: CPU port is not supported (uses VLAN mode only). |
1818 | */ |
1819 | MLXSW_ITEM32_LP(reg, svpe, 0x00, 16, 0x00, 12); |
1820 | |
1821 | /* reg_svpe_vp_en |
1822 | * Virtual port enable. |
1823 | * 0 - Disable, VLAN mode (VID to FID). |
1824 | * 1 - Enable, Virtual port mode ({Port, VID} to FID). |
1825 | * Access: RW |
1826 | */ |
1827 | MLXSW_ITEM32(reg, svpe, vp_en, 0x00, 8, 1); |
1828 | |
1829 | static inline void mlxsw_reg_svpe_pack(char *payload, u16 local_port, |
1830 | bool enable) |
1831 | { |
1832 | MLXSW_REG_ZERO(svpe, payload); |
1833 | mlxsw_reg_svpe_local_port_set(buf: payload, val: local_port); |
1834 | mlxsw_reg_svpe_vp_en_set(buf: payload, val: enable); |
1835 | } |
1836 | |
1837 | /* SFMR - Switch FID Management Register |
1838 | * ------------------------------------- |
1839 | * Creates and configures FIDs. |
1840 | */ |
1841 | #define MLXSW_REG_SFMR_ID 0x201F |
1842 | #define MLXSW_REG_SFMR_LEN 0x30 |
1843 | |
1844 | MLXSW_REG_DEFINE(sfmr, MLXSW_REG_SFMR_ID, MLXSW_REG_SFMR_LEN); |
1845 | |
1846 | enum mlxsw_reg_sfmr_op { |
1847 | MLXSW_REG_SFMR_OP_CREATE_FID, |
1848 | MLXSW_REG_SFMR_OP_DESTROY_FID, |
1849 | }; |
1850 | |
1851 | /* reg_sfmr_op |
1852 | * Operation. |
1853 | * 0 - Create or edit FID. |
1854 | * 1 - Destroy FID. |
1855 | * Access: WO |
1856 | */ |
1857 | MLXSW_ITEM32(reg, sfmr, op, 0x00, 24, 4); |
1858 | |
1859 | /* reg_sfmr_fid |
1860 | * Filtering ID. |
1861 | * Access: Index |
1862 | */ |
1863 | MLXSW_ITEM32(reg, sfmr, fid, 0x00, 0, 16); |
1864 | |
1865 | /* reg_sfmr_flood_rsp |
1866 | * Router sub-port flooding table. |
1867 | * 0 - Regular flooding table. |
1868 | * 1 - Router sub-port flooding table. For this FID the flooding is per |
1869 | * router-sub-port local_port. Must not be set for a FID which is not a |
1870 | * router-sub-port and must be set prior to enabling the relevant RIF. |
1871 | * Access: RW |
1872 | * |
1873 | * Note: Reserved when legacy bridge model is used. |
1874 | */ |
1875 | MLXSW_ITEM32(reg, sfmr, flood_rsp, 0x08, 31, 1); |
1876 | |
1877 | /* reg_sfmr_flood_bridge_type |
1878 | * Flood bridge type (see SFGC.bridge_type). |
1879 | * 0 - type_0. |
1880 | * 1 - type_1. |
1881 | * Access: RW |
1882 | * |
1883 | * Note: Reserved when legacy bridge model is used and when flood_rsp=1. |
1884 | */ |
1885 | MLXSW_ITEM32(reg, sfmr, flood_bridge_type, 0x08, 28, 1); |
1886 | |
1887 | /* reg_sfmr_fid_offset |
1888 | * FID offset. |
1889 | * Used to point into the flooding table selected by SFGC register if |
1890 | * the table is of type FID-Offset. Otherwise, this field is reserved. |
1891 | * Access: RW |
1892 | */ |
1893 | MLXSW_ITEM32(reg, sfmr, fid_offset, 0x08, 0, 16); |
1894 | |
1895 | /* reg_sfmr_vtfp |
1896 | * Valid Tunnel Flood Pointer. |
1897 | * If not set, then nve_tunnel_flood_ptr is reserved and considered NULL. |
1898 | * Access: RW |
1899 | * |
1900 | * Note: Reserved for 802.1Q FIDs. |
1901 | */ |
1902 | MLXSW_ITEM32(reg, sfmr, vtfp, 0x0C, 31, 1); |
1903 | |
1904 | /* reg_sfmr_nve_tunnel_flood_ptr |
1905 | * Underlay Flooding and BC Pointer. |
1906 | * Used as a pointer to the first entry of the group based link lists of |
1907 | * flooding or BC entries (for NVE tunnels). |
1908 | * Access: RW |
1909 | */ |
1910 | MLXSW_ITEM32(reg, sfmr, nve_tunnel_flood_ptr, 0x0C, 0, 24); |
1911 | |
1912 | /* reg_sfmr_vv |
1913 | * VNI Valid. |
1914 | * If not set, then vni is reserved. |
1915 | * Access: RW |
1916 | * |
1917 | * Note: Reserved for 802.1Q FIDs. |
1918 | */ |
1919 | MLXSW_ITEM32(reg, sfmr, vv, 0x10, 31, 1); |
1920 | |
1921 | /* reg_sfmr_vni |
1922 | * Virtual Network Identifier. |
1923 | * When legacy bridge model is used, a given VNI can only be assigned to one |
1924 | * FID. When unified bridge model is used, it configures only the FID->VNI, |
1925 | * the VNI->FID is done by SVFA. |
1926 | * Access: RW |
1927 | */ |
1928 | MLXSW_ITEM32(reg, sfmr, vni, 0x10, 0, 24); |
1929 | |
1930 | /* reg_sfmr_irif_v |
1931 | * Ingress RIF valid. |
1932 | * 0 - Ingress RIF is not valid, no ingress RIF assigned. |
1933 | * 1 - Ingress RIF valid. |
1934 | * Must not be set for a non valid RIF. |
1935 | * Access: RW |
1936 | * |
1937 | * Note: Reserved when legacy bridge model is used. |
1938 | */ |
1939 | MLXSW_ITEM32(reg, sfmr, irif_v, 0x14, 24, 1); |
1940 | |
1941 | /* reg_sfmr_irif |
1942 | * Ingress RIF (Router Interface). |
1943 | * Range is 0..cap_max_router_interfaces-1. |
1944 | * Access: RW |
1945 | * |
1946 | * Note: Reserved when legacy bridge model is used and when irif_v=0. |
1947 | */ |
1948 | MLXSW_ITEM32(reg, sfmr, irif, 0x14, 0, 16); |
1949 | |
1950 | /* reg_sfmr_smpe_valid |
1951 | * SMPE is valid. |
1952 | * Access: RW |
1953 | * |
1954 | * Note: Reserved when legacy bridge model is used, when flood_rsp=1 and on |
1955 | * Spectrum-1. |
1956 | */ |
1957 | MLXSW_ITEM32(reg, sfmr, smpe_valid, 0x28, 20, 1); |
1958 | |
1959 | /* reg_sfmr_smpe |
1960 | * Switch multicast port to egress VID. |
1961 | * Range is 0..cap_max_rmpe-1 |
1962 | * Access: RW |
1963 | * |
1964 | * Note: Reserved when legacy bridge model is used, when flood_rsp=1 and on |
1965 | * Spectrum-1. |
1966 | */ |
1967 | MLXSW_ITEM32(reg, sfmr, smpe, 0x28, 0, 16); |
1968 | |
1969 | static inline void mlxsw_reg_sfmr_pack(char *payload, |
1970 | enum mlxsw_reg_sfmr_op op, u16 fid, |
1971 | u16 fid_offset, bool flood_rsp, |
1972 | enum mlxsw_reg_bridge_type bridge_type, |
1973 | bool smpe_valid, u16 smpe) |
1974 | { |
1975 | MLXSW_REG_ZERO(sfmr, payload); |
1976 | mlxsw_reg_sfmr_op_set(buf: payload, val: op); |
1977 | mlxsw_reg_sfmr_fid_set(buf: payload, val: fid); |
1978 | mlxsw_reg_sfmr_fid_offset_set(buf: payload, val: fid_offset); |
1979 | mlxsw_reg_sfmr_vtfp_set(buf: payload, val: false); |
1980 | mlxsw_reg_sfmr_vv_set(buf: payload, val: false); |
1981 | mlxsw_reg_sfmr_flood_rsp_set(buf: payload, val: flood_rsp); |
1982 | mlxsw_reg_sfmr_flood_bridge_type_set(buf: payload, val: bridge_type); |
1983 | mlxsw_reg_sfmr_smpe_valid_set(buf: payload, val: smpe_valid); |
1984 | mlxsw_reg_sfmr_smpe_set(buf: payload, val: smpe); |
1985 | } |
1986 | |
1987 | /* SPVMLR - Switch Port VLAN MAC Learning Register |
1988 | * ----------------------------------------------- |
1989 | * Controls the switch MAC learning policy per {Port, VID}. |
1990 | */ |
1991 | #define MLXSW_REG_SPVMLR_ID 0x2020 |
1992 | #define MLXSW_REG_SPVMLR_BASE_LEN 0x04 /* base length, without records */ |
1993 | #define MLXSW_REG_SPVMLR_REC_LEN 0x04 /* record length */ |
1994 | #define MLXSW_REG_SPVMLR_REC_MAX_COUNT 255 |
1995 | #define MLXSW_REG_SPVMLR_LEN (MLXSW_REG_SPVMLR_BASE_LEN + \ |
1996 | MLXSW_REG_SPVMLR_REC_LEN * \ |
1997 | MLXSW_REG_SPVMLR_REC_MAX_COUNT) |
1998 | |
1999 | MLXSW_REG_DEFINE(spvmlr, MLXSW_REG_SPVMLR_ID, MLXSW_REG_SPVMLR_LEN); |
2000 | |
2001 | /* reg_spvmlr_local_port |
2002 | * Local ingress port. |
2003 | * Access: Index |
2004 | * |
2005 | * Note: CPU port is not supported. |
2006 | */ |
2007 | MLXSW_ITEM32_LP(reg, spvmlr, 0x00, 16, 0x00, 12); |
2008 | |
2009 | /* reg_spvmlr_num_rec |
2010 | * Number of records to update. |
2011 | * Access: OP |
2012 | */ |
2013 | MLXSW_ITEM32(reg, spvmlr, num_rec, 0x00, 0, 8); |
2014 | |
2015 | /* reg_spvmlr_rec_learn_enable |
2016 | * 0 - Disable learning for {Port, VID}. |
2017 | * 1 - Enable learning for {Port, VID}. |
2018 | * Access: RW |
2019 | */ |
2020 | MLXSW_ITEM32_INDEXED(reg, spvmlr, rec_learn_enable, MLXSW_REG_SPVMLR_BASE_LEN, |
2021 | 31, 1, MLXSW_REG_SPVMLR_REC_LEN, 0x00, false); |
2022 | |
2023 | /* reg_spvmlr_rec_vid |
2024 | * VLAN ID to be added/removed from port or for querying. |
2025 | * Access: Index |
2026 | */ |
2027 | MLXSW_ITEM32_INDEXED(reg, spvmlr, rec_vid, MLXSW_REG_SPVMLR_BASE_LEN, 0, 12, |
2028 | MLXSW_REG_SPVMLR_REC_LEN, 0x00, false); |
2029 | |
2030 | static inline void mlxsw_reg_spvmlr_pack(char *payload, u16 local_port, |
2031 | u16 vid_begin, u16 vid_end, |
2032 | bool learn_enable) |
2033 | { |
2034 | int num_rec = vid_end - vid_begin + 1; |
2035 | int i; |
2036 | |
2037 | WARN_ON(num_rec < 1 || num_rec > MLXSW_REG_SPVMLR_REC_MAX_COUNT); |
2038 | |
2039 | MLXSW_REG_ZERO(spvmlr, payload); |
2040 | mlxsw_reg_spvmlr_local_port_set(buf: payload, val: local_port); |
2041 | mlxsw_reg_spvmlr_num_rec_set(buf: payload, val: num_rec); |
2042 | |
2043 | for (i = 0; i < num_rec; i++) { |
2044 | mlxsw_reg_spvmlr_rec_learn_enable_set(buf: payload, index: i, val: learn_enable); |
2045 | mlxsw_reg_spvmlr_rec_vid_set(buf: payload, index: i, val: vid_begin + i); |
2046 | } |
2047 | } |
2048 | |
2049 | /* SPFSR - Switch Port FDB Security Register |
2050 | * ----------------------------------------- |
2051 | * Configures the security mode per port. |
2052 | */ |
2053 | #define MLXSW_REG_SPFSR_ID 0x2023 |
2054 | #define MLXSW_REG_SPFSR_LEN 0x08 |
2055 | |
2056 | MLXSW_REG_DEFINE(spfsr, MLXSW_REG_SPFSR_ID, MLXSW_REG_SPFSR_LEN); |
2057 | |
2058 | /* reg_spfsr_local_port |
2059 | * Local port. |
2060 | * Access: Index |
2061 | * |
2062 | * Note: not supported for CPU port. |
2063 | */ |
2064 | MLXSW_ITEM32_LP(reg, spfsr, 0x00, 16, 0x00, 12); |
2065 | |
2066 | /* reg_spfsr_security |
2067 | * Security checks. |
2068 | * 0: disabled (default) |
2069 | * 1: enabled |
2070 | * Access: RW |
2071 | */ |
2072 | MLXSW_ITEM32(reg, spfsr, security, 0x04, 31, 1); |
2073 | |
2074 | static inline void mlxsw_reg_spfsr_pack(char *payload, u16 local_port, |
2075 | bool security) |
2076 | { |
2077 | MLXSW_REG_ZERO(spfsr, payload); |
2078 | mlxsw_reg_spfsr_local_port_set(buf: payload, val: local_port); |
2079 | mlxsw_reg_spfsr_security_set(buf: payload, val: security); |
2080 | } |
2081 | |
2082 | /* SPVC - Switch Port VLAN Classification Register |
2083 | * ----------------------------------------------- |
2084 | * Configures the port to identify packets as untagged / single tagged / |
2085 | * double packets based on the packet EtherTypes. |
2086 | * Ethertype IDs are configured by SVER. |
2087 | */ |
2088 | #define MLXSW_REG_SPVC_ID 0x2026 |
2089 | #define MLXSW_REG_SPVC_LEN 0x0C |
2090 | |
2091 | MLXSW_REG_DEFINE(spvc, MLXSW_REG_SPVC_ID, MLXSW_REG_SPVC_LEN); |
2092 | |
2093 | /* reg_spvc_local_port |
2094 | * Local port. |
2095 | * Access: Index |
2096 | * |
2097 | * Note: applies both to Rx port and Tx port, so if a packet traverses |
2098 | * through Rx port i and a Tx port j then port i and port j must have the |
2099 | * same configuration. |
2100 | */ |
2101 | MLXSW_ITEM32_LP(reg, spvc, 0x00, 16, 0x00, 12); |
2102 | |
2103 | /* reg_spvc_inner_et2 |
2104 | * Vlan Tag1 EtherType2 enable. |
2105 | * Packet is initially classified as double VLAN Tag if in addition to |
2106 | * being classified with a tag0 VLAN Tag its tag1 EtherType value is |
2107 | * equal to ether_type2. |
2108 | * 0: disable (default) |
2109 | * 1: enable |
2110 | * Access: RW |
2111 | */ |
2112 | MLXSW_ITEM32(reg, spvc, inner_et2, 0x08, 17, 1); |
2113 | |
2114 | /* reg_spvc_et2 |
2115 | * Vlan Tag0 EtherType2 enable. |
2116 | * Packet is initially classified as VLAN Tag if its tag0 EtherType is |
2117 | * equal to ether_type2. |
2118 | * 0: disable (default) |
2119 | * 1: enable |
2120 | * Access: RW |
2121 | */ |
2122 | MLXSW_ITEM32(reg, spvc, et2, 0x08, 16, 1); |
2123 | |
2124 | /* reg_spvc_inner_et1 |
2125 | * Vlan Tag1 EtherType1 enable. |
2126 | * Packet is initially classified as double VLAN Tag if in addition to |
2127 | * being classified with a tag0 VLAN Tag its tag1 EtherType value is |
2128 | * equal to ether_type1. |
2129 | * 0: disable |
2130 | * 1: enable (default) |
2131 | * Access: RW |
2132 | */ |
2133 | MLXSW_ITEM32(reg, spvc, inner_et1, 0x08, 9, 1); |
2134 | |
2135 | /* reg_spvc_et1 |
2136 | * Vlan Tag0 EtherType1 enable. |
2137 | * Packet is initially classified as VLAN Tag if its tag0 EtherType is |
2138 | * equal to ether_type1. |
2139 | * 0: disable |
2140 | * 1: enable (default) |
2141 | * Access: RW |
2142 | */ |
2143 | MLXSW_ITEM32(reg, spvc, et1, 0x08, 8, 1); |
2144 | |
2145 | /* reg_inner_et0 |
2146 | * Vlan Tag1 EtherType0 enable. |
2147 | * Packet is initially classified as double VLAN Tag if in addition to |
2148 | * being classified with a tag0 VLAN Tag its tag1 EtherType value is |
2149 | * equal to ether_type0. |
2150 | * 0: disable |
2151 | * 1: enable (default) |
2152 | * Access: RW |
2153 | */ |
2154 | MLXSW_ITEM32(reg, spvc, inner_et0, 0x08, 1, 1); |
2155 | |
2156 | /* reg_et0 |
2157 | * Vlan Tag0 EtherType0 enable. |
2158 | * Packet is initially classified as VLAN Tag if its tag0 EtherType is |
2159 | * equal to ether_type0. |
2160 | * 0: disable |
2161 | * 1: enable (default) |
2162 | * Access: RW |
2163 | */ |
2164 | MLXSW_ITEM32(reg, spvc, et0, 0x08, 0, 1); |
2165 | |
2166 | static inline void mlxsw_reg_spvc_pack(char *payload, u16 local_port, bool et1, |
2167 | bool et0) |
2168 | { |
2169 | MLXSW_REG_ZERO(spvc, payload); |
2170 | mlxsw_reg_spvc_local_port_set(buf: payload, val: local_port); |
2171 | /* Enable inner_et1 and inner_et0 to enable identification of double |
2172 | * tagged packets. |
2173 | */ |
2174 | mlxsw_reg_spvc_inner_et1_set(buf: payload, val: 1); |
2175 | mlxsw_reg_spvc_inner_et0_set(buf: payload, val: 1); |
2176 | mlxsw_reg_spvc_et1_set(buf: payload, val: et1); |
2177 | mlxsw_reg_spvc_et0_set(buf: payload, val: et0); |
2178 | } |
2179 | |
2180 | /* SPEVET - Switch Port Egress VLAN EtherType |
2181 | * ------------------------------------------ |
2182 | * The switch port egress VLAN EtherType configures which EtherType to push at |
2183 | * egress for packets incoming through a local port for which 'SPVID.egr_et_set' |
2184 | * is set. |
2185 | */ |
2186 | #define MLXSW_REG_SPEVET_ID 0x202A |
2187 | #define MLXSW_REG_SPEVET_LEN 0x08 |
2188 | |
2189 | MLXSW_REG_DEFINE(spevet, MLXSW_REG_SPEVET_ID, MLXSW_REG_SPEVET_LEN); |
2190 | |
2191 | /* reg_spevet_local_port |
2192 | * Egress Local port number. |
2193 | * Not supported to CPU port. |
2194 | * Access: Index |
2195 | */ |
2196 | MLXSW_ITEM32_LP(reg, spevet, 0x00, 16, 0x00, 12); |
2197 | |
2198 | /* reg_spevet_et_vlan |
2199 | * Egress EtherType VLAN to push when SPVID.egr_et_set field set for the packet: |
2200 | * 0: ether_type0 - (default) |
2201 | * 1: ether_type1 |
2202 | * 2: ether_type2 |
2203 | * Access: RW |
2204 | */ |
2205 | MLXSW_ITEM32(reg, spevet, et_vlan, 0x04, 16, 2); |
2206 | |
2207 | static inline void mlxsw_reg_spevet_pack(char *payload, u16 local_port, |
2208 | u8 et_vlan) |
2209 | { |
2210 | MLXSW_REG_ZERO(spevet, payload); |
2211 | mlxsw_reg_spevet_local_port_set(buf: payload, val: local_port); |
2212 | mlxsw_reg_spevet_et_vlan_set(payload, et_vlan); |
2213 | } |
2214 | |
2215 | /* SMPE - Switch Multicast Port to Egress VID |
2216 | * ------------------------------------------ |
2217 | * The switch multicast port to egress VID maps |
2218 | * {egress_port, SMPE index} -> {VID}. |
2219 | */ |
2220 | #define MLXSW_REG_SMPE_ID 0x202B |
2221 | #define MLXSW_REG_SMPE_LEN 0x0C |
2222 | |
2223 | MLXSW_REG_DEFINE(smpe, MLXSW_REG_SMPE_ID, MLXSW_REG_SMPE_LEN); |
2224 | |
2225 | /* reg_smpe_local_port |
2226 | * Local port number. |
2227 | * CPU port is not supported. |
2228 | * Access: Index |
2229 | */ |
2230 | MLXSW_ITEM32_LP(reg, smpe, 0x00, 16, 0x00, 12); |
2231 | |
2232 | /* reg_smpe_smpe_index |
2233 | * Switch multicast port to egress VID. |
2234 | * Range is 0..cap_max_rmpe-1. |
2235 | * Access: Index |
2236 | */ |
2237 | MLXSW_ITEM32(reg, smpe, smpe_index, 0x04, 0, 16); |
2238 | |
2239 | /* reg_smpe_evid |
2240 | * Egress VID. |
2241 | * Access: RW |
2242 | */ |
2243 | MLXSW_ITEM32(reg, smpe, evid, 0x08, 0, 12); |
2244 | |
2245 | static inline void mlxsw_reg_smpe_pack(char *payload, u16 local_port, |
2246 | u16 smpe_index, u16 evid) |
2247 | { |
2248 | MLXSW_REG_ZERO(smpe, payload); |
2249 | mlxsw_reg_smpe_local_port_set(buf: payload, val: local_port); |
2250 | mlxsw_reg_smpe_smpe_index_set(buf: payload, val: smpe_index); |
2251 | mlxsw_reg_smpe_evid_set(buf: payload, val: evid); |
2252 | } |
2253 | |
2254 | /* SMID-V2 - Switch Multicast ID Version 2 Register |
2255 | * ------------------------------------------------ |
2256 | * The MID record maps from a MID (Multicast ID), which is a unique identifier |
2257 | * of the multicast group within the stacking domain, into a list of local |
2258 | * ports into which the packet is replicated. |
2259 | */ |
2260 | #define MLXSW_REG_SMID2_ID 0x2034 |
2261 | #define MLXSW_REG_SMID2_LEN 0x120 |
2262 | |
2263 | MLXSW_REG_DEFINE(smid2, MLXSW_REG_SMID2_ID, MLXSW_REG_SMID2_LEN); |
2264 | |
2265 | /* reg_smid2_swid |
2266 | * Switch partition ID. |
2267 | * Access: Index |
2268 | */ |
2269 | MLXSW_ITEM32(reg, smid2, swid, 0x00, 24, 8); |
2270 | |
2271 | /* reg_smid2_mid |
2272 | * Multicast identifier - global identifier that represents the multicast group |
2273 | * across all devices. |
2274 | * Access: Index |
2275 | */ |
2276 | MLXSW_ITEM32(reg, smid2, mid, 0x00, 0, 16); |
2277 | |
2278 | /* reg_smid2_smpe_valid |
2279 | * SMPE is valid. |
2280 | * When not valid, the egress VID will not be modified by the SMPE table. |
2281 | * Access: RW |
2282 | * |
2283 | * Note: Reserved when legacy bridge model is used and on Spectrum-2. |
2284 | */ |
2285 | MLXSW_ITEM32(reg, smid2, smpe_valid, 0x08, 20, 1); |
2286 | |
2287 | /* reg_smid2_smpe |
2288 | * Switch multicast port to egress VID. |
2289 | * Access: RW |
2290 | * |
2291 | * Note: Reserved when legacy bridge model is used and on Spectrum-2. |
2292 | */ |
2293 | MLXSW_ITEM32(reg, smid2, smpe, 0x08, 0, 16); |
2294 | |
2295 | /* reg_smid2_port |
2296 | * Local port memebership (1 bit per port). |
2297 | * Access: RW |
2298 | */ |
2299 | MLXSW_ITEM_BIT_ARRAY(reg, smid2, port, 0x20, 0x80, 1); |
2300 | |
2301 | /* reg_smid2_port_mask |
2302 | * Local port mask (1 bit per port). |
2303 | * Access: WO |
2304 | */ |
2305 | MLXSW_ITEM_BIT_ARRAY(reg, smid2, port_mask, 0xA0, 0x80, 1); |
2306 | |
2307 | static inline void mlxsw_reg_smid2_pack(char *payload, u16 mid, u16 port, |
2308 | bool set, bool smpe_valid, u16 smpe) |
2309 | { |
2310 | MLXSW_REG_ZERO(smid2, payload); |
2311 | mlxsw_reg_smid2_swid_set(buf: payload, val: 0); |
2312 | mlxsw_reg_smid2_mid_set(buf: payload, val: mid); |
2313 | mlxsw_reg_smid2_port_set(payload, port, set); |
2314 | mlxsw_reg_smid2_port_mask_set(payload, port, 1); |
2315 | mlxsw_reg_smid2_smpe_valid_set(buf: payload, val: smpe_valid); |
2316 | mlxsw_reg_smid2_smpe_set(buf: payload, val: smpe_valid ? smpe : 0); |
2317 | } |
2318 | |
2319 | /* CWTP - Congetion WRED ECN TClass Profile |
2320 | * ---------------------------------------- |
2321 | * Configures the profiles for queues of egress port and traffic class |
2322 | */ |
2323 | #define MLXSW_REG_CWTP_ID 0x2802 |
2324 | #define MLXSW_REG_CWTP_BASE_LEN 0x28 |
2325 | #define MLXSW_REG_CWTP_PROFILE_DATA_REC_LEN 0x08 |
2326 | #define MLXSW_REG_CWTP_LEN 0x40 |
2327 | |
2328 | MLXSW_REG_DEFINE(cwtp, MLXSW_REG_CWTP_ID, MLXSW_REG_CWTP_LEN); |
2329 | |
2330 | /* reg_cwtp_local_port |
2331 | * Local port number |
2332 | * Not supported for CPU port |
2333 | * Access: Index |
2334 | */ |
2335 | MLXSW_ITEM32_LP(reg, cwtp, 0x00, 16, 0x00, 12); |
2336 | |
2337 | /* reg_cwtp_traffic_class |
2338 | * Traffic Class to configure |
2339 | * Access: Index |
2340 | */ |
2341 | MLXSW_ITEM32(reg, cwtp, traffic_class, 32, 0, 8); |
2342 | |
2343 | /* reg_cwtp_profile_min |
2344 | * Minimum Average Queue Size of the profile in cells. |
2345 | * Access: RW |
2346 | */ |
2347 | MLXSW_ITEM32_INDEXED(reg, cwtp, profile_min, MLXSW_REG_CWTP_BASE_LEN, |
2348 | 0, 20, MLXSW_REG_CWTP_PROFILE_DATA_REC_LEN, 0, false); |
2349 | |
2350 | /* reg_cwtp_profile_percent |
2351 | * Percentage of WRED and ECN marking for maximum Average Queue size |
2352 | * Range is 0 to 100, units of integer percentage |
2353 | * Access: RW |
2354 | */ |
2355 | MLXSW_ITEM32_INDEXED(reg, cwtp, profile_percent, MLXSW_REG_CWTP_BASE_LEN, |
2356 | 24, 7, MLXSW_REG_CWTP_PROFILE_DATA_REC_LEN, 4, false); |
2357 | |
2358 | /* reg_cwtp_profile_max |
2359 | * Maximum Average Queue size of the profile in cells |
2360 | * Access: RW |
2361 | */ |
2362 | MLXSW_ITEM32_INDEXED(reg, cwtp, profile_max, MLXSW_REG_CWTP_BASE_LEN, |
2363 | 0, 20, MLXSW_REG_CWTP_PROFILE_DATA_REC_LEN, 4, false); |
2364 | |
2365 | #define MLXSW_REG_CWTP_MIN_VALUE 64 |
2366 | #define MLXSW_REG_CWTP_MAX_PROFILE 2 |
2367 | #define MLXSW_REG_CWTP_DEFAULT_PROFILE 1 |
2368 | |
2369 | static inline void mlxsw_reg_cwtp_pack(char *payload, u16 local_port, |
2370 | u8 traffic_class) |
2371 | { |
2372 | int i; |
2373 | |
2374 | MLXSW_REG_ZERO(cwtp, payload); |
2375 | mlxsw_reg_cwtp_local_port_set(buf: payload, val: local_port); |
2376 | mlxsw_reg_cwtp_traffic_class_set(payload, traffic_class); |
2377 | |
2378 | for (i = 0; i <= MLXSW_REG_CWTP_MAX_PROFILE; i++) { |
2379 | mlxsw_reg_cwtp_profile_min_set(buf: payload, index: i, |
2380 | MLXSW_REG_CWTP_MIN_VALUE); |
2381 | mlxsw_reg_cwtp_profile_max_set(buf: payload, index: i, |
2382 | MLXSW_REG_CWTP_MIN_VALUE); |
2383 | } |
2384 | } |
2385 | |
2386 | #define MLXSW_REG_CWTP_PROFILE_TO_INDEX(profile) (profile - 1) |
2387 | |
2388 | static inline void |
2389 | mlxsw_reg_cwtp_profile_pack(char *payload, u8 profile, u32 min, u32 max, |
2390 | u32 probability) |
2391 | { |
2392 | u8 index = MLXSW_REG_CWTP_PROFILE_TO_INDEX(profile); |
2393 | |
2394 | mlxsw_reg_cwtp_profile_min_set(buf: payload, index, val: min); |
2395 | mlxsw_reg_cwtp_profile_max_set(buf: payload, index, val: max); |
2396 | mlxsw_reg_cwtp_profile_percent_set(buf: payload, index, val: probability); |
2397 | } |
2398 | |
2399 | /* CWTPM - Congestion WRED ECN TClass and Pool Mapping |
2400 | * --------------------------------------------------- |
2401 | * The CWTPM register maps each egress port and traffic class to profile num. |
2402 | */ |
2403 | #define MLXSW_REG_CWTPM_ID 0x2803 |
2404 | #define MLXSW_REG_CWTPM_LEN 0x44 |
2405 | |
2406 | MLXSW_REG_DEFINE(cwtpm, MLXSW_REG_CWTPM_ID, MLXSW_REG_CWTPM_LEN); |
2407 | |
2408 | /* reg_cwtpm_local_port |
2409 | * Local port number |
2410 | * Not supported for CPU port |
2411 | * Access: Index |
2412 | */ |
2413 | MLXSW_ITEM32_LP(reg, cwtpm, 0x00, 16, 0x00, 12); |
2414 | |
2415 | /* reg_cwtpm_traffic_class |
2416 | * Traffic Class to configure |
2417 | * Access: Index |
2418 | */ |
2419 | MLXSW_ITEM32(reg, cwtpm, traffic_class, 32, 0, 8); |
2420 | |
2421 | /* reg_cwtpm_ew |
2422 | * Control enablement of WRED for traffic class: |
2423 | * 0 - Disable |
2424 | * 1 - Enable |
2425 | * Access: RW |
2426 | */ |
2427 | MLXSW_ITEM32(reg, cwtpm, ew, 36, 1, 1); |
2428 | |
2429 | /* reg_cwtpm_ee |
2430 | * Control enablement of ECN for traffic class: |
2431 | * 0 - Disable |
2432 | * 1 - Enable |
2433 | * Access: RW |
2434 | */ |
2435 | MLXSW_ITEM32(reg, cwtpm, ee, 36, 0, 1); |
2436 | |
2437 | /* reg_cwtpm_tcp_g |
2438 | * TCP Green Profile. |
2439 | * Index of the profile within {port, traffic class} to use. |
2440 | * 0 for disabling both WRED and ECN for this type of traffic. |
2441 | * Access: RW |
2442 | */ |
2443 | MLXSW_ITEM32(reg, cwtpm, tcp_g, 52, 0, 2); |
2444 | |
2445 | /* reg_cwtpm_tcp_y |
2446 | * TCP Yellow Profile. |
2447 | * Index of the profile within {port, traffic class} to use. |
2448 | * 0 for disabling both WRED and ECN for this type of traffic. |
2449 | * Access: RW |
2450 | */ |
2451 | MLXSW_ITEM32(reg, cwtpm, tcp_y, 56, 16, 2); |
2452 | |
2453 | /* reg_cwtpm_tcp_r |
2454 | * TCP Red Profile. |
2455 | * Index of the profile within {port, traffic class} to use. |
2456 | * 0 for disabling both WRED and ECN for this type of traffic. |
2457 | * Access: RW |
2458 | */ |
2459 | MLXSW_ITEM32(reg, cwtpm, tcp_r, 56, 0, 2); |
2460 | |
2461 | /* reg_cwtpm_ntcp_g |
2462 | * Non-TCP Green Profile. |
2463 | * Index of the profile within {port, traffic class} to use. |
2464 | * 0 for disabling both WRED and ECN for this type of traffic. |
2465 | * Access: RW |
2466 | */ |
2467 | MLXSW_ITEM32(reg, cwtpm, ntcp_g, 60, 0, 2); |
2468 | |
2469 | /* reg_cwtpm_ntcp_y |
2470 | * Non-TCP Yellow Profile. |
2471 | * Index of the profile within {port, traffic class} to use. |
2472 | * 0 for disabling both WRED and ECN for this type of traffic. |
2473 | * Access: RW |
2474 | */ |
2475 | MLXSW_ITEM32(reg, cwtpm, ntcp_y, 64, 16, 2); |
2476 | |
2477 | /* reg_cwtpm_ntcp_r |
2478 | * Non-TCP Red Profile. |
2479 | * Index of the profile within {port, traffic class} to use. |
2480 | * 0 for disabling both WRED and ECN for this type of traffic. |
2481 | * Access: RW |
2482 | */ |
2483 | MLXSW_ITEM32(reg, cwtpm, ntcp_r, 64, 0, 2); |
2484 | |
2485 | #define MLXSW_REG_CWTPM_RESET_PROFILE 0 |
2486 | |
2487 | static inline void mlxsw_reg_cwtpm_pack(char *payload, u16 local_port, |
2488 | u8 traffic_class, u8 profile, |
2489 | bool wred, bool ecn) |
2490 | { |
2491 | MLXSW_REG_ZERO(cwtpm, payload); |
2492 | mlxsw_reg_cwtpm_local_port_set(buf: payload, val: local_port); |
2493 | mlxsw_reg_cwtpm_traffic_class_set(payload, traffic_class); |
2494 | mlxsw_reg_cwtpm_ew_set(buf: payload, val: wred); |
2495 | mlxsw_reg_cwtpm_ee_set(buf: payload, val: ecn); |
2496 | mlxsw_reg_cwtpm_tcp_g_set(payload, profile); |
2497 | mlxsw_reg_cwtpm_tcp_y_set(payload, profile); |
2498 | mlxsw_reg_cwtpm_tcp_r_set(payload, profile); |
2499 | mlxsw_reg_cwtpm_ntcp_g_set(payload, profile); |
2500 | mlxsw_reg_cwtpm_ntcp_y_set(payload, profile); |
2501 | mlxsw_reg_cwtpm_ntcp_r_set(payload, profile); |
2502 | } |
2503 | |
2504 | /* PGCR - Policy-Engine General Configuration Register |
2505 | * --------------------------------------------------- |
2506 | * This register configures general Policy-Engine settings. |
2507 | */ |
2508 | #define MLXSW_REG_PGCR_ID 0x3001 |
2509 | #define MLXSW_REG_PGCR_LEN 0x20 |
2510 | |
2511 | MLXSW_REG_DEFINE(pgcr, MLXSW_REG_PGCR_ID, MLXSW_REG_PGCR_LEN); |
2512 | |
2513 | /* reg_pgcr_default_action_pointer_base |
2514 | * Default action pointer base. Each region has a default action pointer |
2515 | * which is equal to default_action_pointer_base + region_id. |
2516 | * Access: RW |
2517 | */ |
2518 | MLXSW_ITEM32(reg, pgcr, default_action_pointer_base, 0x1C, 0, 24); |
2519 | |
2520 | static inline void mlxsw_reg_pgcr_pack(char *payload, u32 pointer_base) |
2521 | { |
2522 | MLXSW_REG_ZERO(pgcr, payload); |
2523 | mlxsw_reg_pgcr_default_action_pointer_base_set(buf: payload, val: pointer_base); |
2524 | } |
2525 | |
2526 | /* PPBT - Policy-Engine Port Binding Table |
2527 | * --------------------------------------- |
2528 | * This register is used for configuration of the Port Binding Table. |
2529 | */ |
2530 | #define MLXSW_REG_PPBT_ID 0x3002 |
2531 | #define MLXSW_REG_PPBT_LEN 0x14 |
2532 | |
2533 | MLXSW_REG_DEFINE(ppbt, MLXSW_REG_PPBT_ID, MLXSW_REG_PPBT_LEN); |
2534 | |
2535 | enum mlxsw_reg_pxbt_e { |
2536 | MLXSW_REG_PXBT_E_IACL, |
2537 | MLXSW_REG_PXBT_E_EACL, |
2538 | }; |
2539 | |
2540 | /* reg_ppbt_e |
2541 | * Access: Index |
2542 | */ |
2543 | MLXSW_ITEM32(reg, ppbt, e, 0x00, 31, 1); |
2544 | |
2545 | enum mlxsw_reg_pxbt_op { |
2546 | MLXSW_REG_PXBT_OP_BIND, |
2547 | MLXSW_REG_PXBT_OP_UNBIND, |
2548 | }; |
2549 | |
2550 | /* reg_ppbt_op |
2551 | * Access: RW |
2552 | */ |
2553 | MLXSW_ITEM32(reg, ppbt, op, 0x00, 28, 3); |
2554 | |
2555 | /* reg_ppbt_local_port |
2556 | * Local port. Not including CPU port. |
2557 | * Access: Index |
2558 | */ |
2559 | MLXSW_ITEM32_LP(reg, ppbt, 0x00, 16, 0x00, 12); |
2560 | |
2561 | /* reg_ppbt_g |
2562 | * group - When set, the binding is of an ACL group. When cleared, |
2563 | * the binding is of an ACL. |
2564 | * Must be set to 1 for Spectrum. |
2565 | * Access: RW |
2566 | */ |
2567 | MLXSW_ITEM32(reg, ppbt, g, 0x10, 31, 1); |
2568 | |
2569 | /* reg_ppbt_acl_info |
2570 | * ACL/ACL group identifier. If the g bit is set, this field should hold |
2571 | * the acl_group_id, else it should hold the acl_id. |
2572 | * Access: RW |
2573 | */ |
2574 | MLXSW_ITEM32(reg, ppbt, acl_info, 0x10, 0, 16); |
2575 | |
2576 | static inline void mlxsw_reg_ppbt_pack(char *payload, enum mlxsw_reg_pxbt_e e, |
2577 | enum mlxsw_reg_pxbt_op op, |
2578 | u16 local_port, u16 acl_info) |
2579 | { |
2580 | MLXSW_REG_ZERO(ppbt, payload); |
2581 | mlxsw_reg_ppbt_e_set(buf: payload, val: e); |
2582 | mlxsw_reg_ppbt_op_set(buf: payload, val: op); |
2583 | mlxsw_reg_ppbt_local_port_set(buf: payload, val: local_port); |
2584 | mlxsw_reg_ppbt_g_set(buf: payload, val: true); |
2585 | mlxsw_reg_ppbt_acl_info_set(buf: payload, val: acl_info); |
2586 | } |
2587 | |
2588 | /* PACL - Policy-Engine ACL Register |
2589 | * --------------------------------- |
2590 | * This register is used for configuration of the ACL. |
2591 | */ |
2592 | #define MLXSW_REG_PACL_ID 0x3004 |
2593 | #define MLXSW_REG_PACL_LEN 0x70 |
2594 | |
2595 | MLXSW_REG_DEFINE(pacl, MLXSW_REG_PACL_ID, MLXSW_REG_PACL_LEN); |
2596 | |
2597 | /* reg_pacl_v |
2598 | * Valid. Setting the v bit makes the ACL valid. It should not be cleared |
2599 | * while the ACL is bounded to either a port, VLAN or ACL rule. |
2600 | * Access: RW |
2601 | */ |
2602 | MLXSW_ITEM32(reg, pacl, v, 0x00, 24, 1); |
2603 | |
2604 | /* reg_pacl_acl_id |
2605 | * An identifier representing the ACL (managed by software) |
2606 | * Range 0 .. cap_max_acl_regions - 1 |
2607 | * Access: Index |
2608 | */ |
2609 | MLXSW_ITEM32(reg, pacl, acl_id, 0x08, 0, 16); |
2610 | |
2611 | #define MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN 16 |
2612 | |
2613 | /* reg_pacl_tcam_region_info |
2614 | * Opaque object that represents a TCAM region. |
2615 | * Obtained through PTAR register. |
2616 | * Access: RW |
2617 | */ |
2618 | MLXSW_ITEM_BUF(reg, pacl, tcam_region_info, 0x30, |
2619 | MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN); |
2620 | |
2621 | static inline void mlxsw_reg_pacl_pack(char *payload, u16 acl_id, |
2622 | bool valid, const char *tcam_region_info) |
2623 | { |
2624 | MLXSW_REG_ZERO(pacl, payload); |
2625 | mlxsw_reg_pacl_acl_id_set(buf: payload, val: acl_id); |
2626 | mlxsw_reg_pacl_v_set(buf: payload, val: valid); |
2627 | mlxsw_reg_pacl_tcam_region_info_memcpy_to(buf: payload, src: tcam_region_info); |
2628 | } |
2629 | |
2630 | /* PAGT - Policy-Engine ACL Group Table |
2631 | * ------------------------------------ |
2632 | * This register is used for configuration of the ACL Group Table. |
2633 | */ |
2634 | #define MLXSW_REG_PAGT_ID 0x3005 |
2635 | #define MLXSW_REG_PAGT_BASE_LEN 0x30 |
2636 | #define MLXSW_REG_PAGT_ACL_LEN 4 |
2637 | #define MLXSW_REG_PAGT_ACL_MAX_NUM 16 |
2638 | #define MLXSW_REG_PAGT_LEN (MLXSW_REG_PAGT_BASE_LEN + \ |
2639 | MLXSW_REG_PAGT_ACL_MAX_NUM * MLXSW_REG_PAGT_ACL_LEN) |
2640 | |
2641 | MLXSW_REG_DEFINE(pagt, MLXSW_REG_PAGT_ID, MLXSW_REG_PAGT_LEN); |
2642 | |
2643 | /* reg_pagt_size |
2644 | * Number of ACLs in the group. |
2645 | * Size 0 invalidates a group. |
2646 | * Range 0 .. cap_max_acl_group_size (hard coded to 16 for now) |
2647 | * Total number of ACLs in all groups must be lower or equal |
2648 | * to cap_max_acl_tot_groups |
2649 | * Note: a group which is binded must not be invalidated |
2650 | * Access: Index |
2651 | */ |
2652 | MLXSW_ITEM32(reg, pagt, size, 0x00, 0, 8); |
2653 | |
2654 | /* reg_pagt_acl_group_id |
2655 | * An identifier (numbered from 0..cap_max_acl_groups-1) representing |
2656 | * the ACL Group identifier (managed by software). |
2657 | * Access: Index |
2658 | */ |
2659 | MLXSW_ITEM32(reg, pagt, acl_group_id, 0x08, 0, 16); |
2660 | |
2661 | /* reg_pagt_multi |
2662 | * Multi-ACL |
2663 | * 0 - This ACL is the last ACL in the multi-ACL |
2664 | * 1 - This ACL is part of a multi-ACL |
2665 | * Access: RW |
2666 | */ |
2667 | MLXSW_ITEM32_INDEXED(reg, pagt, multi, 0x30, 31, 1, 0x04, 0x00, false); |
2668 | |
2669 | /* reg_pagt_acl_id |
2670 | * ACL identifier |
2671 | * Access: RW |
2672 | */ |
2673 | MLXSW_ITEM32_INDEXED(reg, pagt, acl_id, 0x30, 0, 16, 0x04, 0x00, false); |
2674 | |
2675 | static inline void mlxsw_reg_pagt_pack(char *payload, u16 acl_group_id) |
2676 | { |
2677 | MLXSW_REG_ZERO(pagt, payload); |
2678 | mlxsw_reg_pagt_acl_group_id_set(buf: payload, val: acl_group_id); |
2679 | } |
2680 | |
2681 | static inline void mlxsw_reg_pagt_acl_id_pack(char *payload, int index, |
2682 | u16 acl_id, bool multi) |
2683 | { |
2684 | u8 size = mlxsw_reg_pagt_size_get(payload); |
2685 | |
2686 | if (index >= size) |
2687 | mlxsw_reg_pagt_size_set(buf: payload, val: index + 1); |
2688 | mlxsw_reg_pagt_multi_set(buf: payload, index, val: multi); |
2689 | mlxsw_reg_pagt_acl_id_set(buf: payload, index, val: acl_id); |
2690 | } |
2691 | |
2692 | /* PTAR - Policy-Engine TCAM Allocation Register |
2693 | * --------------------------------------------- |
2694 | * This register is used for allocation of regions in the TCAM. |
2695 | * Note: Query method is not supported on this register. |
2696 | */ |
2697 | #define MLXSW_REG_PTAR_ID 0x3006 |
2698 | #define MLXSW_REG_PTAR_BASE_LEN 0x20 |
2699 | #define MLXSW_REG_PTAR_KEY_ID_LEN 1 |
2700 | #define MLXSW_REG_PTAR_KEY_ID_MAX_NUM 16 |
2701 | #define MLXSW_REG_PTAR_LEN (MLXSW_REG_PTAR_BASE_LEN + \ |
2702 | MLXSW_REG_PTAR_KEY_ID_MAX_NUM * MLXSW_REG_PTAR_KEY_ID_LEN) |
2703 | |
2704 | MLXSW_REG_DEFINE(ptar, MLXSW_REG_PTAR_ID, MLXSW_REG_PTAR_LEN); |
2705 | |
2706 | enum mlxsw_reg_ptar_op { |
2707 | /* allocate a TCAM region */ |
2708 | MLXSW_REG_PTAR_OP_ALLOC, |
2709 | /* resize a TCAM region */ |
2710 | MLXSW_REG_PTAR_OP_RESIZE, |
2711 | /* deallocate TCAM region */ |
2712 | MLXSW_REG_PTAR_OP_FREE, |
2713 | /* test allocation */ |
2714 | MLXSW_REG_PTAR_OP_TEST, |
2715 | }; |
2716 | |
2717 | /* reg_ptar_op |
2718 | * Access: OP |
2719 | */ |
2720 | MLXSW_ITEM32(reg, ptar, op, 0x00, 28, 4); |
2721 | |
2722 | /* reg_ptar_action_set_type |
2723 | * Type of action set to be used on this region. |
2724 | * For Spectrum and Spectrum-2, this is always type 2 - "flexible" |
2725 | * Access: WO |
2726 | */ |
2727 | MLXSW_ITEM32(reg, ptar, action_set_type, 0x00, 16, 8); |
2728 | |
2729 | enum mlxsw_reg_ptar_key_type { |
2730 | MLXSW_REG_PTAR_KEY_TYPE_FLEX = 0x50, /* Spetrum */ |
2731 | MLXSW_REG_PTAR_KEY_TYPE_FLEX2 = 0x51, /* Spectrum-2 */ |
2732 | }; |
2733 | |
2734 | /* reg_ptar_key_type |
2735 | * TCAM key type for the region. |
2736 | * Access: WO |
2737 | */ |
2738 | MLXSW_ITEM32(reg, ptar, key_type, 0x00, 0, 8); |
2739 | |
2740 | /* reg_ptar_region_size |
2741 | * TCAM region size. When allocating/resizing this is the requested size, |
2742 | * the response is the actual size. Note that actual size may be |
2743 | * larger than requested. |
2744 | * Allowed range 1 .. cap_max_rules-1 |
2745 | * Reserved during op deallocate. |
2746 | * Access: WO |
2747 | */ |
2748 | MLXSW_ITEM32(reg, ptar, region_size, 0x04, 0, 16); |
2749 | |
2750 | /* reg_ptar_region_id |
2751 | * Region identifier |
2752 | * Range 0 .. cap_max_regions-1 |
2753 | * Access: Index |
2754 | */ |
2755 | MLXSW_ITEM32(reg, ptar, region_id, 0x08, 0, 16); |
2756 | |
2757 | /* reg_ptar_tcam_region_info |
2758 | * Opaque object that represents the TCAM region. |
2759 | * Returned when allocating a region. |
2760 | * Provided by software for ACL generation and region deallocation and resize. |
2761 | * Access: RW |
2762 | */ |
2763 | MLXSW_ITEM_BUF(reg, ptar, tcam_region_info, 0x10, |
2764 | MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN); |
2765 | |
2766 | /* reg_ptar_flexible_key_id |
2767 | * Identifier of the Flexible Key. |
2768 | * Only valid if key_type == "FLEX_KEY" |
2769 | * The key size will be rounded up to one of the following values: |
2770 | * 9B, 18B, 36B, 54B. |
2771 | * This field is reserved for in resize operation. |
2772 | * Access: WO |
2773 | */ |
2774 | MLXSW_ITEM8_INDEXED(reg, ptar, flexible_key_id, 0x20, 0, 8, |
2775 | MLXSW_REG_PTAR_KEY_ID_LEN, 0x00, false); |
2776 | |
2777 | static inline void mlxsw_reg_ptar_pack(char *payload, enum mlxsw_reg_ptar_op op, |
2778 | enum mlxsw_reg_ptar_key_type key_type, |
2779 | u16 region_size, u16 region_id, |
2780 | const char *tcam_region_info) |
2781 | { |
2782 | MLXSW_REG_ZERO(ptar, payload); |
2783 | mlxsw_reg_ptar_op_set(buf: payload, val: op); |
2784 | mlxsw_reg_ptar_action_set_type_set(buf: payload, val: 2); /* "flexible" */ |
2785 | mlxsw_reg_ptar_key_type_set(buf: payload, val: key_type); |
2786 | mlxsw_reg_ptar_region_size_set(buf: payload, val: region_size); |
2787 | mlxsw_reg_ptar_region_id_set(buf: payload, val: region_id); |
2788 | mlxsw_reg_ptar_tcam_region_info_memcpy_to(buf: payload, src: tcam_region_info); |
2789 | } |
2790 | |
2791 | static inline void mlxsw_reg_ptar_key_id_pack(char *payload, int index, |
2792 | u16 key_id) |
2793 | { |
2794 | mlxsw_reg_ptar_flexible_key_id_set(payload, index, key_id); |
2795 | } |
2796 | |
2797 | static inline void mlxsw_reg_ptar_unpack(char *payload, char *tcam_region_info) |
2798 | { |
2799 | mlxsw_reg_ptar_tcam_region_info_memcpy_from(buf: payload, dst: tcam_region_info); |
2800 | } |
2801 | |
2802 | /* PPBS - Policy-Engine Policy Based Switching Register |
2803 | * ---------------------------------------------------- |
2804 | * This register retrieves and sets Policy Based Switching Table entries. |
2805 | */ |
2806 | #define MLXSW_REG_PPBS_ID 0x300C |
2807 | #define MLXSW_REG_PPBS_LEN 0x14 |
2808 | |
2809 | MLXSW_REG_DEFINE(ppbs, MLXSW_REG_PPBS_ID, MLXSW_REG_PPBS_LEN); |
2810 | |
2811 | /* reg_ppbs_pbs_ptr |
2812 | * Index into the PBS table. |
2813 | * For Spectrum, the index points to the KVD Linear. |
2814 | * Access: Index |
2815 | */ |
2816 | MLXSW_ITEM32(reg, ppbs, pbs_ptr, 0x08, 0, 24); |
2817 | |
2818 | /* reg_ppbs_system_port |
2819 | * Unique port identifier for the final destination of the packet. |
2820 | * Access: RW |
2821 | */ |
2822 | MLXSW_ITEM32(reg, ppbs, system_port, 0x10, 0, 16); |
2823 | |
2824 | static inline void mlxsw_reg_ppbs_pack(char *payload, u32 pbs_ptr, |
2825 | u16 system_port) |
2826 | { |
2827 | MLXSW_REG_ZERO(ppbs, payload); |
2828 | mlxsw_reg_ppbs_pbs_ptr_set(buf: payload, val: pbs_ptr); |
2829 | mlxsw_reg_ppbs_system_port_set(buf: payload, val: system_port); |
2830 | } |
2831 | |
2832 | /* PRCR - Policy-Engine Rules Copy Register |
2833 | * ---------------------------------------- |
2834 | * This register is used for accessing rules within a TCAM region. |
2835 | */ |
2836 | #define MLXSW_REG_PRCR_ID 0x300D |
2837 | #define MLXSW_REG_PRCR_LEN 0x40 |
2838 | |
2839 | MLXSW_REG_DEFINE(prcr, MLXSW_REG_PRCR_ID, MLXSW_REG_PRCR_LEN); |
2840 | |
2841 | enum mlxsw_reg_prcr_op { |
2842 | /* Move rules. Moves the rules from "tcam_region_info" starting |
2843 | * at offset "offset" to "dest_tcam_region_info" |
2844 | * at offset "dest_offset." |
2845 | */ |
2846 | MLXSW_REG_PRCR_OP_MOVE, |
2847 | /* Copy rules. Copies the rules from "tcam_region_info" starting |
2848 | * at offset "offset" to "dest_tcam_region_info" |
2849 | * at offset "dest_offset." |
2850 | */ |
2851 | MLXSW_REG_PRCR_OP_COPY, |
2852 | }; |
2853 | |
2854 | /* reg_prcr_op |
2855 | * Access: OP |
2856 | */ |
2857 | MLXSW_ITEM32(reg, prcr, op, 0x00, 28, 4); |
2858 | |
2859 | /* reg_prcr_offset |
2860 | * Offset within the source region to copy/move from. |
2861 | * Access: Index |
2862 | */ |
2863 | MLXSW_ITEM32(reg, prcr, offset, 0x00, 0, 16); |
2864 | |
2865 | /* reg_prcr_size |
2866 | * The number of rules to copy/move. |
2867 | * Access: WO |
2868 | */ |
2869 | MLXSW_ITEM32(reg, prcr, size, 0x04, 0, 16); |
2870 | |
2871 | /* reg_prcr_tcam_region_info |
2872 | * Opaque object that represents the source TCAM region. |
2873 | * Access: Index |
2874 | */ |
2875 | MLXSW_ITEM_BUF(reg, prcr, tcam_region_info, 0x10, |
2876 | MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN); |
2877 | |
2878 | /* reg_prcr_dest_offset |
2879 | * Offset within the source region to copy/move to. |
2880 | * Access: Index |
2881 | */ |
2882 | MLXSW_ITEM32(reg, prcr, dest_offset, 0x20, 0, 16); |
2883 | |
2884 | /* reg_prcr_dest_tcam_region_info |
2885 | * Opaque object that represents the destination TCAM region. |
2886 | * Access: Index |
2887 | */ |
2888 | MLXSW_ITEM_BUF(reg, prcr, dest_tcam_region_info, 0x30, |
2889 | MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN); |
2890 | |
2891 | static inline void mlxsw_reg_prcr_pack(char *payload, enum mlxsw_reg_prcr_op op, |
2892 | const char *src_tcam_region_info, |
2893 | u16 src_offset, |
2894 | const char *dest_tcam_region_info, |
2895 | u16 dest_offset, u16 size) |
2896 | { |
2897 | MLXSW_REG_ZERO(prcr, payload); |
2898 | mlxsw_reg_prcr_op_set(buf: payload, val: op); |
2899 | mlxsw_reg_prcr_offset_set(buf: payload, val: src_offset); |
2900 | mlxsw_reg_prcr_size_set(buf: payload, val: size); |
2901 | mlxsw_reg_prcr_tcam_region_info_memcpy_to(buf: payload, |
2902 | src: src_tcam_region_info); |
2903 | mlxsw_reg_prcr_dest_offset_set(buf: payload, val: dest_offset); |
2904 | mlxsw_reg_prcr_dest_tcam_region_info_memcpy_to(buf: payload, |
2905 | src: dest_tcam_region_info); |
2906 | } |
2907 | |
2908 | /* PEFA - Policy-Engine Extended Flexible Action Register |
2909 | * ------------------------------------------------------ |
2910 | * This register is used for accessing an extended flexible action entry |
2911 | * in the central KVD Linear Database. |
2912 | */ |
2913 | #define MLXSW_REG_PEFA_ID 0x300F |
2914 | #define MLXSW_REG_PEFA_LEN 0xB0 |
2915 | |
2916 | MLXSW_REG_DEFINE(pefa, MLXSW_REG_PEFA_ID, MLXSW_REG_PEFA_LEN); |
2917 | |
2918 | /* reg_pefa_index |
2919 | * Index in the KVD Linear Centralized Database. |
2920 | * Access: Index |
2921 | */ |
2922 | MLXSW_ITEM32(reg, pefa, index, 0x00, 0, 24); |
2923 | |
2924 | /* reg_pefa_a |
2925 | * Index in the KVD Linear Centralized Database. |
2926 | * Activity |
2927 | * For a new entry: set if ca=0, clear if ca=1 |
2928 | * Set if a packet lookup has hit on the specific entry |
2929 | * Access: RO |
2930 | */ |
2931 | MLXSW_ITEM32(reg, pefa, a, 0x04, 29, 1); |
2932 | |
2933 | /* reg_pefa_ca |
2934 | * Clear activity |
2935 | * When write: activity is according to this field |
2936 | * When read: after reading the activity is cleared according to ca |
2937 | * Access: OP |
2938 | */ |
2939 | MLXSW_ITEM32(reg, pefa, ca, 0x04, 24, 1); |
2940 | |
2941 | #define MLXSW_REG_FLEX_ACTION_SET_LEN 0xA8 |
2942 | |
2943 | /* reg_pefa_flex_action_set |
2944 | * Action-set to perform when rule is matched. |
2945 | * Must be zero padded if action set is shorter. |
2946 | * Access: RW |
2947 | */ |
2948 | MLXSW_ITEM_BUF(reg, pefa, flex_action_set, 0x08, MLXSW_REG_FLEX_ACTION_SET_LEN); |
2949 | |
2950 | static inline void mlxsw_reg_pefa_pack(char *payload, u32 index, bool ca, |
2951 | const char *flex_action_set) |
2952 | { |
2953 | MLXSW_REG_ZERO(pefa, payload); |
2954 | mlxsw_reg_pefa_index_set(buf: payload, val: index); |
2955 | mlxsw_reg_pefa_ca_set(buf: payload, val: ca); |
2956 | if (flex_action_set) |
2957 | mlxsw_reg_pefa_flex_action_set_memcpy_to(buf: payload, |
2958 | src: flex_action_set); |
2959 | } |
2960 | |
2961 | static inline void mlxsw_reg_pefa_unpack(char *payload, bool *p_a) |
2962 | { |
2963 | *p_a = mlxsw_reg_pefa_a_get(payload); |
2964 | } |
2965 | |
2966 | /* PEMRBT - Policy-Engine Multicast Router Binding Table Register |
2967 | * -------------------------------------------------------------- |
2968 | * This register is used for binding Multicast router to an ACL group |
2969 | * that serves the MC router. |
2970 | * This register is not supported by SwitchX/-2 and Spectrum. |
2971 | */ |
2972 | #define MLXSW_REG_PEMRBT_ID 0x3014 |
2973 | #define MLXSW_REG_PEMRBT_LEN 0x14 |
2974 | |
2975 | MLXSW_REG_DEFINE(pemrbt, MLXSW_REG_PEMRBT_ID, MLXSW_REG_PEMRBT_LEN); |
2976 | |
2977 | enum mlxsw_reg_pemrbt_protocol { |
2978 | MLXSW_REG_PEMRBT_PROTO_IPV4, |
2979 | MLXSW_REG_PEMRBT_PROTO_IPV6, |
2980 | }; |
2981 | |
2982 | /* reg_pemrbt_protocol |
2983 | * Access: Index |
2984 | */ |
2985 | MLXSW_ITEM32(reg, pemrbt, protocol, 0x00, 0, 1); |
2986 | |
2987 | /* reg_pemrbt_group_id |
2988 | * ACL group identifier. |
2989 | * Range 0..cap_max_acl_groups-1 |
2990 | * Access: RW |
2991 | */ |
2992 | MLXSW_ITEM32(reg, pemrbt, group_id, 0x10, 0, 16); |
2993 | |
2994 | static inline void |
2995 | mlxsw_reg_pemrbt_pack(char *payload, enum mlxsw_reg_pemrbt_protocol protocol, |
2996 | u16 group_id) |
2997 | { |
2998 | MLXSW_REG_ZERO(pemrbt, payload); |
2999 | mlxsw_reg_pemrbt_protocol_set(buf: payload, val: protocol); |
3000 | mlxsw_reg_pemrbt_group_id_set(buf: payload, val: group_id); |
3001 | } |
3002 | |
3003 | /* PTCE-V2 - Policy-Engine TCAM Entry Register Version 2 |
3004 | * ----------------------------------------------------- |
3005 | * This register is used for accessing rules within a TCAM region. |
3006 | * It is a new version of PTCE in order to support wider key, |
3007 | * mask and action within a TCAM region. This register is not supported |
3008 | * by SwitchX and SwitchX-2. |
3009 | */ |
3010 | #define MLXSW_REG_PTCE2_ID 0x3017 |
3011 | #define MLXSW_REG_PTCE2_LEN 0x1D8 |
3012 | |
3013 | MLXSW_REG_DEFINE(ptce2, MLXSW_REG_PTCE2_ID, MLXSW_REG_PTCE2_LEN); |
3014 | |
3015 | /* reg_ptce2_v |
3016 | * Valid. |
3017 | * Access: RW |
3018 | */ |
3019 | MLXSW_ITEM32(reg, ptce2, v, 0x00, 31, 1); |
3020 | |
3021 | /* reg_ptce2_a |
3022 | * Activity. Set if a packet lookup has hit on the specific entry. |
3023 | * To clear the "a" bit, use "clear activity" op or "clear on read" op. |
3024 | * Access: RO |
3025 | */ |
3026 | MLXSW_ITEM32(reg, ptce2, a, 0x00, 30, 1); |
3027 | |
3028 | enum mlxsw_reg_ptce2_op { |
3029 | /* Read operation. */ |
3030 | MLXSW_REG_PTCE2_OP_QUERY_READ = 0, |
3031 | /* clear on read operation. Used to read entry |
3032 | * and clear Activity bit. |
3033 | */ |
3034 | MLXSW_REG_PTCE2_OP_QUERY_CLEAR_ON_READ = 1, |
3035 | /* Write operation. Used to write a new entry to the table. |
3036 | * All R/W fields are relevant for new entry. Activity bit is set |
3037 | * for new entries - Note write with v = 0 will delete the entry. |
3038 | */ |
3039 | MLXSW_REG_PTCE2_OP_WRITE_WRITE = 0, |
3040 | /* Update action. Only action set will be updated. */ |
3041 | MLXSW_REG_PTCE2_OP_WRITE_UPDATE = 1, |
3042 | /* Clear activity. A bit is cleared for the entry. */ |
3043 | MLXSW_REG_PTCE2_OP_WRITE_CLEAR_ACTIVITY = 2, |
3044 | }; |
3045 | |
3046 | /* reg_ptce2_op |
3047 | * Access: OP |
3048 | */ |
3049 | MLXSW_ITEM32(reg, ptce2, op, 0x00, 20, 3); |
3050 | |
3051 | /* reg_ptce2_offset |
3052 | * Access: Index |
3053 | */ |
3054 | MLXSW_ITEM32(reg, ptce2, offset, 0x00, 0, 16); |
3055 | |
3056 | /* reg_ptce2_priority |
3057 | * Priority of the rule, higher values win. The range is 1..cap_kvd_size-1. |
3058 | * Note: priority does not have to be unique per rule. |
3059 | * Within a region, higher priority should have lower offset (no limitation |
3060 | * between regions in a multi-region). |
3061 | * Access: RW |
3062 | */ |
3063 | MLXSW_ITEM32(reg, ptce2, priority, 0x04, 0, 24); |
3064 | |
3065 | /* reg_ptce2_tcam_region_info |
3066 | * Opaque object that represents the TCAM region. |
3067 | * Access: Index |
3068 | */ |
3069 | MLXSW_ITEM_BUF(reg, ptce2, tcam_region_info, 0x10, |
3070 | MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN); |
3071 | |
3072 | #define MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN 96 |
3073 | |
3074 | /* reg_ptce2_flex_key_blocks |
3075 | * ACL Key. |
3076 | * Access: RW |
3077 | */ |
3078 | MLXSW_ITEM_BUF(reg, ptce2, flex_key_blocks, 0x20, |
3079 | MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN); |
3080 | |
3081 | /* reg_ptce2_mask |
3082 | * mask- in the same size as key. A bit that is set directs the TCAM |
3083 | * to compare the corresponding bit in key. A bit that is clear directs |
3084 | * the TCAM to ignore the corresponding bit in key. |
3085 | * Access: RW |
3086 | */ |
3087 | MLXSW_ITEM_BUF(reg, ptce2, mask, 0x80, |
3088 | MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN); |
3089 | |
3090 | /* reg_ptce2_flex_action_set |
3091 | * ACL action set. |
3092 | * Access: RW |
3093 | */ |
3094 | MLXSW_ITEM_BUF(reg, ptce2, flex_action_set, 0xE0, |
3095 | MLXSW_REG_FLEX_ACTION_SET_LEN); |
3096 | |
3097 | static inline void mlxsw_reg_ptce2_pack(char *payload, bool valid, |
3098 | enum mlxsw_reg_ptce2_op op, |
3099 | const char *tcam_region_info, |
3100 | u16 offset, u32 priority) |
3101 | { |
3102 | MLXSW_REG_ZERO(ptce2, payload); |
3103 | mlxsw_reg_ptce2_v_set(buf: payload, val: valid); |
3104 | mlxsw_reg_ptce2_op_set(buf: payload, val: op); |
3105 | mlxsw_reg_ptce2_offset_set(buf: payload, val: offset); |
3106 | mlxsw_reg_ptce2_priority_set(buf: payload, val: priority); |
3107 | mlxsw_reg_ptce2_tcam_region_info_memcpy_to(buf: payload, src: tcam_region_info); |
3108 | } |
3109 | |
3110 | /* PERPT - Policy-Engine ERP Table Register |
3111 | * ---------------------------------------- |
3112 | * This register adds and removes eRPs from the eRP table. |
3113 | */ |
3114 | #define MLXSW_REG_PERPT_ID 0x3021 |
3115 | #define MLXSW_REG_PERPT_LEN 0x80 |
3116 | |
3117 | MLXSW_REG_DEFINE(perpt, MLXSW_REG_PERPT_ID, MLXSW_REG_PERPT_LEN); |
3118 | |
3119 | /* reg_perpt_erpt_bank |
3120 | * eRP table bank. |
3121 | * Range 0 .. cap_max_erp_table_banks - 1 |
3122 | * Access: Index |
3123 | */ |
3124 | MLXSW_ITEM32(reg, perpt, erpt_bank, 0x00, 16, 4); |
3125 | |
3126 | /* reg_perpt_erpt_index |
3127 | * Index to eRP table within the eRP bank. |
3128 | * Range is 0 .. cap_max_erp_table_bank_size - 1 |
3129 | * Access: Index |
3130 | */ |
3131 | MLXSW_ITEM32(reg, perpt, erpt_index, 0x00, 0, 8); |
3132 | |
3133 | enum mlxsw_reg_perpt_key_size { |
3134 | MLXSW_REG_PERPT_KEY_SIZE_2KB, |
3135 | MLXSW_REG_PERPT_KEY_SIZE_4KB, |
3136 | MLXSW_REG_PERPT_KEY_SIZE_8KB, |
3137 | MLXSW_REG_PERPT_KEY_SIZE_12KB, |
3138 | }; |
3139 | |
3140 | /* reg_perpt_key_size |
3141 | * Access: OP |
3142 | */ |
3143 | MLXSW_ITEM32(reg, perpt, key_size, 0x04, 0, 4); |
3144 | |
3145 | /* reg_perpt_bf_bypass |
3146 | * 0 - The eRP is used only if bloom filter state is set for the given |
3147 | * rule. |
3148 | * 1 - The eRP is used regardless of bloom filter state. |
3149 | * The bypass is an OR condition of region_id or eRP. See PERCR.bf_bypass |
3150 | * Access: RW |
3151 | */ |
3152 | MLXSW_ITEM32(reg, perpt, bf_bypass, 0x08, 8, 1); |
3153 | |
3154 | /* reg_perpt_erp_id |
3155 | * eRP ID for use by the rules. |
3156 | * Access: RW |
3157 | */ |
3158 | MLXSW_ITEM32(reg, perpt, erp_id, 0x08, 0, 4); |
3159 | |
3160 | /* reg_perpt_erpt_base_bank |
3161 | * Base eRP table bank, points to head of erp_vector |
3162 | * Range is 0 .. cap_max_erp_table_banks - 1 |
3163 | * Access: OP |
3164 | */ |
3165 | MLXSW_ITEM32(reg, perpt, erpt_base_bank, 0x0C, 16, 4); |
3166 | |
3167 | /* reg_perpt_erpt_base_index |
3168 | * Base index to eRP table within the eRP bank |
3169 | * Range is 0 .. cap_max_erp_table_bank_size - 1 |
3170 | * Access: OP |
3171 | */ |
3172 | MLXSW_ITEM32(reg, perpt, erpt_base_index, 0x0C, 0, 8); |
3173 | |
3174 | /* reg_perpt_erp_index_in_vector |
3175 | * eRP index in the vector. |
3176 | * Access: OP |
3177 | */ |
3178 | MLXSW_ITEM32(reg, perpt, erp_index_in_vector, 0x10, 0, 4); |
3179 | |
3180 | /* reg_perpt_erp_vector |
3181 | * eRP vector. |
3182 | * Access: OP |
3183 | */ |
3184 | MLXSW_ITEM_BIT_ARRAY(reg, perpt, erp_vector, 0x14, 4, 1); |
3185 | |
3186 | /* reg_perpt_mask |
3187 | * Mask |
3188 | * 0 - A-TCAM will ignore the bit in key |
3189 | * 1 - A-TCAM will compare the bit in key |
3190 | * Access: RW |
3191 | */ |
3192 | MLXSW_ITEM_BUF(reg, perpt, mask, 0x20, MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN); |
3193 | |
3194 | static inline void mlxsw_reg_perpt_erp_vector_pack(char *payload, |
3195 | unsigned long *erp_vector, |
3196 | unsigned long size) |
3197 | { |
3198 | unsigned long bit; |
3199 | |
3200 | for_each_set_bit(bit, erp_vector, size) |
3201 | mlxsw_reg_perpt_erp_vector_set(payload, bit, true); |
3202 | } |
3203 | |
3204 | static inline void |
3205 | mlxsw_reg_perpt_pack(char *payload, u8 erpt_bank, u8 erpt_index, |
3206 | enum mlxsw_reg_perpt_key_size key_size, u8 erp_id, |
3207 | u8 erpt_base_bank, u8 erpt_base_index, u8 erp_index, |
3208 | char *mask) |
3209 | { |
3210 | MLXSW_REG_ZERO(perpt, payload); |
3211 | mlxsw_reg_perpt_erpt_bank_set(payload, erpt_bank); |
3212 | mlxsw_reg_perpt_erpt_index_set(payload, erpt_index); |
3213 | mlxsw_reg_perpt_key_size_set(buf: payload, val: key_size); |
3214 | mlxsw_reg_perpt_bf_bypass_set(buf: payload, val: false); |
3215 | mlxsw_reg_perpt_erp_id_set(payload, erp_id); |
3216 | mlxsw_reg_perpt_erpt_base_bank_set(payload, erpt_base_bank); |
3217 | mlxsw_reg_perpt_erpt_base_index_set(payload, erpt_base_index); |
3218 | mlxsw_reg_perpt_erp_index_in_vector_set(payload, erp_index); |
3219 | mlxsw_reg_perpt_mask_memcpy_to(buf: payload, src: mask); |
3220 | } |
3221 | |
3222 | /* PERAR - Policy-Engine Region Association Register |
3223 | * ------------------------------------------------- |
3224 | * This register associates a hw region for region_id's. Changing on the fly |
3225 | * is supported by the device. |
3226 | */ |
3227 | #define MLXSW_REG_PERAR_ID 0x3026 |
3228 | #define MLXSW_REG_PERAR_LEN 0x08 |
3229 | |
3230 | MLXSW_REG_DEFINE(perar, MLXSW_REG_PERAR_ID, MLXSW_REG_PERAR_LEN); |
3231 | |
3232 | /* reg_perar_region_id |
3233 | * Region identifier |
3234 | * Range 0 .. cap_max_regions-1 |
3235 | * Access: Index |
3236 | */ |
3237 | MLXSW_ITEM32(reg, perar, region_id, 0x00, 0, 16); |
3238 | |
3239 | static inline unsigned int |
3240 | mlxsw_reg_perar_hw_regions_needed(unsigned int block_num) |
3241 | { |
3242 | return DIV_ROUND_UP(block_num, 4); |
3243 | } |
3244 | |
3245 | /* reg_perar_hw_region |
3246 | * HW Region |
3247 | * Range 0 .. cap_max_regions-1 |
3248 | * Default: hw_region = region_id |
3249 | * For a 8 key block region, 2 consecutive regions are used |
3250 | * For a 12 key block region, 3 consecutive regions are used |
3251 | * Access: RW |
3252 | */ |
3253 | MLXSW_ITEM32(reg, perar, hw_region, 0x04, 0, 16); |
3254 | |
3255 | static inline void mlxsw_reg_perar_pack(char *payload, u16 region_id, |
3256 | u16 hw_region) |
3257 | { |
3258 | MLXSW_REG_ZERO(perar, payload); |
3259 | mlxsw_reg_perar_region_id_set(buf: payload, val: region_id); |
3260 | mlxsw_reg_perar_hw_region_set(buf: payload, val: hw_region); |
3261 | } |
3262 | |
3263 | /* PTCE-V3 - Policy-Engine TCAM Entry Register Version 3 |
3264 | * ----------------------------------------------------- |
3265 | * This register is a new version of PTCE-V2 in order to support the |
3266 | * A-TCAM. This register is not supported by SwitchX/-2 and Spectrum. |
3267 | */ |
3268 | #define MLXSW_REG_PTCE3_ID 0x3027 |
3269 | #define MLXSW_REG_PTCE3_LEN 0xF0 |
3270 | |
3271 | MLXSW_REG_DEFINE(ptce3, MLXSW_REG_PTCE3_ID, MLXSW_REG_PTCE3_LEN); |
3272 | |
3273 | /* reg_ptce3_v |
3274 | * Valid. |
3275 | * Access: RW |
3276 | */ |
3277 | MLXSW_ITEM32(reg, ptce3, v, 0x00, 31, 1); |
3278 | |
3279 | enum mlxsw_reg_ptce3_op { |
3280 | /* Write operation. Used to write a new entry to the table. |
3281 | * All R/W fields are relevant for new entry. Activity bit is set |
3282 | * for new entries. Write with v = 0 will delete the entry. Must |
3283 | * not be used if an entry exists. |
3284 | */ |
3285 | MLXSW_REG_PTCE3_OP_WRITE_WRITE = 0, |
3286 | /* Update operation */ |
3287 | MLXSW_REG_PTCE3_OP_WRITE_UPDATE = 1, |
3288 | /* Read operation */ |
3289 | MLXSW_REG_PTCE3_OP_QUERY_READ = 0, |
3290 | }; |
3291 | |
3292 | /* reg_ptce3_op |
3293 | * Access: OP |
3294 | */ |
3295 | MLXSW_ITEM32(reg, ptce3, op, 0x00, 20, 3); |
3296 | |
3297 | /* reg_ptce3_priority |
3298 | * Priority of the rule. Higher values win. |
3299 | * For Spectrum-2 range is 1..cap_kvd_size - 1 |
3300 | * Note: Priority does not have to be unique per rule. |
3301 | * Access: RW |
3302 | */ |
3303 | MLXSW_ITEM32(reg, ptce3, priority, 0x04, 0, 24); |
3304 | |
3305 | /* reg_ptce3_tcam_region_info |
3306 | * Opaque object that represents the TCAM region. |
3307 | * Access: Index |
3308 | */ |
3309 | MLXSW_ITEM_BUF(reg, ptce3, tcam_region_info, 0x10, |
3310 | MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN); |
3311 | |
3312 | /* reg_ptce3_flex2_key_blocks |
3313 | * ACL key. The key must be masked according to eRP (if exists) or |
3314 | * according to master mask. |
3315 | * Access: Index |
3316 | */ |
3317 | MLXSW_ITEM_BUF(reg, ptce3, flex2_key_blocks, 0x20, |
3318 | MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN); |
3319 | |
3320 | /* reg_ptce3_erp_id |
3321 | * eRP ID. |
3322 | * Access: Index |
3323 | */ |
3324 | MLXSW_ITEM32(reg, ptce3, erp_id, 0x80, 0, 4); |
3325 | |
3326 | /* reg_ptce3_delta_start |
3327 | * Start point of delta_value and delta_mask, in bits. Must not exceed |
3328 | * num_key_blocks * 36 - 8. Reserved when delta_mask = 0. |
3329 | * Access: Index |
3330 | */ |
3331 | MLXSW_ITEM32(reg, ptce3, delta_start, 0x84, 0, 10); |
3332 | |
3333 | /* reg_ptce3_delta_mask |
3334 | * Delta mask. |
3335 | * 0 - Ignore relevant bit in delta_value |
3336 | * 1 - Compare relevant bit in delta_value |
3337 | * Delta mask must not be set for reserved fields in the key blocks. |
3338 | * Note: No delta when no eRPs. Thus, for regions with |
3339 | * PERERP.erpt_pointer_valid = 0 the delta mask must be 0. |
3340 | * Access: Index |
3341 | */ |
3342 | MLXSW_ITEM32(reg, ptce3, delta_mask, 0x88, 16, 8); |
3343 | |
3344 | /* reg_ptce3_delta_value |
3345 | * Delta value. |
3346 | * Bits which are masked by delta_mask must be 0. |
3347 | * Access: Index |
3348 | */ |
3349 | MLXSW_ITEM32(reg, ptce3, delta_value, 0x88, 0, 8); |
3350 | |
3351 | /* reg_ptce3_prune_vector |
3352 | * Pruning vector relative to the PERPT.erp_id. |
3353 | * Used for reducing lookups. |
3354 | * 0 - NEED: Do a lookup using the eRP. |
3355 | * 1 - PRUNE: Do not perform a lookup using the eRP. |
3356 | * Maybe be modified by PEAPBL and PEAPBM. |
3357 | * Note: In Spectrum-2, a region of 8 key blocks must be set to either |
3358 | * all 1's or all 0's. |
3359 | * Access: RW |
3360 | */ |
3361 | MLXSW_ITEM_BIT_ARRAY(reg, ptce3, prune_vector, 0x90, 4, 1); |
3362 | |
3363 | /* reg_ptce3_prune_ctcam |
3364 | * Pruning on C-TCAM. Used for reducing lookups. |
3365 | * 0 - NEED: Do a lookup in the C-TCAM. |
3366 | * 1 - PRUNE: Do not perform a lookup in the C-TCAM. |
3367 | * Access: RW |
3368 | */ |
3369 | MLXSW_ITEM32(reg, ptce3, prune_ctcam, 0x94, 31, 1); |
3370 | |
3371 | /* reg_ptce3_large_exists |
3372 | * Large entry key ID exists. |
3373 | * Within the region: |
3374 | * 0 - SINGLE: The large_entry_key_id is not currently in use. |
3375 | * For rule insert: The MSB of the key (blocks 6..11) will be added. |
3376 | * For rule delete: The MSB of the key will be removed. |
3377 | * 1 - NON_SINGLE: The large_entry_key_id is currently in use. |
3378 | * For rule insert: The MSB of the key (blocks 6..11) will not be added. |
3379 | * For rule delete: The MSB of the key will not be removed. |
3380 | * Access: WO |
3381 | */ |
3382 | MLXSW_ITEM32(reg, ptce3, large_exists, 0x98, 31, 1); |
3383 | |
3384 | /* reg_ptce3_large_entry_key_id |
3385 | * Large entry key ID. |
3386 | * A key for 12 key blocks rules. Reserved when region has less than 12 key |
3387 | * blocks. Must be different for different keys which have the same common |
3388 | * 6 key blocks (MSB, blocks 6..11) key within a region. |
3389 | * Range is 0..cap_max_pe_large_key_id - 1 |
3390 | * Access: RW |
3391 | */ |
3392 | MLXSW_ITEM32(reg, ptce3, large_entry_key_id, 0x98, 0, 24); |
3393 | |
3394 | /* reg_ptce3_action_pointer |
3395 | * Pointer to action. |
3396 | * Range is 0..cap_max_kvd_action_sets - 1 |
3397 | * Access: RW |
3398 | */ |
3399 | MLXSW_ITEM32(reg, ptce3, action_pointer, 0xA0, 0, 24); |
3400 | |
3401 | static inline void mlxsw_reg_ptce3_pack(char *payload, bool valid, |
3402 | enum mlxsw_reg_ptce3_op op, |
3403 | u32 priority, |
3404 | const char *tcam_region_info, |
3405 | const char *key, u8 erp_id, |
3406 | u16 delta_start, u8 delta_mask, |
3407 | u8 delta_value, bool large_exists, |
3408 | u32 lkey_id, u32 action_pointer) |
3409 | { |
3410 | MLXSW_REG_ZERO(ptce3, payload); |
3411 | mlxsw_reg_ptce3_v_set(buf: payload, val: valid); |
3412 | mlxsw_reg_ptce3_op_set(buf: payload, val: op); |
3413 | mlxsw_reg_ptce3_priority_set(buf: payload, val: priority); |
3414 | mlxsw_reg_ptce3_tcam_region_info_memcpy_to(buf: payload, src: tcam_region_info); |
3415 | mlxsw_reg_ptce3_flex2_key_blocks_memcpy_to(buf: payload, src: key); |
3416 | mlxsw_reg_ptce3_erp_id_set(payload, erp_id); |
3417 | mlxsw_reg_ptce3_delta_start_set(buf: payload, val: delta_start); |
3418 | mlxsw_reg_ptce3_delta_mask_set(payload, delta_mask); |
3419 | mlxsw_reg_ptce3_delta_value_set(payload, delta_value); |
3420 | mlxsw_reg_ptce3_large_exists_set(buf: payload, val: large_exists); |
3421 | mlxsw_reg_ptce3_large_entry_key_id_set(buf: payload, val: lkey_id); |
3422 | mlxsw_reg_ptce3_action_pointer_set(buf: payload, val: action_pointer); |
3423 | } |
3424 | |
3425 | /* PERCR - Policy-Engine Region Configuration Register |
3426 | * --------------------------------------------------- |
3427 | * This register configures the region parameters. The region_id must be |
3428 | * allocated. |
3429 | */ |
3430 | #define MLXSW_REG_PERCR_ID 0x302A |
3431 | #define MLXSW_REG_PERCR_LEN 0x80 |
3432 | |
3433 | MLXSW_REG_DEFINE(percr, MLXSW_REG_PERCR_ID, MLXSW_REG_PERCR_LEN); |
3434 | |
3435 | /* reg_percr_region_id |
3436 | * Region identifier. |
3437 | * Range 0..cap_max_regions-1 |
3438 | * Access: Index |
3439 | */ |
3440 | MLXSW_ITEM32(reg, percr, region_id, 0x00, 0, 16); |
3441 | |
3442 | /* reg_percr_atcam_ignore_prune |
3443 | * Ignore prune_vector by other A-TCAM rules. Used e.g., for a new rule. |
3444 | * Access: RW |
3445 | */ |
3446 | MLXSW_ITEM32(reg, percr, atcam_ignore_prune, 0x04, 25, 1); |
3447 | |
3448 | /* reg_percr_ctcam_ignore_prune |
3449 | * Ignore prune_ctcam by other A-TCAM rules. Used e.g., for a new rule. |
3450 | * Access: RW |
3451 | */ |
3452 | MLXSW_ITEM32(reg, percr, ctcam_ignore_prune, 0x04, 24, 1); |
3453 | |
3454 | /* reg_percr_bf_bypass |
3455 | * Bloom filter bypass. |
3456 | * 0 - Bloom filter is used (default) |
3457 | * 1 - Bloom filter is bypassed. The bypass is an OR condition of |
3458 | * region_id or eRP. See PERPT.bf_bypass |
3459 | * Access: RW |
3460 | */ |
3461 | MLXSW_ITEM32(reg, percr, bf_bypass, 0x04, 16, 1); |
3462 | |
3463 | /* reg_percr_master_mask |
3464 | * Master mask. Logical OR mask of all masks of all rules of a region |
3465 | * (both A-TCAM and C-TCAM). When there are no eRPs |
3466 | * (erpt_pointer_valid = 0), then this provides the mask. |
3467 | * Access: RW |
3468 | */ |
3469 | MLXSW_ITEM_BUF(reg, percr, master_mask, 0x20, 96); |
3470 | |
3471 | static inline void mlxsw_reg_percr_pack(char *payload, u16 region_id) |
3472 | { |
3473 | MLXSW_REG_ZERO(percr, payload); |
3474 | mlxsw_reg_percr_region_id_set(buf: payload, val: region_id); |
3475 | mlxsw_reg_percr_atcam_ignore_prune_set(buf: payload, val: false); |
3476 | mlxsw_reg_percr_ctcam_ignore_prune_set(buf: payload, val: false); |
3477 | mlxsw_reg_percr_bf_bypass_set(buf: payload, val: false); |
3478 | } |
3479 | |
3480 | /* PERERP - Policy-Engine Region eRP Register |
3481 | * ------------------------------------------ |
3482 | * This register configures the region eRP. The region_id must be |
3483 | * allocated. |
3484 | */ |
3485 | #define MLXSW_REG_PERERP_ID 0x302B |
3486 | #define MLXSW_REG_PERERP_LEN 0x1C |
3487 | |
3488 | MLXSW_REG_DEFINE(pererp, MLXSW_REG_PERERP_ID, MLXSW_REG_PERERP_LEN); |
3489 | |
3490 | /* reg_pererp_region_id |
3491 | * Region identifier. |
3492 | * Range 0..cap_max_regions-1 |
3493 | * Access: Index |
3494 | */ |
3495 | MLXSW_ITEM32(reg, pererp, region_id, 0x00, 0, 16); |
3496 | |
3497 | /* reg_pererp_ctcam_le |
3498 | * C-TCAM lookup enable. Reserved when erpt_pointer_valid = 0. |
3499 | * Access: RW |
3500 | */ |
3501 | MLXSW_ITEM32(reg, pererp, ctcam_le, 0x04, 28, 1); |
3502 | |
3503 | /* reg_pererp_erpt_pointer_valid |
3504 | * erpt_pointer is valid. |
3505 | * Access: RW |
3506 | */ |
3507 | MLXSW_ITEM32(reg, pererp, erpt_pointer_valid, 0x10, 31, 1); |
3508 | |
3509 | /* reg_pererp_erpt_bank_pointer |
3510 | * Pointer to eRP table bank. May be modified at any time. |
3511 | * Range 0..cap_max_erp_table_banks-1 |
3512 | * Reserved when erpt_pointer_valid = 0 |
3513 | */ |
3514 | MLXSW_ITEM32(reg, pererp, erpt_bank_pointer, 0x10, 16, 4); |
3515 | |
3516 | /* reg_pererp_erpt_pointer |
3517 | * Pointer to eRP table within the eRP bank. Can be changed for an |
3518 | * existing region. |
3519 | * Range 0..cap_max_erp_table_size-1 |
3520 | * Reserved when erpt_pointer_valid = 0 |
3521 | * Access: RW |
3522 | */ |
3523 | MLXSW_ITEM32(reg, pererp, erpt_pointer, 0x10, 0, 8); |
3524 | |
3525 | /* reg_pererp_erpt_vector |
3526 | * Vector of allowed eRP indexes starting from erpt_pointer within the |
3527 | * erpt_bank_pointer. Next entries will be in next bank. |
3528 | * Note that eRP index is used and not eRP ID. |
3529 | * Reserved when erpt_pointer_valid = 0 |
3530 | * Access: RW |
3531 | */ |
3532 | MLXSW_ITEM_BIT_ARRAY(reg, pererp, erpt_vector, 0x14, 4, 1); |
3533 | |
3534 | /* reg_pererp_master_rp_id |
3535 | * Master RP ID. When there are no eRPs, then this provides the eRP ID |
3536 | * for the lookup. Can be changed for an existing region. |
3537 | * Reserved when erpt_pointer_valid = 1 |
3538 | * Access: RW |
3539 | */ |
3540 | MLXSW_ITEM32(reg, pererp, master_rp_id, 0x18, 0, 4); |
3541 | |
3542 | static inline void mlxsw_reg_pererp_erp_vector_pack(char *payload, |
3543 | unsigned long *erp_vector, |
3544 | unsigned long size) |
3545 | { |
3546 | unsigned long bit; |
3547 | |
3548 | for_each_set_bit(bit, erp_vector, size) |
3549 | mlxsw_reg_pererp_erpt_vector_set(payload, bit, true); |
3550 | } |
3551 | |
3552 | static inline void mlxsw_reg_pererp_pack(char *payload, u16 region_id, |
3553 | bool ctcam_le, bool erpt_pointer_valid, |
3554 | u8 erpt_bank_pointer, u8 erpt_pointer, |
3555 | u8 master_rp_id) |
3556 | { |
3557 | MLXSW_REG_ZERO(pererp, payload); |
3558 | mlxsw_reg_pererp_region_id_set(buf: payload, val: region_id); |
3559 | mlxsw_reg_pererp_ctcam_le_set(buf: payload, val: ctcam_le); |
3560 | mlxsw_reg_pererp_erpt_pointer_valid_set(buf: payload, val: erpt_pointer_valid); |
3561 | mlxsw_reg_pererp_erpt_bank_pointer_set(payload, erpt_bank_pointer); |
3562 | mlxsw_reg_pererp_erpt_pointer_set(payload, erpt_pointer); |
3563 | mlxsw_reg_pererp_master_rp_id_set(payload, master_rp_id); |
3564 | } |
3565 | |
3566 | /* PEABFE - Policy-Engine Algorithmic Bloom Filter Entries Register |
3567 | * ---------------------------------------------------------------- |
3568 | * This register configures the Bloom filter entries. |
3569 | */ |
3570 | #define MLXSW_REG_PEABFE_ID 0x3022 |
3571 | #define MLXSW_REG_PEABFE_BASE_LEN 0x10 |
3572 | #define MLXSW_REG_PEABFE_BF_REC_LEN 0x4 |
3573 | #define MLXSW_REG_PEABFE_BF_REC_MAX_COUNT 256 |
3574 | #define MLXSW_REG_PEABFE_LEN (MLXSW_REG_PEABFE_BASE_LEN + \ |
3575 | MLXSW_REG_PEABFE_BF_REC_LEN * \ |
3576 | MLXSW_REG_PEABFE_BF_REC_MAX_COUNT) |
3577 | |
3578 | MLXSW_REG_DEFINE(peabfe, MLXSW_REG_PEABFE_ID, MLXSW_REG_PEABFE_LEN); |
3579 | |
3580 | /* reg_peabfe_size |
3581 | * Number of BF entries to be updated. |
3582 | * Range 1..256 |
3583 | * Access: Op |
3584 | */ |
3585 | MLXSW_ITEM32(reg, peabfe, size, 0x00, 0, 9); |
3586 | |
3587 | /* reg_peabfe_bf_entry_state |
3588 | * Bloom filter state |
3589 | * 0 - Clear |
3590 | * 1 - Set |
3591 | * Access: RW |
3592 | */ |
3593 | MLXSW_ITEM32_INDEXED(reg, peabfe, bf_entry_state, |
3594 | MLXSW_REG_PEABFE_BASE_LEN, 31, 1, |
3595 | MLXSW_REG_PEABFE_BF_REC_LEN, 0x00, false); |
3596 | |
3597 | /* reg_peabfe_bf_entry_bank |
3598 | * Bloom filter bank ID |
3599 | * Range 0..cap_max_erp_table_banks-1 |
3600 | * Access: Index |
3601 | */ |
3602 | MLXSW_ITEM32_INDEXED(reg, peabfe, bf_entry_bank, |
3603 | MLXSW_REG_PEABFE_BASE_LEN, 24, 4, |
3604 | MLXSW_REG_PEABFE_BF_REC_LEN, 0x00, false); |
3605 | |
3606 | /* reg_peabfe_bf_entry_index |
3607 | * Bloom filter entry index |
3608 | * Range 0..2^cap_max_bf_log-1 |
3609 | * Access: Index |
3610 | */ |
3611 | MLXSW_ITEM32_INDEXED(reg, peabfe, bf_entry_index, |
3612 | MLXSW_REG_PEABFE_BASE_LEN, 0, 24, |
3613 | MLXSW_REG_PEABFE_BF_REC_LEN, 0x00, false); |
3614 | |
3615 | static inline void mlxsw_reg_peabfe_pack(char *payload) |
3616 | { |
3617 | MLXSW_REG_ZERO(peabfe, payload); |
3618 | } |
3619 | |
3620 | static inline void mlxsw_reg_peabfe_rec_pack(char *payload, int rec_index, |
3621 | u8 state, u8 bank, u32 bf_index) |
3622 | { |
3623 | u8 num_rec = mlxsw_reg_peabfe_size_get(payload); |
3624 | |
3625 | if (rec_index >= num_rec) |
3626 | mlxsw_reg_peabfe_size_set(buf: payload, val: rec_index + 1); |
3627 | mlxsw_reg_peabfe_bf_entry_state_set(payload, rec_index, state); |
3628 | mlxsw_reg_peabfe_bf_entry_bank_set(payload, rec_index, bank); |
3629 | mlxsw_reg_peabfe_bf_entry_index_set(buf: payload, index: rec_index, val: bf_index); |
3630 | } |
3631 | |
3632 | /* IEDR - Infrastructure Entry Delete Register |
3633 | * ---------------------------------------------------- |
3634 | * This register is used for deleting entries from the entry tables. |
3635 | * It is legitimate to attempt to delete a nonexisting entry (the device will |
3636 | * respond as a good flow). |
3637 | */ |
3638 | #define MLXSW_REG_IEDR_ID 0x3804 |
3639 | #define MLXSW_REG_IEDR_BASE_LEN 0x10 /* base length, without records */ |
3640 | #define MLXSW_REG_IEDR_REC_LEN 0x8 /* record length */ |
3641 | #define MLXSW_REG_IEDR_REC_MAX_COUNT 64 |
3642 | #define MLXSW_REG_IEDR_LEN (MLXSW_REG_IEDR_BASE_LEN + \ |
3643 | MLXSW_REG_IEDR_REC_LEN * \ |
3644 | MLXSW_REG_IEDR_REC_MAX_COUNT) |
3645 | |
3646 | MLXSW_REG_DEFINE(iedr, MLXSW_REG_IEDR_ID, MLXSW_REG_IEDR_LEN); |
3647 | |
3648 | /* reg_iedr_num_rec |
3649 | * Number of records. |
3650 | * Access: OP |
3651 | */ |
3652 | MLXSW_ITEM32(reg, iedr, num_rec, 0x00, 0, 8); |
3653 | |
3654 | /* reg_iedr_rec_type |
3655 | * Resource type. |
3656 | * Access: OP |
3657 | */ |
3658 | MLXSW_ITEM32_INDEXED(reg, iedr, rec_type, MLXSW_REG_IEDR_BASE_LEN, 24, 8, |
3659 | MLXSW_REG_IEDR_REC_LEN, 0x00, false); |
3660 | |
3661 | /* reg_iedr_rec_size |
3662 | * Size of entries do be deleted. The unit is 1 entry, regardless of entry type. |
3663 | * Access: OP |
3664 | */ |
3665 | MLXSW_ITEM32_INDEXED(reg, iedr, rec_size, MLXSW_REG_IEDR_BASE_LEN, 0, 13, |
3666 | MLXSW_REG_IEDR_REC_LEN, 0x00, false); |
3667 | |
3668 | /* reg_iedr_rec_index_start |
3669 | * Resource index start. |
3670 | * Access: OP |
3671 | */ |
3672 | MLXSW_ITEM32_INDEXED(reg, iedr, rec_index_start, MLXSW_REG_IEDR_BASE_LEN, 0, 24, |
3673 | MLXSW_REG_IEDR_REC_LEN, 0x04, false); |
3674 | |
3675 | static inline void mlxsw_reg_iedr_pack(char *payload) |
3676 | { |
3677 | MLXSW_REG_ZERO(iedr, payload); |
3678 | } |
3679 | |
3680 | static inline void mlxsw_reg_iedr_rec_pack(char *payload, int rec_index, |
3681 | u8 rec_type, u16 rec_size, |
3682 | u32 rec_index_start) |
3683 | { |
3684 | u8 num_rec = mlxsw_reg_iedr_num_rec_get(payload); |
3685 | |
3686 | if (rec_index >= num_rec) |
3687 | mlxsw_reg_iedr_num_rec_set(buf: payload, val: rec_index + 1); |
3688 | mlxsw_reg_iedr_rec_type_set(payload, rec_index, rec_type); |
3689 | mlxsw_reg_iedr_rec_size_set(buf: payload, index: rec_index, val: rec_size); |
3690 | mlxsw_reg_iedr_rec_index_start_set(buf: payload, index: rec_index, val: rec_index_start); |
3691 | } |
3692 | |
3693 | /* QPTS - QoS Priority Trust State Register |
3694 | * ---------------------------------------- |
3695 | * This register controls the port policy to calculate the switch priority and |
3696 | * packet color based on incoming packet fields. |
3697 | */ |
3698 | #define MLXSW_REG_QPTS_ID 0x4002 |
3699 | #define MLXSW_REG_QPTS_LEN 0x8 |
3700 | |
3701 | MLXSW_REG_DEFINE(qpts, MLXSW_REG_QPTS_ID, MLXSW_REG_QPTS_LEN); |
3702 | |
3703 | /* reg_qpts_local_port |
3704 | * Local port number. |
3705 | * Access: Index |
3706 | * |
3707 | * Note: CPU port is supported. |
3708 | */ |
3709 | MLXSW_ITEM32_LP(reg, qpts, 0x00, 16, 0x00, 12); |
3710 | |
3711 | enum mlxsw_reg_qpts_trust_state { |
3712 | MLXSW_REG_QPTS_TRUST_STATE_PCP = 1, |
3713 | MLXSW_REG_QPTS_TRUST_STATE_DSCP = 2, /* For MPLS, trust EXP. */ |
3714 | }; |
3715 | |
3716 | /* reg_qpts_trust_state |
3717 | * Trust state for a given port. |
3718 | * Access: RW |
3719 | */ |
3720 | MLXSW_ITEM32(reg, qpts, trust_state, 0x04, 0, 3); |
3721 | |
3722 | static inline void mlxsw_reg_qpts_pack(char *payload, u16 local_port, |
3723 | enum mlxsw_reg_qpts_trust_state ts) |
3724 | { |
3725 | MLXSW_REG_ZERO(qpts, payload); |
3726 | |
3727 | mlxsw_reg_qpts_local_port_set(buf: payload, val: local_port); |
3728 | mlxsw_reg_qpts_trust_state_set(buf: payload, val: ts); |
3729 | } |
3730 | |
3731 | /* QPCR - QoS Policer Configuration Register |
3732 | * ----------------------------------------- |
3733 | * The QPCR register is used to create policers - that limit |
3734 | * the rate of bytes or packets via some trap group. |
3735 | */ |
3736 | #define MLXSW_REG_QPCR_ID 0x4004 |
3737 | #define MLXSW_REG_QPCR_LEN 0x28 |
3738 | |
3739 | MLXSW_REG_DEFINE(qpcr, MLXSW_REG_QPCR_ID, MLXSW_REG_QPCR_LEN); |
3740 | |
3741 | enum mlxsw_reg_qpcr_g { |
3742 | MLXSW_REG_QPCR_G_GLOBAL = 2, |
3743 | MLXSW_REG_QPCR_G_STORM_CONTROL = 3, |
3744 | }; |
3745 | |
3746 | /* reg_qpcr_g |
3747 | * The policer type. |
3748 | * Access: Index |
3749 | */ |
3750 | MLXSW_ITEM32(reg, qpcr, g, 0x00, 14, 2); |
3751 | |
3752 | /* reg_qpcr_pid |
3753 | * Policer ID. |
3754 | * Access: Index |
3755 | */ |
3756 | MLXSW_ITEM32(reg, qpcr, pid, 0x00, 0, 14); |
3757 | |
3758 | /* reg_qpcr_clear_counter |
3759 | * Clear counters. |
3760 | * Access: OP |
3761 | */ |
3762 | MLXSW_ITEM32(reg, qpcr, clear_counter, 0x04, 31, 1); |
3763 | |
3764 | /* reg_qpcr_color_aware |
3765 | * Is the policer aware of colors. |
3766 | * Must be 0 (unaware) for cpu port. |
3767 | * Access: RW for unbounded policer. RO for bounded policer. |
3768 | */ |
3769 | MLXSW_ITEM32(reg, qpcr, color_aware, 0x04, 15, 1); |
3770 | |
3771 | /* reg_qpcr_bytes |
3772 | * Is policer limit is for bytes per sec or packets per sec. |
3773 | * 0 - packets |
3774 | * 1 - bytes |
3775 | * Access: RW for unbounded policer. RO for bounded policer. |
3776 | */ |
3777 | MLXSW_ITEM32(reg, qpcr, bytes, 0x04, 14, 1); |
3778 | |
3779 | enum mlxsw_reg_qpcr_ir_units { |
3780 | MLXSW_REG_QPCR_IR_UNITS_M, |
3781 | MLXSW_REG_QPCR_IR_UNITS_K, |
3782 | }; |
3783 | |
3784 | /* reg_qpcr_ir_units |
3785 | * Policer's units for cir and eir fields (for bytes limits only) |
3786 | * 1 - 10^3 |
3787 | * 0 - 10^6 |
3788 | * Access: OP |
3789 | */ |
3790 | MLXSW_ITEM32(reg, qpcr, ir_units, 0x04, 12, 1); |
3791 | |
3792 | enum mlxsw_reg_qpcr_rate_type { |
3793 | MLXSW_REG_QPCR_RATE_TYPE_SINGLE = 1, |
3794 | MLXSW_REG_QPCR_RATE_TYPE_DOUBLE = 2, |
3795 | }; |
3796 | |
3797 | /* reg_qpcr_rate_type |
3798 | * Policer can have one limit (single rate) or 2 limits with specific operation |
3799 | * for packets that exceed the lower rate but not the upper one. |
3800 | * (For cpu port must be single rate) |
3801 | * Access: RW for unbounded policer. RO for bounded policer. |
3802 | */ |
3803 | MLXSW_ITEM32(reg, qpcr, rate_type, 0x04, 8, 2); |
3804 | |
3805 | /* reg_qpc_cbs |
3806 | * Policer's committed burst size. |
3807 | * The policer is working with time slices of 50 nano sec. By default every |
3808 | * slice is granted the proportionate share of the committed rate. If we want to |
3809 | * allow a slice to exceed that share (while still keeping the rate per sec) we |
3810 | * can allow burst. The burst size is between the default proportionate share |
3811 | * (and no lower than 8) to 32Gb. (Even though giving a number higher than the |
3812 | * committed rate will result in exceeding the rate). The burst size must be a |
3813 | * log of 2 and will be determined by 2^cbs. |
3814 | * Access: RW |
3815 | */ |
3816 | MLXSW_ITEM32(reg, qpcr, cbs, 0x08, 24, 6); |
3817 | |
3818 | /* reg_qpcr_cir |
3819 | * Policer's committed rate. |
3820 | * The rate used for sungle rate, the lower rate for double rate. |
3821 | * For bytes limits, the rate will be this value * the unit from ir_units. |
3822 | * (Resolution error is up to 1%). |
3823 | * Access: RW |
3824 | */ |
3825 | MLXSW_ITEM32(reg, qpcr, cir, 0x0C, 0, 32); |
3826 | |
3827 | /* reg_qpcr_eir |
3828 | * Policer's exceed rate. |
3829 | * The higher rate for double rate, reserved for single rate. |
3830 | * Lower rate for double rate policer. |
3831 | * For bytes limits, the rate will be this value * the unit from ir_units. |
3832 | * (Resolution error is up to 1%). |
3833 | * Access: RW |
3834 | */ |
3835 | MLXSW_ITEM32(reg, qpcr, eir, 0x10, 0, 32); |
3836 | |
3837 | #define MLXSW_REG_QPCR_DOUBLE_RATE_ACTION 2 |
3838 | |
3839 | /* reg_qpcr_exceed_action. |
3840 | * What to do with packets between the 2 limits for double rate. |
3841 | * Access: RW for unbounded policer. RO for bounded policer. |
3842 | */ |
3843 | MLXSW_ITEM32(reg, qpcr, exceed_action, 0x14, 0, 4); |
3844 | |
3845 | enum mlxsw_reg_qpcr_action { |
3846 | /* Discard */ |
3847 | MLXSW_REG_QPCR_ACTION_DISCARD = 1, |
3848 | /* Forward and set color to red. |
3849 | * If the packet is intended to cpu port, it will be dropped. |
3850 | */ |
3851 | MLXSW_REG_QPCR_ACTION_FORWARD = 2, |
3852 | }; |
3853 | |
3854 | /* reg_qpcr_violate_action |
3855 | * What to do with packets that cross the cir limit (for single rate) or the eir |
3856 | * limit (for double rate). |
3857 | * Access: RW for unbounded policer. RO for bounded policer. |
3858 | */ |
3859 | MLXSW_ITEM32(reg, qpcr, violate_action, 0x18, 0, 4); |
3860 | |
3861 | /* reg_qpcr_violate_count |
3862 | * Counts the number of times violate_action happened on this PID. |
3863 | * Access: RW |
3864 | */ |
3865 | MLXSW_ITEM64(reg, qpcr, violate_count, 0x20, 0, 64); |
3866 | |
3867 | /* Packets */ |
3868 | #define MLXSW_REG_QPCR_LOWEST_CIR 1 |
3869 | #define MLXSW_REG_QPCR_HIGHEST_CIR (2 * 1000 * 1000 * 1000) /* 2Gpps */ |
3870 | #define MLXSW_REG_QPCR_LOWEST_CBS 4 |
3871 | #define MLXSW_REG_QPCR_HIGHEST_CBS 24 |
3872 | |
3873 | /* Bandwidth */ |
3874 | #define MLXSW_REG_QPCR_LOWEST_CIR_BITS 1024 /* bps */ |
3875 | #define MLXSW_REG_QPCR_HIGHEST_CIR_BITS 2000000000000ULL /* 2Tbps */ |
3876 | #define MLXSW_REG_QPCR_LOWEST_CBS_BITS_SP1 4 |
3877 | #define MLXSW_REG_QPCR_LOWEST_CBS_BITS_SP2 4 |
3878 | #define MLXSW_REG_QPCR_HIGHEST_CBS_BITS_SP1 25 |
3879 | #define MLXSW_REG_QPCR_HIGHEST_CBS_BITS_SP2 31 |
3880 | |
3881 | static inline void mlxsw_reg_qpcr_pack(char *payload, u16 pid, |
3882 | enum mlxsw_reg_qpcr_ir_units ir_units, |
3883 | bool bytes, u32 cir, u16 cbs) |
3884 | { |
3885 | MLXSW_REG_ZERO(qpcr, payload); |
3886 | mlxsw_reg_qpcr_pid_set(buf: payload, val: pid); |
3887 | mlxsw_reg_qpcr_g_set(buf: payload, val: MLXSW_REG_QPCR_G_GLOBAL); |
3888 | mlxsw_reg_qpcr_rate_type_set(buf: payload, val: MLXSW_REG_QPCR_RATE_TYPE_SINGLE); |
3889 | mlxsw_reg_qpcr_violate_action_set(buf: payload, |
3890 | val: MLXSW_REG_QPCR_ACTION_DISCARD); |
3891 | mlxsw_reg_qpcr_cir_set(buf: payload, val: cir); |
3892 | mlxsw_reg_qpcr_ir_units_set(buf: payload, val: ir_units); |
3893 | mlxsw_reg_qpcr_bytes_set(buf: payload, val: bytes); |
3894 | mlxsw_reg_qpcr_cbs_set(buf: payload, val: cbs); |
3895 | } |
3896 | |
3897 | /* QTCT - QoS Switch Traffic Class Table |
3898 | * ------------------------------------- |
3899 | * Configures the mapping between the packet switch priority and the |
3900 | * traffic class on the transmit port. |
3901 | */ |
3902 | #define MLXSW_REG_QTCT_ID 0x400A |
3903 | #define MLXSW_REG_QTCT_LEN 0x08 |
3904 | |
3905 | MLXSW_REG_DEFINE(qtct, MLXSW_REG_QTCT_ID, MLXSW_REG_QTCT_LEN); |
3906 | |
3907 | /* reg_qtct_local_port |
3908 | * Local port number. |
3909 | * Access: Index |
3910 | * |
3911 | * Note: CPU port is not supported. |
3912 | */ |
3913 | MLXSW_ITEM32_LP(reg, qtct, 0x00, 16, 0x00, 12); |
3914 | |
3915 | /* reg_qtct_sub_port |
3916 | * Virtual port within the physical port. |
3917 | * Should be set to 0 when virtual ports are not enabled on the port. |
3918 | * Access: Index |
3919 | */ |
3920 | MLXSW_ITEM32(reg, qtct, sub_port, 0x00, 8, 8); |
3921 | |
3922 | /* reg_qtct_switch_prio |
3923 | * Switch priority. |
3924 | * Access: Index |
3925 | */ |
3926 | MLXSW_ITEM32(reg, qtct, switch_prio, 0x00, 0, 4); |
3927 | |
3928 | /* reg_qtct_tclass |
3929 | * Traffic class. |
3930 | * Default values: |
3931 | * switch_prio 0 : tclass 1 |
3932 | * switch_prio 1 : tclass 0 |
3933 | * switch_prio i : tclass i, for i > 1 |
3934 | * Access: RW |
3935 | */ |
3936 | MLXSW_ITEM32(reg, qtct, tclass, 0x04, 0, 4); |
3937 | |
3938 | static inline void mlxsw_reg_qtct_pack(char *payload, u16 local_port, |
3939 | u8 switch_prio, u8 tclass) |
3940 | { |
3941 | MLXSW_REG_ZERO(qtct, payload); |
3942 | mlxsw_reg_qtct_local_port_set(buf: payload, val: local_port); |
3943 | mlxsw_reg_qtct_switch_prio_set(payload, switch_prio); |
3944 | mlxsw_reg_qtct_tclass_set(payload, tclass); |
3945 | } |
3946 | |
3947 | /* QEEC - QoS ETS Element Configuration Register |
3948 | * --------------------------------------------- |
3949 | * Configures the ETS elements. |
3950 | */ |
3951 | #define MLXSW_REG_QEEC_ID 0x400D |
3952 | #define MLXSW_REG_QEEC_LEN 0x20 |
3953 | |
3954 | MLXSW_REG_DEFINE(qeec, MLXSW_REG_QEEC_ID, MLXSW_REG_QEEC_LEN); |
3955 | |
3956 | /* reg_qeec_local_port |
3957 | * Local port number. |
3958 | * Access: Index |
3959 | * |
3960 | * Note: CPU port is supported. |
3961 | */ |
3962 | MLXSW_ITEM32_LP(reg, qeec, 0x00, 16, 0x00, 12); |
3963 | |
3964 | enum mlxsw_reg_qeec_hr { |
3965 | MLXSW_REG_QEEC_HR_PORT, |
3966 | MLXSW_REG_QEEC_HR_GROUP, |
3967 | MLXSW_REG_QEEC_HR_SUBGROUP, |
3968 | MLXSW_REG_QEEC_HR_TC, |
3969 | }; |
3970 | |
3971 | /* reg_qeec_element_hierarchy |
3972 | * 0 - Port |
3973 | * 1 - Group |
3974 | * 2 - Subgroup |
3975 | * 3 - Traffic Class |
3976 | * Access: Index |
3977 | */ |
3978 | MLXSW_ITEM32(reg, qeec, element_hierarchy, 0x04, 16, 4); |
3979 | |
3980 | /* reg_qeec_element_index |
3981 | * The index of the element in the hierarchy. |
3982 | * Access: Index |
3983 | */ |
3984 | MLXSW_ITEM32(reg, qeec, element_index, 0x04, 0, 8); |
3985 | |
3986 | /* reg_qeec_next_element_index |
3987 | * The index of the next (lower) element in the hierarchy. |
3988 | * Access: RW |
3989 | * |
3990 | * Note: Reserved for element_hierarchy 0. |
3991 | */ |
3992 | MLXSW_ITEM32(reg, qeec, next_element_index, 0x08, 0, 8); |
3993 | |
3994 | /* reg_qeec_mise |
3995 | * Min shaper configuration enable. Enables configuration of the min |
3996 | * shaper on this ETS element |
3997 | * 0 - Disable |
3998 | * 1 - Enable |
3999 | * Access: RW |
4000 | */ |
4001 | MLXSW_ITEM32(reg, qeec, mise, 0x0C, 31, 1); |
4002 | |
4003 | /* reg_qeec_ptps |
4004 | * PTP shaper |
4005 | * 0: regular shaper mode |
4006 | * 1: PTP oriented shaper |
4007 | * Allowed only for hierarchy 0 |
4008 | * Not supported for CPU port |
4009 | * Note that ptps mode may affect the shaper rates of all hierarchies |
4010 | * Supported only on Spectrum-1 |
4011 | * Access: RW |
4012 | */ |
4013 | MLXSW_ITEM32(reg, qeec, ptps, 0x0C, 29, 1); |
4014 | |
4015 | enum { |
4016 | MLXSW_REG_QEEC_BYTES_MODE, |
4017 | MLXSW_REG_QEEC_PACKETS_MODE, |
4018 | }; |
4019 | |
4020 | /* reg_qeec_pb |
4021 | * Packets or bytes mode. |
4022 | * 0 - Bytes mode |
4023 | * 1 - Packets mode |
4024 | * Access: RW |
4025 | * |
4026 | * Note: Used for max shaper configuration. For Spectrum, packets mode |
4027 | * is supported only for traffic classes of CPU port. |
4028 | */ |
4029 | MLXSW_ITEM32(reg, qeec, pb, 0x0C, 28, 1); |
4030 | |
4031 | /* The smallest permitted min shaper rate. */ |
4032 | #define MLXSW_REG_QEEC_MIS_MIN 200000 /* Kbps */ |
4033 | |
4034 | /* reg_qeec_min_shaper_rate |
4035 | * Min shaper information rate. |
4036 | * For CPU port, can only be configured for port hierarchy. |
4037 | * When in bytes mode, value is specified in units of 1000bps. |
4038 | * Access: RW |
4039 | */ |
4040 | MLXSW_ITEM32(reg, qeec, min_shaper_rate, 0x0C, 0, 28); |
4041 | |
4042 | /* reg_qeec_mase |
4043 | * Max shaper configuration enable. Enables configuration of the max |
4044 | * shaper on this ETS element. |
4045 | * 0 - Disable |
4046 | * 1 - Enable |
4047 | * Access: RW |
4048 | */ |
4049 | MLXSW_ITEM32(reg, qeec, mase, 0x10, 31, 1); |
4050 | |
4051 | /* The largest max shaper value possible to disable the shaper. */ |
4052 | #define MLXSW_REG_QEEC_MAS_DIS ((1u << 31) - 1) /* Kbps */ |
4053 | |
4054 | /* reg_qeec_max_shaper_rate |
4055 | * Max shaper information rate. |
4056 | * For CPU port, can only be configured for port hierarchy. |
4057 | * When in bytes mode, value is specified in units of 1000bps. |
4058 | * Access: RW |
4059 | */ |
4060 | MLXSW_ITEM32(reg, qeec, max_shaper_rate, 0x10, 0, 31); |
4061 | |
4062 | /* reg_qeec_de |
4063 | * DWRR configuration enable. Enables configuration of the dwrr and |
4064 | * dwrr_weight. |
4065 | * 0 - Disable |
4066 | * 1 - Enable |
4067 | * Access: RW |
4068 | */ |
4069 | MLXSW_ITEM32(reg, qeec, de, 0x18, 31, 1); |
4070 | |
4071 | /* reg_qeec_dwrr |
4072 | * Transmission selection algorithm to use on the link going down from |
4073 | * the ETS element. |
4074 | * 0 - Strict priority |
4075 | * 1 - DWRR |
4076 | * Access: RW |
4077 | */ |
4078 | MLXSW_ITEM32(reg, qeec, dwrr, 0x18, 15, 1); |
4079 | |
4080 | /* reg_qeec_dwrr_weight |
4081 | * DWRR weight on the link going down from the ETS element. The |
4082 | * percentage of bandwidth guaranteed to an ETS element within |
4083 | * its hierarchy. The sum of all weights across all ETS elements |
4084 | * within one hierarchy should be equal to 100. Reserved when |
4085 | * transmission selection algorithm is strict priority. |
4086 | * Access: RW |
4087 | */ |
4088 | MLXSW_ITEM32(reg, qeec, dwrr_weight, 0x18, 0, 8); |
4089 | |
4090 | /* reg_qeec_max_shaper_bs |
4091 | * Max shaper burst size |
4092 | * Burst size is 2^max_shaper_bs * 512 bits |
4093 | * For Spectrum-1: Range is: 5..25 |
4094 | * For Spectrum-2: Range is: 11..25 |
4095 | * Reserved when ptps = 1 |
4096 | * Access: RW |
4097 | */ |
4098 | MLXSW_ITEM32(reg, qeec, max_shaper_bs, 0x1C, 0, 6); |
4099 | |
4100 | #define MLXSW_REG_QEEC_HIGHEST_SHAPER_BS 25 |
4101 | #define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP1 5 |
4102 | #define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP2 11 |
4103 | #define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP3 11 |
4104 | #define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP4 11 |
4105 | |
4106 | static inline void mlxsw_reg_qeec_pack(char *payload, u16 local_port, |
4107 | enum mlxsw_reg_qeec_hr hr, u8 index, |
4108 | u8 next_index) |
4109 | { |
4110 | MLXSW_REG_ZERO(qeec, payload); |
4111 | mlxsw_reg_qeec_local_port_set(buf: payload, val: local_port); |
4112 | mlxsw_reg_qeec_element_hierarchy_set(buf: payload, val: hr); |
4113 | mlxsw_reg_qeec_element_index_set(payload, index); |
4114 | mlxsw_reg_qeec_next_element_index_set(payload, next_index); |
4115 | } |
4116 | |
4117 | static inline void mlxsw_reg_qeec_ptps_pack(char *payload, u16 local_port, |
4118 | bool ptps) |
4119 | { |
4120 | MLXSW_REG_ZERO(qeec, payload); |
4121 | mlxsw_reg_qeec_local_port_set(buf: payload, val: local_port); |
4122 | mlxsw_reg_qeec_element_hierarchy_set(buf: payload, val: MLXSW_REG_QEEC_HR_PORT); |
4123 | mlxsw_reg_qeec_ptps_set(buf: payload, val: ptps); |
4124 | } |
4125 | |
4126 | /* QRWE - QoS ReWrite Enable |
4127 | * ------------------------- |
4128 | * This register configures the rewrite enable per receive port. |
4129 | */ |
4130 | #define MLXSW_REG_QRWE_ID 0x400F |
4131 | #define MLXSW_REG_QRWE_LEN 0x08 |
4132 | |
4133 | MLXSW_REG_DEFINE(qrwe, MLXSW_REG_QRWE_ID, MLXSW_REG_QRWE_LEN); |
4134 | |
4135 | /* reg_qrwe_local_port |
4136 | * Local port number. |
4137 | * Access: Index |
4138 | * |
4139 | * Note: CPU port is supported. No support for router port. |
4140 | */ |
4141 | MLXSW_ITEM32_LP(reg, qrwe, 0x00, 16, 0x00, 12); |
4142 | |
4143 | /* reg_qrwe_dscp |
4144 | * Whether to enable DSCP rewrite (default is 0, don't rewrite). |
4145 | * Access: RW |
4146 | */ |
4147 | MLXSW_ITEM32(reg, qrwe, dscp, 0x04, 1, 1); |
4148 | |
4149 | /* reg_qrwe_pcp |
4150 | * Whether to enable PCP and DEI rewrite (default is 0, don't rewrite). |
4151 | * Access: RW |
4152 | */ |
4153 | MLXSW_ITEM32(reg, qrwe, pcp, 0x04, 0, 1); |
4154 | |
4155 | static inline void mlxsw_reg_qrwe_pack(char *payload, u16 local_port, |
4156 | bool rewrite_pcp, bool rewrite_dscp) |
4157 | { |
4158 | MLXSW_REG_ZERO(qrwe, payload); |
4159 | mlxsw_reg_qrwe_local_port_set(buf: payload, val: local_port); |
4160 | mlxsw_reg_qrwe_pcp_set(buf: payload, val: rewrite_pcp); |
4161 | mlxsw_reg_qrwe_dscp_set(buf: payload, val: rewrite_dscp); |
4162 | } |
4163 | |
4164 | /* QPDSM - QoS Priority to DSCP Mapping |
4165 | * ------------------------------------ |
4166 | * QoS Priority to DSCP Mapping Register |
4167 | */ |
4168 | #define MLXSW_REG_QPDSM_ID 0x4011 |
4169 | #define MLXSW_REG_QPDSM_BASE_LEN 0x04 /* base length, without records */ |
4170 | #define MLXSW_REG_QPDSM_PRIO_ENTRY_REC_LEN 0x4 /* record length */ |
4171 | #define MLXSW_REG_QPDSM_PRIO_ENTRY_REC_MAX_COUNT 16 |
4172 | #define MLXSW_REG_QPDSM_LEN (MLXSW_REG_QPDSM_BASE_LEN + \ |
4173 | MLXSW_REG_QPDSM_PRIO_ENTRY_REC_LEN * \ |
4174 | MLXSW_REG_QPDSM_PRIO_ENTRY_REC_MAX_COUNT) |
4175 | |
4176 | MLXSW_REG_DEFINE(qpdsm, MLXSW_REG_QPDSM_ID, MLXSW_REG_QPDSM_LEN); |
4177 | |
4178 | /* reg_qpdsm_local_port |
4179 | * Local Port. Supported for data packets from CPU port. |
4180 | * Access: Index |
4181 | */ |
4182 | MLXSW_ITEM32_LP(reg, qpdsm, 0x00, 16, 0x00, 12); |
4183 | |
4184 | /* reg_qpdsm_prio_entry_color0_e |
4185 | * Enable update of the entry for color 0 and a given port. |
4186 | * Access: WO |
4187 | */ |
4188 | MLXSW_ITEM32_INDEXED(reg, qpdsm, prio_entry_color0_e, |
4189 | MLXSW_REG_QPDSM_BASE_LEN, 31, 1, |
4190 | MLXSW_REG_QPDSM_PRIO_ENTRY_REC_LEN, 0x00, false); |
4191 | |
4192 | /* reg_qpdsm_prio_entry_color0_dscp |
4193 | * DSCP field in the outer label of the packet for color 0 and a given port. |
4194 | * Reserved when e=0. |
4195 | * Access: RW |
4196 | */ |
4197 | MLXSW_ITEM32_INDEXED(reg, qpdsm, prio_entry_color0_dscp, |
4198 | MLXSW_REG_QPDSM_BASE_LEN, 24, 6, |
4199 | MLXSW_REG_QPDSM_PRIO_ENTRY_REC_LEN, 0x00, false); |
4200 | |
4201 | /* reg_qpdsm_prio_entry_color1_e |
4202 | * Enable update of the entry for color 1 and a given port. |
4203 | * Access: WO |
4204 | */ |
4205 | MLXSW_ITEM32_INDEXED(reg, qpdsm, prio_entry_color1_e, |
4206 | MLXSW_REG_QPDSM_BASE_LEN, 23, 1, |
4207 | MLXSW_REG_QPDSM_PRIO_ENTRY_REC_LEN, 0x00, false); |
4208 | |
4209 | /* reg_qpdsm_prio_entry_color1_dscp |
4210 | * DSCP field in the outer label of the packet for color 1 and a given port. |
4211 | * Reserved when e=0. |
4212 | * Access: RW |
4213 | */ |
4214 | MLXSW_ITEM32_INDEXED(reg, qpdsm, prio_entry_color1_dscp, |
4215 | MLXSW_REG_QPDSM_BASE_LEN, 16, 6, |
4216 | MLXSW_REG_QPDSM_PRIO_ENTRY_REC_LEN, 0x00, false); |
4217 | |
4218 | /* reg_qpdsm_prio_entry_color2_e |
4219 | * Enable update of the entry for color 2 and a given port. |
4220 | * Access: WO |
4221 | */ |
4222 | MLXSW_ITEM32_INDEXED(reg, qpdsm, prio_entry_color2_e, |
4223 | MLXSW_REG_QPDSM_BASE_LEN, 15, 1, |
4224 | MLXSW_REG_QPDSM_PRIO_ENTRY_REC_LEN, 0x00, false); |
4225 | |
4226 | /* reg_qpdsm_prio_entry_color2_dscp |
4227 | * DSCP field in the outer label of the packet for color 2 and a given port. |
4228 | * Reserved when e=0. |
4229 | * Access: RW |
4230 | */ |
4231 | MLXSW_ITEM32_INDEXED(reg, qpdsm, prio_entry_color2_dscp, |
4232 | MLXSW_REG_QPDSM_BASE_LEN, 8, 6, |
4233 | MLXSW_REG_QPDSM_PRIO_ENTRY_REC_LEN, 0x00, false); |
4234 | |
4235 | static inline void mlxsw_reg_qpdsm_pack(char *payload, u16 local_port) |
4236 | { |
4237 | MLXSW_REG_ZERO(qpdsm, payload); |
4238 | mlxsw_reg_qpdsm_local_port_set(buf: payload, val: local_port); |
4239 | } |
4240 | |
4241 | static inline void |
4242 | mlxsw_reg_qpdsm_prio_pack(char *payload, unsigned short prio, u8 dscp) |
4243 | { |
4244 | mlxsw_reg_qpdsm_prio_entry_color0_e_set(buf: payload, index: prio, val: 1); |
4245 | mlxsw_reg_qpdsm_prio_entry_color0_dscp_set(payload, prio, dscp); |
4246 | mlxsw_reg_qpdsm_prio_entry_color1_e_set(buf: payload, index: prio, val: 1); |
4247 | mlxsw_reg_qpdsm_prio_entry_color1_dscp_set(payload, prio, dscp); |
4248 | mlxsw_reg_qpdsm_prio_entry_color2_e_set(buf: payload, index: prio, val: 1); |
4249 | mlxsw_reg_qpdsm_prio_entry_color2_dscp_set(payload, prio, dscp); |
4250 | } |
4251 | |
4252 | /* QPDP - QoS Port DSCP to Priority Mapping Register |
4253 | * ------------------------------------------------- |
4254 | * This register controls the port default Switch Priority and Color. The |
4255 | * default Switch Priority and Color are used for frames where the trust state |
4256 | * uses default values. All member ports of a LAG should be configured with the |
4257 | * same default values. |
4258 | */ |
4259 | #define MLXSW_REG_QPDP_ID 0x4007 |
4260 | #define MLXSW_REG_QPDP_LEN 0x8 |
4261 | |
4262 | MLXSW_REG_DEFINE(qpdp, MLXSW_REG_QPDP_ID, MLXSW_REG_QPDP_LEN); |
4263 | |
4264 | /* reg_qpdp_local_port |
4265 | * Local Port. Supported for data packets from CPU port. |
4266 | * Access: Index |
4267 | */ |
4268 | MLXSW_ITEM32_LP(reg, qpdp, 0x00, 16, 0x00, 12); |
4269 | |
4270 | /* reg_qpdp_switch_prio |
4271 | * Default port Switch Priority (default 0) |
4272 | * Access: RW |
4273 | */ |
4274 | MLXSW_ITEM32(reg, qpdp, switch_prio, 0x04, 0, 4); |
4275 | |
4276 | static inline void mlxsw_reg_qpdp_pack(char *payload, u16 local_port, |
4277 | u8 switch_prio) |
4278 | { |
4279 | MLXSW_REG_ZERO(qpdp, payload); |
4280 | mlxsw_reg_qpdp_local_port_set(buf: payload, val: local_port); |
4281 | mlxsw_reg_qpdp_switch_prio_set(payload, switch_prio); |
4282 | } |
4283 | |
4284 | /* QPDPM - QoS Port DSCP to Priority Mapping Register |
4285 | * -------------------------------------------------- |
4286 | * This register controls the mapping from DSCP field to |
4287 | * Switch Priority for IP packets. |
4288 | */ |
4289 | #define MLXSW_REG_QPDPM_ID 0x4013 |
4290 | #define MLXSW_REG_QPDPM_BASE_LEN 0x4 /* base length, without records */ |
4291 | #define MLXSW_REG_QPDPM_DSCP_ENTRY_REC_LEN 0x2 /* record length */ |
4292 | #define MLXSW_REG_QPDPM_DSCP_ENTRY_REC_MAX_COUNT 64 |
4293 | #define MLXSW_REG_QPDPM_LEN (MLXSW_REG_QPDPM_BASE_LEN + \ |
4294 | MLXSW_REG_QPDPM_DSCP_ENTRY_REC_LEN * \ |
4295 | MLXSW_REG_QPDPM_DSCP_ENTRY_REC_MAX_COUNT) |
4296 | |
4297 | MLXSW_REG_DEFINE(qpdpm, MLXSW_REG_QPDPM_ID, MLXSW_REG_QPDPM_LEN); |
4298 | |
4299 | /* reg_qpdpm_local_port |
4300 | * Local Port. Supported for data packets from CPU port. |
4301 | * Access: Index |
4302 | */ |
4303 | MLXSW_ITEM32_LP(reg, qpdpm, 0x00, 16, 0x00, 12); |
4304 | |
4305 | /* reg_qpdpm_dscp_e |
4306 | * Enable update of the specific entry. When cleared, the switch_prio and color |
4307 | * fields are ignored and the previous switch_prio and color values are |
4308 | * preserved. |
4309 | * Access: WO |
4310 | */ |
4311 | MLXSW_ITEM16_INDEXED(reg, qpdpm, dscp_entry_e, MLXSW_REG_QPDPM_BASE_LEN, 15, 1, |
4312 | MLXSW_REG_QPDPM_DSCP_ENTRY_REC_LEN, 0x00, false); |
4313 | |
4314 | /* reg_qpdpm_dscp_prio |
4315 | * The new Switch Priority value for the relevant DSCP value. |
4316 | * Access: RW |
4317 | */ |
4318 | MLXSW_ITEM16_INDEXED(reg, qpdpm, dscp_entry_prio, |
4319 | MLXSW_REG_QPDPM_BASE_LEN, 0, 4, |
4320 | MLXSW_REG_QPDPM_DSCP_ENTRY_REC_LEN, 0x00, false); |
4321 | |
4322 | static inline void mlxsw_reg_qpdpm_pack(char *payload, u16 local_port) |
4323 | { |
4324 | MLXSW_REG_ZERO(qpdpm, payload); |
4325 | mlxsw_reg_qpdpm_local_port_set(buf: payload, val: local_port); |
4326 | } |
4327 | |
4328 | static inline void |
4329 | mlxsw_reg_qpdpm_dscp_pack(char *payload, unsigned short dscp, u8 prio) |
4330 | { |
4331 | mlxsw_reg_qpdpm_dscp_entry_e_set(buf: payload, index: dscp, val: 1); |
4332 | mlxsw_reg_qpdpm_dscp_entry_prio_set(payload, dscp, prio); |
4333 | } |
4334 | |
4335 | /* QTCTM - QoS Switch Traffic Class Table is Multicast-Aware Register |
4336 | * ------------------------------------------------------------------ |
4337 | * This register configures if the Switch Priority to Traffic Class mapping is |
4338 | * based on Multicast packet indication. If so, then multicast packets will get |
4339 | * a Traffic Class that is plus (cap_max_tclass_data/2) the value configured by |
4340 | * QTCT. |
4341 | * By default, Switch Priority to Traffic Class mapping is not based on |
4342 | * Multicast packet indication. |
4343 | */ |
4344 | #define MLXSW_REG_QTCTM_ID 0x401A |
4345 | #define MLXSW_REG_QTCTM_LEN 0x08 |
4346 | |
4347 | MLXSW_REG_DEFINE(qtctm, MLXSW_REG_QTCTM_ID, MLXSW_REG_QTCTM_LEN); |
4348 | |
4349 | /* reg_qtctm_local_port |
4350 | * Local port number. |
4351 | * No support for CPU port. |
4352 | * Access: Index |
4353 | */ |
4354 | MLXSW_ITEM32_LP(reg, qtctm, 0x00, 16, 0x00, 12); |
4355 | |
4356 | /* reg_qtctm_mc |
4357 | * Multicast Mode |
4358 | * Whether Switch Priority to Traffic Class mapping is based on Multicast packet |
4359 | * indication (default is 0, not based on Multicast packet indication). |
4360 | */ |
4361 | MLXSW_ITEM32(reg, qtctm, mc, 0x04, 0, 1); |
4362 | |
4363 | static inline void |
4364 | mlxsw_reg_qtctm_pack(char *payload, u16 local_port, bool mc) |
4365 | { |
4366 | MLXSW_REG_ZERO(qtctm, payload); |
4367 | mlxsw_reg_qtctm_local_port_set(buf: payload, val: local_port); |
4368 | mlxsw_reg_qtctm_mc_set(buf: payload, val: mc); |
4369 | } |
4370 | |
4371 | /* QPSC - QoS PTP Shaper Configuration Register |
4372 | * -------------------------------------------- |
4373 | * The QPSC allows advanced configuration of the shapers when QEEC.ptps=1. |
4374 | * Supported only on Spectrum-1. |
4375 | */ |
4376 | #define MLXSW_REG_QPSC_ID 0x401B |
4377 | #define MLXSW_REG_QPSC_LEN 0x28 |
4378 | |
4379 | MLXSW_REG_DEFINE(qpsc, MLXSW_REG_QPSC_ID, MLXSW_REG_QPSC_LEN); |
4380 | |
4381 | enum mlxsw_reg_qpsc_port_speed { |
4382 | MLXSW_REG_QPSC_PORT_SPEED_100M, |
4383 | MLXSW_REG_QPSC_PORT_SPEED_1G, |
4384 | MLXSW_REG_QPSC_PORT_SPEED_10G, |
4385 | MLXSW_REG_QPSC_PORT_SPEED_25G, |
4386 | }; |
4387 | |
4388 | /* reg_qpsc_port_speed |
4389 | * Port speed. |
4390 | * Access: Index |
4391 | */ |
4392 | MLXSW_ITEM32(reg, qpsc, port_speed, 0x00, 0, 4); |
4393 | |
4394 | /* reg_qpsc_shaper_time_exp |
4395 | * The base-time-interval for updating the shapers tokens (for all hierarchies). |
4396 | * shaper_update_rate = 2 ^ shaper_time_exp * (1 + shaper_time_mantissa) * 32nSec |
4397 | * shaper_rate = 64bit * shaper_inc / shaper_update_rate |
4398 | * Access: RW |
4399 | */ |
4400 | MLXSW_ITEM32(reg, qpsc, shaper_time_exp, 0x04, 16, 4); |
4401 | |
4402 | /* reg_qpsc_shaper_time_mantissa |
4403 | * The base-time-interval for updating the shapers tokens (for all hierarchies). |
4404 | * shaper_update_rate = 2 ^ shaper_time_exp * (1 + shaper_time_mantissa) * 32nSec |
4405 | * shaper_rate = 64bit * shaper_inc / shaper_update_rate |
4406 | * Access: RW |
4407 | */ |
4408 | MLXSW_ITEM32(reg, qpsc, shaper_time_mantissa, 0x04, 0, 5); |
4409 | |
4410 | /* reg_qpsc_shaper_inc |
4411 | * Number of tokens added to shaper on each update. |
4412 | * Units of 8B. |
4413 | * Access: RW |
4414 | */ |
4415 | MLXSW_ITEM32(reg, qpsc, shaper_inc, 0x08, 0, 5); |
4416 | |
4417 | /* reg_qpsc_shaper_bs |
4418 | * Max shaper Burst size. |
4419 | * Burst size is 2 ^ max_shaper_bs * 512 [bits] |
4420 | * Range is: 5..25 (from 2KB..2GB) |
4421 | * Access: RW |
4422 | */ |
4423 | MLXSW_ITEM32(reg, qpsc, shaper_bs, 0x0C, 0, 6); |
4424 | |
4425 | /* reg_qpsc_ptsc_we |
4426 | * Write enable to port_to_shaper_credits. |
4427 | * Access: WO |
4428 | */ |
4429 | MLXSW_ITEM32(reg, qpsc, ptsc_we, 0x10, 31, 1); |
4430 | |
4431 | /* reg_qpsc_port_to_shaper_credits |
4432 | * For split ports: range 1..57 |
4433 | * For non-split ports: range 1..112 |
4434 | * Written only when ptsc_we is set. |
4435 | * Access: RW |
4436 | */ |
4437 | MLXSW_ITEM32(reg, qpsc, port_to_shaper_credits, 0x10, 0, 8); |
4438 | |
4439 | /* reg_qpsc_ing_timestamp_inc |
4440 | * Ingress timestamp increment. |
4441 | * 2's complement. |
4442 | * The timestamp of MTPPTR at ingress will be incremented by this value. Global |
4443 | * value for all ports. |
4444 | * Same units as used by MTPPTR. |
4445 | * Access: RW |
4446 | */ |
4447 | MLXSW_ITEM32(reg, qpsc, ing_timestamp_inc, 0x20, 0, 32); |
4448 | |
4449 | /* reg_qpsc_egr_timestamp_inc |
4450 | * Egress timestamp increment. |
4451 | * 2's complement. |
4452 | * The timestamp of MTPPTR at egress will be incremented by this value. Global |
4453 | * value for all ports. |
4454 | * Same units as used by MTPPTR. |
4455 | * Access: RW |
4456 | */ |
4457 | MLXSW_ITEM32(reg, qpsc, egr_timestamp_inc, 0x24, 0, 32); |
4458 | |
4459 | static inline void |
4460 | mlxsw_reg_qpsc_pack(char *payload, enum mlxsw_reg_qpsc_port_speed port_speed, |
4461 | u8 shaper_time_exp, u8 shaper_time_mantissa, u8 shaper_inc, |
4462 | u8 shaper_bs, u8 port_to_shaper_credits, |
4463 | int ing_timestamp_inc, int egr_timestamp_inc) |
4464 | { |
4465 | MLXSW_REG_ZERO(qpsc, payload); |
4466 | mlxsw_reg_qpsc_port_speed_set(buf: payload, val: port_speed); |
4467 | mlxsw_reg_qpsc_shaper_time_exp_set(payload, shaper_time_exp); |
4468 | mlxsw_reg_qpsc_shaper_time_mantissa_set(payload, shaper_time_mantissa); |
4469 | mlxsw_reg_qpsc_shaper_inc_set(payload, shaper_inc); |
4470 | mlxsw_reg_qpsc_shaper_bs_set(payload, shaper_bs); |
4471 | mlxsw_reg_qpsc_ptsc_we_set(buf: payload, val: true); |
4472 | mlxsw_reg_qpsc_port_to_shaper_credits_set(payload, port_to_shaper_credits); |
4473 | mlxsw_reg_qpsc_ing_timestamp_inc_set(buf: payload, val: ing_timestamp_inc); |
4474 | mlxsw_reg_qpsc_egr_timestamp_inc_set(buf: payload, val: egr_timestamp_inc); |
4475 | } |
4476 | |
4477 | /* PMLP - Ports Module to Local Port Register |
4478 | * ------------------------------------------ |
4479 | * Configures the assignment of modules to local ports. |
4480 | */ |
4481 | #define MLXSW_REG_PMLP_ID 0x5002 |
4482 | #define MLXSW_REG_PMLP_LEN 0x40 |
4483 | |
4484 | MLXSW_REG_DEFINE(pmlp, MLXSW_REG_PMLP_ID, MLXSW_REG_PMLP_LEN); |
4485 | |
4486 | /* reg_pmlp_rxtx |
4487 | * 0 - Tx value is used for both Tx and Rx. |
4488 | * 1 - Rx value is taken from a separte field. |
4489 | * Access: RW |
4490 | */ |
4491 | MLXSW_ITEM32(reg, pmlp, rxtx, 0x00, 31, 1); |
4492 | |
4493 | /* reg_pmlp_local_port |
4494 | * Local port number. |
4495 | * Access: Index |
4496 | */ |
4497 | MLXSW_ITEM32_LP(reg, pmlp, 0x00, 16, 0x00, 12); |
4498 | |
4499 | /* reg_pmlp_width |
4500 | * 0 - Unmap local port. |
4501 | * 1 - Lane 0 is used. |
4502 | * 2 - Lanes 0 and 1 are used. |
4503 | * 4 - Lanes 0, 1, 2 and 3 are used. |
4504 | * 8 - Lanes 0-7 are used. |
4505 | * Access: RW |
4506 | */ |
4507 | MLXSW_ITEM32(reg, pmlp, width, 0x00, 0, 8); |
4508 | |
4509 | /* reg_pmlp_module |
4510 | * Module number. |
4511 | * Access: RW |
4512 | */ |
4513 | MLXSW_ITEM32_INDEXED(reg, pmlp, module, 0x04, 0, 8, 0x04, 0x00, false); |
4514 | |
4515 | /* reg_pmlp_slot_index |
4516 | * Module number. |
4517 | * Slot_index |
4518 | * Slot_index = 0 represent the onboard (motherboard). |
4519 | * In case of non-modular system only slot_index = 0 is available. |
4520 | * Access: RW |
4521 | */ |
4522 | MLXSW_ITEM32_INDEXED(reg, pmlp, slot_index, 0x04, 8, 4, 0x04, 0x00, false); |
4523 | |
4524 | /* reg_pmlp_tx_lane |
4525 | * Tx Lane. When rxtx field is cleared, this field is used for Rx as well. |
4526 | * Access: RW |
4527 | */ |
4528 | MLXSW_ITEM32_INDEXED(reg, pmlp, tx_lane, 0x04, 16, 4, 0x04, 0x00, false); |
4529 | |
4530 | /* reg_pmlp_rx_lane |
4531 | * Rx Lane. When rxtx field is cleared, this field is ignored and Rx lane is |
4532 | * equal to Tx lane. |
4533 | * Access: RW |
4534 | */ |
4535 | MLXSW_ITEM32_INDEXED(reg, pmlp, rx_lane, 0x04, 24, 4, 0x04, 0x00, false); |
4536 | |
4537 | static inline void mlxsw_reg_pmlp_pack(char *payload, u16 local_port) |
4538 | { |
4539 | MLXSW_REG_ZERO(pmlp, payload); |
4540 | mlxsw_reg_pmlp_local_port_set(buf: payload, val: local_port); |
4541 | } |
4542 | |
4543 | /* PMTU - Port MTU Register |
4544 | * ------------------------ |
4545 | * Configures and reports the port MTU. |
4546 | */ |
4547 | #define MLXSW_REG_PMTU_ID 0x5003 |
4548 | #define MLXSW_REG_PMTU_LEN 0x10 |
4549 | |
4550 | MLXSW_REG_DEFINE(pmtu, MLXSW_REG_PMTU_ID, MLXSW_REG_PMTU_LEN); |
4551 | |
4552 | /* reg_pmtu_local_port |
4553 | * Local port number. |
4554 | * Access: Index |
4555 | */ |
4556 | MLXSW_ITEM32_LP(reg, pmtu, 0x00, 16, 0x00, 12); |
4557 | |
4558 | /* reg_pmtu_max_mtu |
4559 | * Maximum MTU. |
4560 | * When port type (e.g. Ethernet) is configured, the relevant MTU is |
4561 | * reported, otherwise the minimum between the max_mtu of the different |
4562 | * types is reported. |
4563 | * Access: RO |
4564 | */ |
4565 | MLXSW_ITEM32(reg, pmtu, max_mtu, 0x04, 16, 16); |
4566 | |
4567 | /* reg_pmtu_admin_mtu |
4568 | * MTU value to set port to. Must be smaller or equal to max_mtu. |
4569 | * Note: If port type is Infiniband, then port must be disabled, when its |
4570 | * MTU is set. |
4571 | * Access: RW |
4572 | */ |
4573 | MLXSW_ITEM32(reg, pmtu, admin_mtu, 0x08, 16, 16); |
4574 | |
4575 | /* reg_pmtu_oper_mtu |
4576 | * The actual MTU configured on the port. Packets exceeding this size |
4577 | * will be dropped. |
4578 | * Note: In Ethernet and FC oper_mtu == admin_mtu, however, in Infiniband |
4579 | * oper_mtu might be smaller than admin_mtu. |
4580 | * Access: RO |
4581 | */ |
4582 | MLXSW_ITEM32(reg, pmtu, oper_mtu, 0x0C, 16, 16); |
4583 | |
4584 | static inline void mlxsw_reg_pmtu_pack(char *payload, u16 local_port, |
4585 | u16 new_mtu) |
4586 | { |
4587 | MLXSW_REG_ZERO(pmtu, payload); |
4588 | mlxsw_reg_pmtu_local_port_set(buf: payload, val: local_port); |
4589 | mlxsw_reg_pmtu_max_mtu_set(buf: payload, val: 0); |
4590 | mlxsw_reg_pmtu_admin_mtu_set(buf: payload, val: new_mtu); |
4591 | mlxsw_reg_pmtu_oper_mtu_set(buf: payload, val: 0); |
4592 | } |
4593 | |
4594 | /* PTYS - Port Type and Speed Register |
4595 | * ----------------------------------- |
4596 | * Configures and reports the port speed type. |
4597 | * |
4598 | * Note: When set while the link is up, the changes will not take effect |
4599 | * until the port transitions from down to up state. |
4600 | */ |
4601 | #define MLXSW_REG_PTYS_ID 0x5004 |
4602 | #define MLXSW_REG_PTYS_LEN 0x40 |
4603 | |
4604 | MLXSW_REG_DEFINE(ptys, MLXSW_REG_PTYS_ID, MLXSW_REG_PTYS_LEN); |
4605 | |
4606 | /* an_disable_admin |
4607 | * Auto negotiation disable administrative configuration |
4608 | * 0 - Device doesn't support AN disable. |
4609 | * 1 - Device supports AN disable. |
4610 | * Access: RW |
4611 | */ |
4612 | MLXSW_ITEM32(reg, ptys, an_disable_admin, 0x00, 30, 1); |
4613 | |
4614 | /* reg_ptys_local_port |
4615 | * Local port number. |
4616 | * Access: Index |
4617 | */ |
4618 | MLXSW_ITEM32_LP(reg, ptys, 0x00, 16, 0x00, 12); |
4619 | |
4620 | #define MLXSW_REG_PTYS_PROTO_MASK_IB BIT(0) |
4621 | #define MLXSW_REG_PTYS_PROTO_MASK_ETH BIT(2) |
4622 | |
4623 | /* reg_ptys_proto_mask |
4624 | * Protocol mask. Indicates which protocol is used. |
4625 | * 0 - Infiniband. |
4626 | * 1 - Fibre Channel. |
4627 | * 2 - Ethernet. |
4628 | * Access: Index |
4629 | */ |
4630 | MLXSW_ITEM32(reg, ptys, proto_mask, 0x00, 0, 3); |
4631 | |
4632 | enum { |
4633 | MLXSW_REG_PTYS_AN_STATUS_NA, |
4634 | MLXSW_REG_PTYS_AN_STATUS_OK, |
4635 | MLXSW_REG_PTYS_AN_STATUS_FAIL, |
4636 | }; |
4637 | |
4638 | /* reg_ptys_an_status |
4639 | * Autonegotiation status. |
4640 | * Access: RO |
4641 | */ |
4642 | MLXSW_ITEM32(reg, ptys, an_status, 0x04, 28, 4); |
4643 | |
4644 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_SGMII_100M BIT(0) |
4645 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_1000BASE_X_SGMII BIT(1) |
4646 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_5GBASE_R BIT(3) |
4647 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_XFI_XAUI_1_10G BIT(4) |
4648 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_XLAUI_4_XLPPI_4_40G BIT(5) |
4649 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_25GAUI_1_25GBASE_CR_KR BIT(6) |
4650 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_2_LAUI_2_50GBASE_CR2_KR2 BIT(7) |
4651 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_1_LAUI_1_50GBASE_CR_KR BIT(8) |
4652 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_CAUI_4_100GBASE_CR4_KR4 BIT(9) |
4653 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_100GAUI_2_100GBASE_CR2_KR2 BIT(10) |
4654 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_200GAUI_4_200GBASE_CR4_KR4 BIT(12) |
4655 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_400GAUI_8 BIT(15) |
4656 | #define MLXSW_REG_PTYS_EXT_ETH_SPEED_800GAUI_8 BIT(19) |
4657 | |
4658 | /* reg_ptys_ext_eth_proto_cap |
4659 | * Extended Ethernet port supported speeds and protocols. |
4660 | * Access: RO |
4661 | */ |
4662 | MLXSW_ITEM32(reg, ptys, ext_eth_proto_cap, 0x08, 0, 32); |
4663 | |
4664 | #define MLXSW_REG_PTYS_ETH_SPEED_SGMII BIT(0) |
4665 | #define MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX BIT(1) |
4666 | #define MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CX4 BIT(2) |
4667 | #define MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4 BIT(3) |
4668 | #define MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR BIT(4) |
4669 | #define MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4 BIT(6) |
4670 | #define MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4 BIT(7) |
4671 | #define MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR BIT(12) |
4672 | #define MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR BIT(13) |
4673 | #define MLXSW_REG_PTYS_ETH_SPEED_10GBASE_ER_LR BIT(14) |
4674 | #define MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4 BIT(15) |
4675 | #define MLXSW_REG_PTYS_ETH_SPEED_40GBASE_LR4_ER4 BIT(16) |
4676 | #define MLXSW_REG_PTYS_ETH_SPEED_50GBASE_SR2 BIT(18) |
4677 | #define MLXSW_REG_PTYS_ETH_SPEED_50GBASE_KR4 BIT(19) |
4678 | #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4 BIT(20) |
4679 | #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 BIT(21) |
4680 | #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 BIT(22) |
4681 | #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4 BIT(23) |
4682 | #define MLXSW_REG_PTYS_ETH_SPEED_100BASE_T BIT(24) |
4683 | #define MLXSW_REG_PTYS_ETH_SPEED_1000BASE_T BIT(25) |
4684 | #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_CR BIT(27) |
4685 | #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_KR BIT(28) |
4686 | #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_SR BIT(29) |
4687 | #define MLXSW_REG_PTYS_ETH_SPEED_50GBASE_CR2 BIT(30) |
4688 | #define MLXSW_REG_PTYS_ETH_SPEED_50GBASE_KR2 BIT(31) |
4689 | |
4690 | /* reg_ptys_eth_proto_cap |
4691 | * Ethernet port supported speeds and protocols. |
4692 | * Access: RO |
4693 | */ |
4694 | MLXSW_ITEM32(reg, ptys, eth_proto_cap, 0x0C, 0, 32); |
4695 | |
4696 | /* reg_ptys_ext_eth_proto_admin |
4697 | * Extended speed and protocol to set port to. |
4698 | * Access: RW |
4699 | */ |
4700 | MLXSW_ITEM32(reg, ptys, ext_eth_proto_admin, 0x14, 0, 32); |
4701 | |
4702 | /* reg_ptys_eth_proto_admin |
4703 | * Speed and protocol to set |
---|