1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright 2014-2016 Freescale Semiconductor Inc. |
4 | * Copyright 2017-2021 NXP |
5 | * |
6 | */ |
7 | |
8 | #include <linux/fsl/mc.h> |
9 | #include "dpsw.h" |
10 | #include "dpsw-cmd.h" |
11 | |
12 | static void build_if_id_bitmap(__le64 *bmap, const u16 *id, const u16 num_ifs) |
13 | { |
14 | int i; |
15 | |
16 | for (i = 0; (i < num_ifs) && (i < DPSW_MAX_IF); i++) { |
17 | if (id[i] < DPSW_MAX_IF) |
18 | bmap[id[i] / 64] |= cpu_to_le64(BIT_MASK(id[i] % 64)); |
19 | } |
20 | } |
21 | |
22 | /** |
23 | * dpsw_open() - Open a control session for the specified object |
24 | * @mc_io: Pointer to MC portal's I/O object |
25 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
26 | * @dpsw_id: DPSW unique ID |
27 | * @token: Returned token; use in subsequent API calls |
28 | * |
29 | * This function can be used to open a control session for an |
30 | * already created object; an object may have been declared in |
31 | * the DPL or by calling the dpsw_create() function. |
32 | * This function returns a unique authentication token, |
33 | * associated with the specific object ID and the specific MC |
34 | * portal; this token must be used in all subsequent commands for |
35 | * this specific object |
36 | * |
37 | * Return: '0' on Success; Error code otherwise. |
38 | */ |
39 | int dpsw_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int dpsw_id, u16 *token) |
40 | { |
41 | struct fsl_mc_command cmd = { 0 }; |
42 | struct dpsw_cmd_open *cmd_params; |
43 | int err; |
44 | |
45 | /* prepare command */ |
46 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_OPEN, |
47 | cmd_flags, |
48 | token: 0); |
49 | cmd_params = (struct dpsw_cmd_open *)cmd.params; |
50 | cmd_params->dpsw_id = cpu_to_le32(dpsw_id); |
51 | |
52 | /* send command to mc*/ |
53 | err = mc_send_command(mc_io, cmd: &cmd); |
54 | if (err) |
55 | return err; |
56 | |
57 | /* retrieve response parameters */ |
58 | *token = mc_cmd_hdr_read_token(cmd: &cmd); |
59 | |
60 | return 0; |
61 | } |
62 | |
63 | /** |
64 | * dpsw_close() - Close the control session of the object |
65 | * @mc_io: Pointer to MC portal's I/O object |
66 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
67 | * @token: Token of DPSW object |
68 | * |
69 | * After this function is called, no further operations are |
70 | * allowed on the object without opening a new control session. |
71 | * |
72 | * Return: '0' on Success; Error code otherwise. |
73 | */ |
74 | int dpsw_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) |
75 | { |
76 | struct fsl_mc_command cmd = { 0 }; |
77 | |
78 | /* prepare command */ |
79 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLOSE, |
80 | cmd_flags, |
81 | token); |
82 | |
83 | /* send command to mc*/ |
84 | return mc_send_command(mc_io, cmd: &cmd); |
85 | } |
86 | |
87 | /** |
88 | * dpsw_enable() - Enable DPSW functionality |
89 | * @mc_io: Pointer to MC portal's I/O object |
90 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
91 | * @token: Token of DPSW object |
92 | * |
93 | * Return: Completion status. '0' on Success; Error code otherwise. |
94 | */ |
95 | int dpsw_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) |
96 | { |
97 | struct fsl_mc_command cmd = { 0 }; |
98 | |
99 | /* prepare command */ |
100 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_ENABLE, |
101 | cmd_flags, |
102 | token); |
103 | |
104 | /* send command to mc*/ |
105 | return mc_send_command(mc_io, cmd: &cmd); |
106 | } |
107 | |
108 | /** |
109 | * dpsw_disable() - Disable DPSW functionality |
110 | * @mc_io: Pointer to MC portal's I/O object |
111 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
112 | * @token: Token of DPSW object |
113 | * |
114 | * Return: Completion status. '0' on Success; Error code otherwise. |
115 | */ |
116 | int dpsw_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) |
117 | { |
118 | struct fsl_mc_command cmd = { 0 }; |
119 | |
120 | /* prepare command */ |
121 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_DISABLE, |
122 | cmd_flags, |
123 | token); |
124 | |
125 | /* send command to mc*/ |
126 | return mc_send_command(mc_io, cmd: &cmd); |
127 | } |
128 | |
129 | /** |
130 | * dpsw_reset() - Reset the DPSW, returns the object to initial state. |
131 | * @mc_io: Pointer to MC portal's I/O object |
132 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
133 | * @token: Token of DPSW object |
134 | * |
135 | * Return: '0' on Success; Error code otherwise. |
136 | */ |
137 | int dpsw_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) |
138 | { |
139 | struct fsl_mc_command cmd = { 0 }; |
140 | |
141 | /* prepare command */ |
142 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_RESET, |
143 | cmd_flags, |
144 | token); |
145 | |
146 | /* send command to mc*/ |
147 | return mc_send_command(mc_io, cmd: &cmd); |
148 | } |
149 | |
150 | /** |
151 | * dpsw_set_irq_enable() - Set overall interrupt state. |
152 | * @mc_io: Pointer to MC portal's I/O object |
153 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
154 | * @token: Token of DPCI object |
155 | * @irq_index: The interrupt index to configure |
156 | * @en: Interrupt state - enable = 1, disable = 0 |
157 | * |
158 | * Allows GPP software to control when interrupts are generated. |
159 | * Each interrupt can have up to 32 causes. The enable/disable control's the |
160 | * overall interrupt state. if the interrupt is disabled no causes will cause |
161 | * an interrupt |
162 | * |
163 | * Return: '0' on Success; Error code otherwise. |
164 | */ |
165 | int dpsw_set_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
166 | u8 irq_index, u8 en) |
167 | { |
168 | struct fsl_mc_command cmd = { 0 }; |
169 | struct dpsw_cmd_set_irq_enable *cmd_params; |
170 | |
171 | /* prepare command */ |
172 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_ENABLE, |
173 | cmd_flags, |
174 | token); |
175 | cmd_params = (struct dpsw_cmd_set_irq_enable *)cmd.params; |
176 | dpsw_set_field(cmd_params->enable_state, ENABLE, en); |
177 | cmd_params->irq_index = irq_index; |
178 | |
179 | /* send command to mc*/ |
180 | return mc_send_command(mc_io, cmd: &cmd); |
181 | } |
182 | |
183 | /** |
184 | * dpsw_set_irq_mask() - Set interrupt mask. |
185 | * @mc_io: Pointer to MC portal's I/O object |
186 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
187 | * @token: Token of DPCI object |
188 | * @irq_index: The interrupt index to configure |
189 | * @mask: Event mask to trigger interrupt; |
190 | * each bit: |
191 | * 0 = ignore event |
192 | * 1 = consider event for asserting IRQ |
193 | * |
194 | * Every interrupt can have up to 32 causes and the interrupt model supports |
195 | * masking/unmasking each cause independently |
196 | * |
197 | * Return: '0' on Success; Error code otherwise. |
198 | */ |
199 | int dpsw_set_irq_mask(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
200 | u8 irq_index, u32 mask) |
201 | { |
202 | struct fsl_mc_command cmd = { 0 }; |
203 | struct dpsw_cmd_set_irq_mask *cmd_params; |
204 | |
205 | /* prepare command */ |
206 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_MASK, |
207 | cmd_flags, |
208 | token); |
209 | cmd_params = (struct dpsw_cmd_set_irq_mask *)cmd.params; |
210 | cmd_params->mask = cpu_to_le32(mask); |
211 | cmd_params->irq_index = irq_index; |
212 | |
213 | /* send command to mc*/ |
214 | return mc_send_command(mc_io, cmd: &cmd); |
215 | } |
216 | |
217 | /** |
218 | * dpsw_get_irq_status() - Get the current status of any pending interrupts |
219 | * @mc_io: Pointer to MC portal's I/O object |
220 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
221 | * @token: Token of DPSW object |
222 | * @irq_index: The interrupt index to configure |
223 | * @status: Returned interrupts status - one bit per cause: |
224 | * 0 = no interrupt pending |
225 | * 1 = interrupt pending |
226 | * |
227 | * Return: '0' on Success; Error code otherwise. |
228 | */ |
229 | int dpsw_get_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
230 | u8 irq_index, u32 *status) |
231 | { |
232 | struct fsl_mc_command cmd = { 0 }; |
233 | struct dpsw_cmd_get_irq_status *cmd_params; |
234 | struct dpsw_rsp_get_irq_status *rsp_params; |
235 | int err; |
236 | |
237 | /* prepare command */ |
238 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_STATUS, |
239 | cmd_flags, |
240 | token); |
241 | cmd_params = (struct dpsw_cmd_get_irq_status *)cmd.params; |
242 | cmd_params->status = cpu_to_le32(*status); |
243 | cmd_params->irq_index = irq_index; |
244 | |
245 | /* send command to mc*/ |
246 | err = mc_send_command(mc_io, cmd: &cmd); |
247 | if (err) |
248 | return err; |
249 | |
250 | /* retrieve response parameters */ |
251 | rsp_params = (struct dpsw_rsp_get_irq_status *)cmd.params; |
252 | *status = le32_to_cpu(rsp_params->status); |
253 | |
254 | return 0; |
255 | } |
256 | |
257 | /** |
258 | * dpsw_clear_irq_status() - Clear a pending interrupt's status |
259 | * @mc_io: Pointer to MC portal's I/O object |
260 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
261 | * @token: Token of DPCI object |
262 | * @irq_index: The interrupt index to configure |
263 | * @status: bits to clear (W1C) - one bit per cause: |
264 | * 0 = don't change |
265 | * 1 = clear status bit |
266 | * |
267 | * Return: '0' on Success; Error code otherwise. |
268 | */ |
269 | int dpsw_clear_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
270 | u8 irq_index, u32 status) |
271 | { |
272 | struct fsl_mc_command cmd = { 0 }; |
273 | struct dpsw_cmd_clear_irq_status *cmd_params; |
274 | |
275 | /* prepare command */ |
276 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLEAR_IRQ_STATUS, |
277 | cmd_flags, |
278 | token); |
279 | cmd_params = (struct dpsw_cmd_clear_irq_status *)cmd.params; |
280 | cmd_params->status = cpu_to_le32(status); |
281 | cmd_params->irq_index = irq_index; |
282 | |
283 | /* send command to mc*/ |
284 | return mc_send_command(mc_io, cmd: &cmd); |
285 | } |
286 | |
287 | /** |
288 | * dpsw_get_attributes() - Retrieve DPSW attributes |
289 | * @mc_io: Pointer to MC portal's I/O object |
290 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
291 | * @token: Token of DPSW object |
292 | * @attr: Returned DPSW attributes |
293 | * |
294 | * Return: Completion status. '0' on Success; Error code otherwise. |
295 | */ |
296 | int dpsw_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
297 | struct dpsw_attr *attr) |
298 | { |
299 | struct fsl_mc_command cmd = { 0 }; |
300 | struct dpsw_rsp_get_attr *rsp_params; |
301 | int err; |
302 | |
303 | /* prepare command */ |
304 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_ATTR, |
305 | cmd_flags, |
306 | token); |
307 | |
308 | /* send command to mc*/ |
309 | err = mc_send_command(mc_io, cmd: &cmd); |
310 | if (err) |
311 | return err; |
312 | |
313 | /* retrieve response parameters */ |
314 | rsp_params = (struct dpsw_rsp_get_attr *)cmd.params; |
315 | attr->num_ifs = le16_to_cpu(rsp_params->num_ifs); |
316 | attr->max_fdbs = rsp_params->max_fdbs; |
317 | attr->num_fdbs = rsp_params->num_fdbs; |
318 | attr->max_vlans = le16_to_cpu(rsp_params->max_vlans); |
319 | attr->num_vlans = le16_to_cpu(rsp_params->num_vlans); |
320 | attr->max_fdb_entries = le16_to_cpu(rsp_params->max_fdb_entries); |
321 | attr->fdb_aging_time = le16_to_cpu(rsp_params->fdb_aging_time); |
322 | attr->id = le32_to_cpu(rsp_params->dpsw_id); |
323 | attr->mem_size = le16_to_cpu(rsp_params->mem_size); |
324 | attr->max_fdb_mc_groups = le16_to_cpu(rsp_params->max_fdb_mc_groups); |
325 | attr->max_meters_per_if = rsp_params->max_meters_per_if; |
326 | attr->options = le64_to_cpu(rsp_params->options); |
327 | attr->component_type = dpsw_get_field(rsp_params->component_type, COMPONENT_TYPE); |
328 | attr->flooding_cfg = dpsw_get_field(rsp_params->repl_cfg, FLOODING_CFG); |
329 | attr->broadcast_cfg = dpsw_get_field(rsp_params->repl_cfg, BROADCAST_CFG); |
330 | return 0; |
331 | } |
332 | |
333 | /** |
334 | * dpsw_if_set_link_cfg() - Set the link configuration. |
335 | * @mc_io: Pointer to MC portal's I/O object |
336 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
337 | * @token: Token of DPSW object |
338 | * @if_id: Interface id |
339 | * @cfg: Link configuration |
340 | * |
341 | * Return: '0' on Success; Error code otherwise. |
342 | */ |
343 | int dpsw_if_set_link_cfg(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id, |
344 | struct dpsw_link_cfg *cfg) |
345 | { |
346 | struct fsl_mc_command cmd = { 0 }; |
347 | struct dpsw_cmd_if_set_link_cfg *cmd_params; |
348 | |
349 | /* prepare command */ |
350 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_LINK_CFG, |
351 | cmd_flags, |
352 | token); |
353 | cmd_params = (struct dpsw_cmd_if_set_link_cfg *)cmd.params; |
354 | cmd_params->if_id = cpu_to_le16(if_id); |
355 | cmd_params->rate = cpu_to_le32(cfg->rate); |
356 | cmd_params->options = cpu_to_le64(cfg->options); |
357 | |
358 | /* send command to mc*/ |
359 | return mc_send_command(mc_io, cmd: &cmd); |
360 | } |
361 | |
362 | /** |
363 | * dpsw_if_get_link_state - Return the link state |
364 | * @mc_io: Pointer to MC portal's I/O object |
365 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
366 | * @token: Token of DPSW object |
367 | * @if_id: Interface id |
368 | * @state: Link state 1 - linkup, 0 - link down or disconnected |
369 | * |
370 | * Return: '0' on Success; Error code otherwise. |
371 | */ |
372 | int dpsw_if_get_link_state(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
373 | u16 if_id, struct dpsw_link_state *state) |
374 | { |
375 | struct fsl_mc_command cmd = { 0 }; |
376 | struct dpsw_cmd_if_get_link_state *cmd_params; |
377 | struct dpsw_rsp_if_get_link_state *rsp_params; |
378 | int err; |
379 | |
380 | /* prepare command */ |
381 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_LINK_STATE, |
382 | cmd_flags, |
383 | token); |
384 | cmd_params = (struct dpsw_cmd_if_get_link_state *)cmd.params; |
385 | cmd_params->if_id = cpu_to_le16(if_id); |
386 | |
387 | /* send command to mc*/ |
388 | err = mc_send_command(mc_io, cmd: &cmd); |
389 | if (err) |
390 | return err; |
391 | |
392 | /* retrieve response parameters */ |
393 | rsp_params = (struct dpsw_rsp_if_get_link_state *)cmd.params; |
394 | state->rate = le32_to_cpu(rsp_params->rate); |
395 | state->options = le64_to_cpu(rsp_params->options); |
396 | state->up = dpsw_get_field(rsp_params->up, UP); |
397 | |
398 | return 0; |
399 | } |
400 | |
401 | /** |
402 | * dpsw_if_set_tci() - Set default VLAN Tag Control Information (TCI) |
403 | * @mc_io: Pointer to MC portal's I/O object |
404 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
405 | * @token: Token of DPSW object |
406 | * @if_id: Interface Identifier |
407 | * @cfg: Tag Control Information Configuration |
408 | * |
409 | * Return: Completion status. '0' on Success; Error code otherwise. |
410 | */ |
411 | int dpsw_if_set_tci(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id, |
412 | const struct dpsw_tci_cfg *cfg) |
413 | { |
414 | struct fsl_mc_command cmd = { 0 }; |
415 | struct dpsw_cmd_if_set_tci *cmd_params; |
416 | u16 tmp_conf = 0; |
417 | |
418 | /* prepare command */ |
419 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_TCI, |
420 | cmd_flags, |
421 | token); |
422 | cmd_params = (struct dpsw_cmd_if_set_tci *)cmd.params; |
423 | cmd_params->if_id = cpu_to_le16(if_id); |
424 | dpsw_set_field(tmp_conf, VLAN_ID, cfg->vlan_id); |
425 | dpsw_set_field(tmp_conf, DEI, cfg->dei); |
426 | dpsw_set_field(tmp_conf, PCP, cfg->pcp); |
427 | cmd_params->conf = cpu_to_le16(tmp_conf); |
428 | |
429 | /* send command to mc*/ |
430 | return mc_send_command(mc_io, cmd: &cmd); |
431 | } |
432 | |
433 | /** |
434 | * dpsw_if_get_tci() - Get default VLAN Tag Control Information (TCI) |
435 | * @mc_io: Pointer to MC portal's I/O object |
436 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
437 | * @token: Token of DPSW object |
438 | * @if_id: Interface Identifier |
439 | * @cfg: Tag Control Information Configuration |
440 | * |
441 | * Return: Completion status. '0' on Success; Error code otherwise. |
442 | */ |
443 | int dpsw_if_get_tci(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id, |
444 | struct dpsw_tci_cfg *cfg) |
445 | { |
446 | struct fsl_mc_command cmd = { 0 }; |
447 | struct dpsw_cmd_if_get_tci *cmd_params; |
448 | struct dpsw_rsp_if_get_tci *rsp_params; |
449 | int err; |
450 | |
451 | /* prepare command */ |
452 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_TCI, |
453 | cmd_flags, |
454 | token); |
455 | cmd_params = (struct dpsw_cmd_if_get_tci *)cmd.params; |
456 | cmd_params->if_id = cpu_to_le16(if_id); |
457 | |
458 | /* send command to mc*/ |
459 | err = mc_send_command(mc_io, cmd: &cmd); |
460 | if (err) |
461 | return err; |
462 | |
463 | /* retrieve response parameters */ |
464 | rsp_params = (struct dpsw_rsp_if_get_tci *)cmd.params; |
465 | cfg->pcp = rsp_params->pcp; |
466 | cfg->dei = rsp_params->dei; |
467 | cfg->vlan_id = le16_to_cpu(rsp_params->vlan_id); |
468 | |
469 | return 0; |
470 | } |
471 | |
472 | /** |
473 | * dpsw_if_set_stp() - Function sets Spanning Tree Protocol (STP) state. |
474 | * @mc_io: Pointer to MC portal's I/O object |
475 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
476 | * @token: Token of DPSW object |
477 | * @if_id: Interface Identifier |
478 | * @cfg: STP State configuration parameters |
479 | * |
480 | * The following STP states are supported - |
481 | * blocking, listening, learning, forwarding and disabled. |
482 | * |
483 | * Return: Completion status. '0' on Success; Error code otherwise. |
484 | */ |
485 | int dpsw_if_set_stp(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id, |
486 | const struct dpsw_stp_cfg *cfg) |
487 | { |
488 | struct fsl_mc_command cmd = { 0 }; |
489 | struct dpsw_cmd_if_set_stp *cmd_params; |
490 | |
491 | /* prepare command */ |
492 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_STP, |
493 | cmd_flags, |
494 | token); |
495 | cmd_params = (struct dpsw_cmd_if_set_stp *)cmd.params; |
496 | cmd_params->if_id = cpu_to_le16(if_id); |
497 | cmd_params->vlan_id = cpu_to_le16(cfg->vlan_id); |
498 | dpsw_set_field(cmd_params->state, STATE, cfg->state); |
499 | |
500 | /* send command to mc*/ |
501 | return mc_send_command(mc_io, cmd: &cmd); |
502 | } |
503 | |
504 | /** |
505 | * dpsw_if_get_counter() - Get specific counter of particular interface |
506 | * @mc_io: Pointer to MC portal's I/O object |
507 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
508 | * @token: Token of DPSW object |
509 | * @if_id: Interface Identifier |
510 | * @type: Counter type |
511 | * @counter: return value |
512 | * |
513 | * Return: Completion status. '0' on Success; Error code otherwise. |
514 | */ |
515 | int dpsw_if_get_counter(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
516 | u16 if_id, enum dpsw_counter type, u64 *counter) |
517 | { |
518 | struct fsl_mc_command cmd = { 0 }; |
519 | struct dpsw_cmd_if_get_counter *cmd_params; |
520 | struct dpsw_rsp_if_get_counter *rsp_params; |
521 | int err; |
522 | |
523 | /* prepare command */ |
524 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_COUNTER, |
525 | cmd_flags, |
526 | token); |
527 | cmd_params = (struct dpsw_cmd_if_get_counter *)cmd.params; |
528 | cmd_params->if_id = cpu_to_le16(if_id); |
529 | dpsw_set_field(cmd_params->type, COUNTER_TYPE, type); |
530 | |
531 | /* send command to mc*/ |
532 | err = mc_send_command(mc_io, cmd: &cmd); |
533 | if (err) |
534 | return err; |
535 | |
536 | /* retrieve response parameters */ |
537 | rsp_params = (struct dpsw_rsp_if_get_counter *)cmd.params; |
538 | *counter = le64_to_cpu(rsp_params->counter); |
539 | |
540 | return 0; |
541 | } |
542 | |
543 | /** |
544 | * dpsw_if_enable() - Enable Interface |
545 | * @mc_io: Pointer to MC portal's I/O object |
546 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
547 | * @token: Token of DPSW object |
548 | * @if_id: Interface Identifier |
549 | * |
550 | * Return: Completion status. '0' on Success; Error code otherwise. |
551 | */ |
552 | int dpsw_if_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id) |
553 | { |
554 | struct fsl_mc_command cmd = { 0 }; |
555 | struct dpsw_cmd_if *cmd_params; |
556 | |
557 | /* prepare command */ |
558 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ENABLE, |
559 | cmd_flags, |
560 | token); |
561 | cmd_params = (struct dpsw_cmd_if *)cmd.params; |
562 | cmd_params->if_id = cpu_to_le16(if_id); |
563 | |
564 | /* send command to mc*/ |
565 | return mc_send_command(mc_io, cmd: &cmd); |
566 | } |
567 | |
568 | /** |
569 | * dpsw_if_disable() - Disable Interface |
570 | * @mc_io: Pointer to MC portal's I/O object |
571 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
572 | * @token: Token of DPSW object |
573 | * @if_id: Interface Identifier |
574 | * |
575 | * Return: Completion status. '0' on Success; Error code otherwise. |
576 | */ |
577 | int dpsw_if_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id) |
578 | { |
579 | struct fsl_mc_command cmd = { 0 }; |
580 | struct dpsw_cmd_if *cmd_params; |
581 | |
582 | /* prepare command */ |
583 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_DISABLE, |
584 | cmd_flags, |
585 | token); |
586 | cmd_params = (struct dpsw_cmd_if *)cmd.params; |
587 | cmd_params->if_id = cpu_to_le16(if_id); |
588 | |
589 | /* send command to mc*/ |
590 | return mc_send_command(mc_io, cmd: &cmd); |
591 | } |
592 | |
593 | /** |
594 | * dpsw_if_get_attributes() - Function obtains attributes of interface |
595 | * @mc_io: Pointer to MC portal's I/O object |
596 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
597 | * @token: Token of DPSW object |
598 | * @if_id: Interface Identifier |
599 | * @attr: Returned interface attributes |
600 | * |
601 | * Return: Completion status. '0' on Success; Error code otherwise. |
602 | */ |
603 | int dpsw_if_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
604 | u16 if_id, struct dpsw_if_attr *attr) |
605 | { |
606 | struct dpsw_rsp_if_get_attr *rsp_params; |
607 | struct fsl_mc_command cmd = { 0 }; |
608 | struct dpsw_cmd_if *cmd_params; |
609 | int err; |
610 | |
611 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_ATTR, cmd_flags, |
612 | token); |
613 | cmd_params = (struct dpsw_cmd_if *)cmd.params; |
614 | cmd_params->if_id = cpu_to_le16(if_id); |
615 | |
616 | err = mc_send_command(mc_io, cmd: &cmd); |
617 | if (err) |
618 | return err; |
619 | |
620 | rsp_params = (struct dpsw_rsp_if_get_attr *)cmd.params; |
621 | attr->num_tcs = rsp_params->num_tcs; |
622 | attr->rate = le32_to_cpu(rsp_params->rate); |
623 | attr->options = le32_to_cpu(rsp_params->options); |
624 | attr->qdid = le16_to_cpu(rsp_params->qdid); |
625 | attr->enabled = dpsw_get_field(rsp_params->conf, ENABLED); |
626 | attr->accept_all_vlan = dpsw_get_field(rsp_params->conf, |
627 | ACCEPT_ALL_VLAN); |
628 | attr->admit_untagged = dpsw_get_field(rsp_params->conf, |
629 | ADMIT_UNTAGGED); |
630 | |
631 | return 0; |
632 | } |
633 | |
634 | /** |
635 | * dpsw_if_set_max_frame_length() - Set Maximum Receive frame length. |
636 | * @mc_io: Pointer to MC portal's I/O object |
637 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
638 | * @token: Token of DPSW object |
639 | * @if_id: Interface Identifier |
640 | * @frame_length: Maximum Frame Length |
641 | * |
642 | * Return: Completion status. '0' on Success; Error code otherwise. |
643 | */ |
644 | int dpsw_if_set_max_frame_length(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
645 | u16 if_id, u16 frame_length) |
646 | { |
647 | struct fsl_mc_command cmd = { 0 }; |
648 | struct dpsw_cmd_if_set_max_frame_length *cmd_params; |
649 | |
650 | /* prepare command */ |
651 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_MAX_FRAME_LENGTH, |
652 | cmd_flags, |
653 | token); |
654 | cmd_params = (struct dpsw_cmd_if_set_max_frame_length *)cmd.params; |
655 | cmd_params->if_id = cpu_to_le16(if_id); |
656 | cmd_params->frame_length = cpu_to_le16(frame_length); |
657 | |
658 | /* send command to mc*/ |
659 | return mc_send_command(mc_io, cmd: &cmd); |
660 | } |
661 | |
662 | /** |
663 | * dpsw_vlan_add() - Adding new VLAN to DPSW. |
664 | * @mc_io: Pointer to MC portal's I/O object |
665 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
666 | * @token: Token of DPSW object |
667 | * @vlan_id: VLAN Identifier |
668 | * @cfg: VLAN configuration |
669 | * |
670 | * Only VLAN ID and FDB ID are required parameters here. |
671 | * 12 bit VLAN ID is defined in IEEE802.1Q. |
672 | * Adding a duplicate VLAN ID is not allowed. |
673 | * FDB ID can be shared across multiple VLANs. Shared learning |
674 | * is obtained by calling dpsw_vlan_add for multiple VLAN IDs |
675 | * with same fdb_id |
676 | * |
677 | * Return: Completion status. '0' on Success; Error code otherwise. |
678 | */ |
679 | int dpsw_vlan_add(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
680 | u16 vlan_id, const struct dpsw_vlan_cfg *cfg) |
681 | { |
682 | struct fsl_mc_command cmd = { 0 }; |
683 | struct dpsw_vlan_add *cmd_params; |
684 | |
685 | /* prepare command */ |
686 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD, |
687 | cmd_flags, |
688 | token); |
689 | cmd_params = (struct dpsw_vlan_add *)cmd.params; |
690 | cmd_params->fdb_id = cpu_to_le16(cfg->fdb_id); |
691 | cmd_params->vlan_id = cpu_to_le16(vlan_id); |
692 | |
693 | /* send command to mc*/ |
694 | return mc_send_command(mc_io, cmd: &cmd); |
695 | } |
696 | |
697 | /** |
698 | * dpsw_vlan_add_if() - Adding a set of interfaces to an existing VLAN. |
699 | * @mc_io: Pointer to MC portal's I/O object |
700 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
701 | * @token: Token of DPSW object |
702 | * @vlan_id: VLAN Identifier |
703 | * @cfg: Set of interfaces to add |
704 | * |
705 | * It adds only interfaces not belonging to this VLAN yet, |
706 | * otherwise an error is generated and an entire command is |
707 | * ignored. This function can be called numerous times always |
708 | * providing required interfaces delta. |
709 | * |
710 | * Return: Completion status. '0' on Success; Error code otherwise. |
711 | */ |
712 | int dpsw_vlan_add_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
713 | u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg) |
714 | { |
715 | struct dpsw_cmd_vlan_add_if *cmd_params; |
716 | struct fsl_mc_command cmd = { 0 }; |
717 | |
718 | /* prepare command */ |
719 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF, |
720 | cmd_flags, |
721 | token); |
722 | cmd_params = (struct dpsw_cmd_vlan_add_if *)cmd.params; |
723 | cmd_params->vlan_id = cpu_to_le16(vlan_id); |
724 | cmd_params->options = cpu_to_le16(cfg->options); |
725 | cmd_params->fdb_id = cpu_to_le16(cfg->fdb_id); |
726 | build_if_id_bitmap(bmap: &cmd_params->if_id, id: cfg->if_id, num_ifs: cfg->num_ifs); |
727 | |
728 | /* send command to mc*/ |
729 | return mc_send_command(mc_io, cmd: &cmd); |
730 | } |
731 | |
732 | /** |
733 | * dpsw_vlan_add_if_untagged() - Defining a set of interfaces that should be |
734 | * transmitted as untagged. |
735 | * @mc_io: Pointer to MC portal's I/O object |
736 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
737 | * @token: Token of DPSW object |
738 | * @vlan_id: VLAN Identifier |
739 | * @cfg: Set of interfaces that should be transmitted as untagged |
740 | * |
741 | * These interfaces should already belong to this VLAN. |
742 | * By default all interfaces are transmitted as tagged. |
743 | * Providing un-existing interface or untagged interface that is |
744 | * configured untagged already generates an error and the entire |
745 | * command is ignored. |
746 | * |
747 | * Return: Completion status. '0' on Success; Error code otherwise. |
748 | */ |
749 | int dpsw_vlan_add_if_untagged(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
750 | u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg) |
751 | { |
752 | struct fsl_mc_command cmd = { 0 }; |
753 | struct dpsw_cmd_vlan_manage_if *cmd_params; |
754 | |
755 | /* prepare command */ |
756 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF_UNTAGGED, |
757 | cmd_flags, |
758 | token); |
759 | cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params; |
760 | cmd_params->vlan_id = cpu_to_le16(vlan_id); |
761 | build_if_id_bitmap(bmap: &cmd_params->if_id, id: cfg->if_id, num_ifs: cfg->num_ifs); |
762 | |
763 | /* send command to mc*/ |
764 | return mc_send_command(mc_io, cmd: &cmd); |
765 | } |
766 | |
767 | /** |
768 | * dpsw_vlan_remove_if() - Remove interfaces from an existing VLAN. |
769 | * @mc_io: Pointer to MC portal's I/O object |
770 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
771 | * @token: Token of DPSW object |
772 | * @vlan_id: VLAN Identifier |
773 | * @cfg: Set of interfaces that should be removed |
774 | * |
775 | * Interfaces must belong to this VLAN, otherwise an error |
776 | * is returned and an the command is ignored |
777 | * |
778 | * Return: Completion status. '0' on Success; Error code otherwise. |
779 | */ |
780 | int dpsw_vlan_remove_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
781 | u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg) |
782 | { |
783 | struct fsl_mc_command cmd = { 0 }; |
784 | struct dpsw_cmd_vlan_manage_if *cmd_params; |
785 | |
786 | /* prepare command */ |
787 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF, |
788 | cmd_flags, |
789 | token); |
790 | cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params; |
791 | cmd_params->vlan_id = cpu_to_le16(vlan_id); |
792 | build_if_id_bitmap(bmap: &cmd_params->if_id, id: cfg->if_id, num_ifs: cfg->num_ifs); |
793 | |
794 | /* send command to mc*/ |
795 | return mc_send_command(mc_io, cmd: &cmd); |
796 | } |
797 | |
798 | /** |
799 | * dpsw_vlan_remove_if_untagged() - Define a set of interfaces that should be |
800 | * converted from transmitted as untagged to transmit as tagged. |
801 | * @mc_io: Pointer to MC portal's I/O object |
802 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
803 | * @token: Token of DPSW object |
804 | * @vlan_id: VLAN Identifier |
805 | * @cfg: Set of interfaces that should be removed |
806 | * |
807 | * Interfaces provided by API have to belong to this VLAN and |
808 | * configured untagged, otherwise an error is returned and the |
809 | * command is ignored |
810 | * |
811 | * Return: Completion status. '0' on Success; Error code otherwise. |
812 | */ |
813 | int dpsw_vlan_remove_if_untagged(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
814 | u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg) |
815 | { |
816 | struct fsl_mc_command cmd = { 0 }; |
817 | struct dpsw_cmd_vlan_manage_if *cmd_params; |
818 | |
819 | /* prepare command */ |
820 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF_UNTAGGED, |
821 | cmd_flags, |
822 | token); |
823 | cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params; |
824 | cmd_params->vlan_id = cpu_to_le16(vlan_id); |
825 | build_if_id_bitmap(bmap: &cmd_params->if_id, id: cfg->if_id, num_ifs: cfg->num_ifs); |
826 | |
827 | /* send command to mc*/ |
828 | return mc_send_command(mc_io, cmd: &cmd); |
829 | } |
830 | |
831 | /** |
832 | * dpsw_vlan_remove() - Remove an entire VLAN |
833 | * @mc_io: Pointer to MC portal's I/O object |
834 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
835 | * @token: Token of DPSW object |
836 | * @vlan_id: VLAN Identifier |
837 | * |
838 | * Return: Completion status. '0' on Success; Error code otherwise. |
839 | */ |
840 | int dpsw_vlan_remove(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
841 | u16 vlan_id) |
842 | { |
843 | struct fsl_mc_command cmd = { 0 }; |
844 | struct dpsw_cmd_vlan_remove *cmd_params; |
845 | |
846 | /* prepare command */ |
847 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE, |
848 | cmd_flags, |
849 | token); |
850 | cmd_params = (struct dpsw_cmd_vlan_remove *)cmd.params; |
851 | cmd_params->vlan_id = cpu_to_le16(vlan_id); |
852 | |
853 | /* send command to mc*/ |
854 | return mc_send_command(mc_io, cmd: &cmd); |
855 | } |
856 | |
857 | /** |
858 | * dpsw_fdb_add() - Add FDB to switch and Returns handle to FDB table for |
859 | * the reference |
860 | * @mc_io: Pointer to MC portal's I/O object |
861 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
862 | * @token: Token of DPSW object |
863 | * @fdb_id: Returned Forwarding Database Identifier |
864 | * @cfg: FDB Configuration |
865 | * |
866 | * Return: Completion status. '0' on Success; Error code otherwise. |
867 | */ |
868 | int dpsw_fdb_add(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 *fdb_id, |
869 | const struct dpsw_fdb_cfg *cfg) |
870 | { |
871 | struct dpsw_cmd_fdb_add *cmd_params; |
872 | struct dpsw_rsp_fdb_add *rsp_params; |
873 | struct fsl_mc_command cmd = { 0 }; |
874 | int err; |
875 | |
876 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD, |
877 | cmd_flags, |
878 | token); |
879 | cmd_params = (struct dpsw_cmd_fdb_add *)cmd.params; |
880 | cmd_params->fdb_ageing_time = cpu_to_le16(cfg->fdb_ageing_time); |
881 | cmd_params->num_fdb_entries = cpu_to_le16(cfg->num_fdb_entries); |
882 | |
883 | err = mc_send_command(mc_io, cmd: &cmd); |
884 | if (err) |
885 | return err; |
886 | |
887 | rsp_params = (struct dpsw_rsp_fdb_add *)cmd.params; |
888 | *fdb_id = le16_to_cpu(rsp_params->fdb_id); |
889 | |
890 | return 0; |
891 | } |
892 | |
893 | /** |
894 | * dpsw_fdb_remove() - Remove FDB from switch |
895 | * @mc_io: Pointer to MC portal's I/O object |
896 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
897 | * @token: Token of DPSW object |
898 | * @fdb_id: Forwarding Database Identifier |
899 | * |
900 | * Return: Completion status. '0' on Success; Error code otherwise. |
901 | */ |
902 | int dpsw_fdb_remove(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 fdb_id) |
903 | { |
904 | struct dpsw_cmd_fdb_remove *cmd_params; |
905 | struct fsl_mc_command cmd = { 0 }; |
906 | |
907 | /* prepare command */ |
908 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE, |
909 | cmd_flags, |
910 | token); |
911 | cmd_params = (struct dpsw_cmd_fdb_remove *)cmd.params; |
912 | cmd_params->fdb_id = cpu_to_le16(fdb_id); |
913 | |
914 | return mc_send_command(mc_io, cmd: &cmd); |
915 | } |
916 | |
917 | /** |
918 | * dpsw_fdb_add_unicast() - Function adds an unicast entry into MAC lookup table |
919 | * @mc_io: Pointer to MC portal's I/O object |
920 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
921 | * @token: Token of DPSW object |
922 | * @fdb_id: Forwarding Database Identifier |
923 | * @cfg: Unicast entry configuration |
924 | * |
925 | * Return: Completion status. '0' on Success; Error code otherwise. |
926 | */ |
927 | int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
928 | u16 fdb_id, const struct dpsw_fdb_unicast_cfg *cfg) |
929 | { |
930 | struct fsl_mc_command cmd = { 0 }; |
931 | struct dpsw_cmd_fdb_unicast_op *cmd_params; |
932 | int i; |
933 | |
934 | /* prepare command */ |
935 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_UNICAST, |
936 | cmd_flags, |
937 | token); |
938 | cmd_params = (struct dpsw_cmd_fdb_unicast_op *)cmd.params; |
939 | cmd_params->fdb_id = cpu_to_le16(fdb_id); |
940 | cmd_params->if_egress = cpu_to_le16(cfg->if_egress); |
941 | for (i = 0; i < 6; i++) |
942 | cmd_params->mac_addr[i] = cfg->mac_addr[5 - i]; |
943 | dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type); |
944 | |
945 | /* send command to mc*/ |
946 | return mc_send_command(mc_io, cmd: &cmd); |
947 | } |
948 | |
949 | /** |
950 | * dpsw_fdb_dump() - Dump the content of FDB table into memory. |
951 | * @mc_io: Pointer to MC portal's I/O object |
952 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
953 | * @token: Token of DPSW object |
954 | * @fdb_id: Forwarding Database Identifier |
955 | * @iova_addr: Data will be stored here as an array of struct fdb_dump_entry |
956 | * @iova_size: Memory size allocated at iova_addr |
957 | * @num_entries:Number of entries written at iova_addr |
958 | * |
959 | * Return: Completion status. '0' on Success; Error code otherwise. |
960 | * |
961 | * The memory allocated at iova_addr must be initialized with zero before |
962 | * command execution. If the FDB table does not fit into memory MC will stop |
963 | * after the memory is filled up. |
964 | * The struct fdb_dump_entry array must be parsed until the end of memory |
965 | * area or until an entry with mac_addr set to zero is found. |
966 | */ |
967 | int dpsw_fdb_dump(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 fdb_id, |
968 | u64 iova_addr, u32 iova_size, u16 *num_entries) |
969 | { |
970 | struct dpsw_cmd_fdb_dump *cmd_params; |
971 | struct dpsw_rsp_fdb_dump *rsp_params; |
972 | struct fsl_mc_command cmd = { 0 }; |
973 | int err; |
974 | |
975 | /* prepare command */ |
976 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_DUMP, |
977 | cmd_flags, |
978 | token); |
979 | cmd_params = (struct dpsw_cmd_fdb_dump *)cmd.params; |
980 | cmd_params->fdb_id = cpu_to_le16(fdb_id); |
981 | cmd_params->iova_addr = cpu_to_le64(iova_addr); |
982 | cmd_params->iova_size = cpu_to_le32(iova_size); |
983 | |
984 | /* send command to mc */ |
985 | err = mc_send_command(mc_io, cmd: &cmd); |
986 | if (err) |
987 | return err; |
988 | |
989 | rsp_params = (struct dpsw_rsp_fdb_dump *)cmd.params; |
990 | *num_entries = le16_to_cpu(rsp_params->num_entries); |
991 | |
992 | return 0; |
993 | } |
994 | |
995 | /** |
996 | * dpsw_fdb_remove_unicast() - removes an entry from MAC lookup table |
997 | * @mc_io: Pointer to MC portal's I/O object |
998 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
999 | * @token: Token of DPSW object |
1000 | * @fdb_id: Forwarding Database Identifier |
1001 | * @cfg: Unicast entry configuration |
1002 | * |
1003 | * Return: Completion status. '0' on Success; Error code otherwise. |
1004 | */ |
1005 | int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1006 | u16 fdb_id, const struct dpsw_fdb_unicast_cfg *cfg) |
1007 | { |
1008 | struct fsl_mc_command cmd = { 0 }; |
1009 | struct dpsw_cmd_fdb_unicast_op *cmd_params; |
1010 | int i; |
1011 | |
1012 | /* prepare command */ |
1013 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_UNICAST, |
1014 | cmd_flags, |
1015 | token); |
1016 | cmd_params = (struct dpsw_cmd_fdb_unicast_op *)cmd.params; |
1017 | cmd_params->fdb_id = cpu_to_le16(fdb_id); |
1018 | for (i = 0; i < 6; i++) |
1019 | cmd_params->mac_addr[i] = cfg->mac_addr[5 - i]; |
1020 | cmd_params->if_egress = cpu_to_le16(cfg->if_egress); |
1021 | dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type); |
1022 | |
1023 | /* send command to mc*/ |
1024 | return mc_send_command(mc_io, cmd: &cmd); |
1025 | } |
1026 | |
1027 | /** |
1028 | * dpsw_fdb_add_multicast() - Add a set of egress interfaces to multi-cast group |
1029 | * @mc_io: Pointer to MC portal's I/O object |
1030 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1031 | * @token: Token of DPSW object |
1032 | * @fdb_id: Forwarding Database Identifier |
1033 | * @cfg: Multicast entry configuration |
1034 | * |
1035 | * If group doesn't exist, it will be created. |
1036 | * It adds only interfaces not belonging to this multicast group |
1037 | * yet, otherwise error will be generated and the command is |
1038 | * ignored. |
1039 | * This function may be called numerous times always providing |
1040 | * required interfaces delta. |
1041 | * |
1042 | * Return: Completion status. '0' on Success; Error code otherwise. |
1043 | */ |
1044 | int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1045 | u16 fdb_id, const struct dpsw_fdb_multicast_cfg *cfg) |
1046 | { |
1047 | struct fsl_mc_command cmd = { 0 }; |
1048 | struct dpsw_cmd_fdb_multicast_op *cmd_params; |
1049 | int i; |
1050 | |
1051 | /* prepare command */ |
1052 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_MULTICAST, |
1053 | cmd_flags, |
1054 | token); |
1055 | cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params; |
1056 | cmd_params->fdb_id = cpu_to_le16(fdb_id); |
1057 | cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs); |
1058 | dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type); |
1059 | build_if_id_bitmap(bmap: &cmd_params->if_id, id: cfg->if_id, num_ifs: cfg->num_ifs); |
1060 | for (i = 0; i < 6; i++) |
1061 | cmd_params->mac_addr[i] = cfg->mac_addr[5 - i]; |
1062 | |
1063 | /* send command to mc*/ |
1064 | return mc_send_command(mc_io, cmd: &cmd); |
1065 | } |
1066 | |
1067 | /** |
1068 | * dpsw_fdb_remove_multicast() - Removing interfaces from an existing multicast |
1069 | * group. |
1070 | * @mc_io: Pointer to MC portal's I/O object |
1071 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1072 | * @token: Token of DPSW object |
1073 | * @fdb_id: Forwarding Database Identifier |
1074 | * @cfg: Multicast entry configuration |
1075 | * |
1076 | * Interfaces provided by this API have to exist in the group, |
1077 | * otherwise an error will be returned and an entire command |
1078 | * ignored. If there is no interface left in the group, |
1079 | * an entire group is deleted |
1080 | * |
1081 | * Return: Completion status. '0' on Success; Error code otherwise. |
1082 | */ |
1083 | int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1084 | u16 fdb_id, const struct dpsw_fdb_multicast_cfg *cfg) |
1085 | { |
1086 | struct fsl_mc_command cmd = { 0 }; |
1087 | struct dpsw_cmd_fdb_multicast_op *cmd_params; |
1088 | int i; |
1089 | |
1090 | /* prepare command */ |
1091 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_MULTICAST, |
1092 | cmd_flags, |
1093 | token); |
1094 | cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params; |
1095 | cmd_params->fdb_id = cpu_to_le16(fdb_id); |
1096 | cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs); |
1097 | dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type); |
1098 | build_if_id_bitmap(bmap: &cmd_params->if_id, id: cfg->if_id, num_ifs: cfg->num_ifs); |
1099 | for (i = 0; i < 6; i++) |
1100 | cmd_params->mac_addr[i] = cfg->mac_addr[5 - i]; |
1101 | |
1102 | /* send command to mc*/ |
1103 | return mc_send_command(mc_io, cmd: &cmd); |
1104 | } |
1105 | |
1106 | /** |
1107 | * dpsw_ctrl_if_get_attributes() - Obtain control interface attributes |
1108 | * @mc_io: Pointer to MC portal's I/O object |
1109 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1110 | * @token: Token of DPSW object |
1111 | * @attr: Returned control interface attributes |
1112 | * |
1113 | * Return: '0' on Success; Error code otherwise. |
1114 | */ |
1115 | int dpsw_ctrl_if_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, |
1116 | u16 token, struct dpsw_ctrl_if_attr *attr) |
1117 | { |
1118 | struct dpsw_rsp_ctrl_if_get_attr *rsp_params; |
1119 | struct fsl_mc_command cmd = { 0 }; |
1120 | int err; |
1121 | |
1122 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_GET_ATTR, |
1123 | cmd_flags, token); |
1124 | |
1125 | err = mc_send_command(mc_io, cmd: &cmd); |
1126 | if (err) |
1127 | return err; |
1128 | |
1129 | rsp_params = (struct dpsw_rsp_ctrl_if_get_attr *)cmd.params; |
1130 | attr->rx_fqid = le32_to_cpu(rsp_params->rx_fqid); |
1131 | attr->rx_err_fqid = le32_to_cpu(rsp_params->rx_err_fqid); |
1132 | attr->tx_err_conf_fqid = le32_to_cpu(rsp_params->tx_err_conf_fqid); |
1133 | |
1134 | return 0; |
1135 | } |
1136 | |
1137 | /** |
1138 | * dpsw_ctrl_if_set_pools() - Set control interface buffer pools |
1139 | * @mc_io: Pointer to MC portal's I/O object |
1140 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1141 | * @token: Token of DPSW object |
1142 | * @cfg: Buffer pools configuration |
1143 | * |
1144 | * Return: '0' on Success; Error code otherwise. |
1145 | */ |
1146 | int dpsw_ctrl_if_set_pools(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1147 | const struct dpsw_ctrl_if_pools_cfg *cfg) |
1148 | { |
1149 | struct dpsw_cmd_ctrl_if_set_pools *cmd_params; |
1150 | struct fsl_mc_command cmd = { 0 }; |
1151 | int i; |
1152 | |
1153 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_SET_POOLS, |
1154 | cmd_flags, token); |
1155 | cmd_params = (struct dpsw_cmd_ctrl_if_set_pools *)cmd.params; |
1156 | cmd_params->num_dpbp = cfg->num_dpbp; |
1157 | for (i = 0; i < DPSW_MAX_DPBP; i++) { |
1158 | cmd_params->dpbp_id[i] = cpu_to_le32(cfg->pools[i].dpbp_id); |
1159 | cmd_params->buffer_size[i] = |
1160 | cpu_to_le16(cfg->pools[i].buffer_size); |
1161 | cmd_params->backup_pool_mask |= |
1162 | DPSW_BACKUP_POOL(cfg->pools[i].backup_pool, i); |
1163 | } |
1164 | |
1165 | return mc_send_command(mc_io, cmd: &cmd); |
1166 | } |
1167 | |
1168 | /** |
1169 | * dpsw_ctrl_if_set_queue() - Set Rx queue configuration |
1170 | * @mc_io: Pointer to MC portal's I/O object |
1171 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1172 | * @token: Token of dpsw object |
1173 | * @qtype: dpsw_queue_type of the targeted queue |
1174 | * @cfg: Rx queue configuration |
1175 | * |
1176 | * Return: '0' on Success; Error code otherwise. |
1177 | */ |
1178 | int dpsw_ctrl_if_set_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1179 | enum dpsw_queue_type qtype, |
1180 | const struct dpsw_ctrl_if_queue_cfg *cfg) |
1181 | { |
1182 | struct dpsw_cmd_ctrl_if_set_queue *cmd_params; |
1183 | struct fsl_mc_command cmd = { 0 }; |
1184 | |
1185 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_SET_QUEUE, |
1186 | cmd_flags, |
1187 | token); |
1188 | cmd_params = (struct dpsw_cmd_ctrl_if_set_queue *)cmd.params; |
1189 | cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id); |
1190 | cmd_params->dest_priority = cfg->dest_cfg.priority; |
1191 | cmd_params->qtype = qtype; |
1192 | cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx); |
1193 | cmd_params->options = cpu_to_le32(cfg->options); |
1194 | dpsw_set_field(cmd_params->dest_type, |
1195 | DEST_TYPE, |
1196 | cfg->dest_cfg.dest_type); |
1197 | |
1198 | return mc_send_command(mc_io, cmd: &cmd); |
1199 | } |
1200 | |
1201 | /** |
1202 | * dpsw_get_api_version() - Get Data Path Switch API version |
1203 | * @mc_io: Pointer to MC portal's I/O object |
1204 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1205 | * @major_ver: Major version of data path switch API |
1206 | * @minor_ver: Minor version of data path switch API |
1207 | * |
1208 | * Return: '0' on Success; Error code otherwise. |
1209 | */ |
1210 | int dpsw_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags, |
1211 | u16 *major_ver, u16 *minor_ver) |
1212 | { |
1213 | struct fsl_mc_command cmd = { 0 }; |
1214 | struct dpsw_rsp_get_api_version *rsp_params; |
1215 | int err; |
1216 | |
1217 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_API_VERSION, |
1218 | cmd_flags, |
1219 | token: 0); |
1220 | |
1221 | err = mc_send_command(mc_io, cmd: &cmd); |
1222 | if (err) |
1223 | return err; |
1224 | |
1225 | rsp_params = (struct dpsw_rsp_get_api_version *)cmd.params; |
1226 | *major_ver = le16_to_cpu(rsp_params->version_major); |
1227 | *minor_ver = le16_to_cpu(rsp_params->version_minor); |
1228 | |
1229 | return 0; |
1230 | } |
1231 | |
1232 | /** |
1233 | * dpsw_if_get_port_mac_addr() - Retrieve MAC address associated to the physical port |
1234 | * @mc_io: Pointer to MC portal's I/O object |
1235 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1236 | * @token: Token of DPSW object |
1237 | * @if_id: Interface Identifier |
1238 | * @mac_addr: MAC address of the physical port, if any, otherwise 0 |
1239 | * |
1240 | * Return: Completion status. '0' on Success; Error code otherwise. |
1241 | */ |
1242 | int dpsw_if_get_port_mac_addr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1243 | u16 if_id, u8 mac_addr[6]) |
1244 | { |
1245 | struct dpsw_rsp_if_get_mac_addr *rsp_params; |
1246 | struct fsl_mc_command cmd = { 0 }; |
1247 | struct dpsw_cmd_if *cmd_params; |
1248 | int err, i; |
1249 | |
1250 | /* prepare command */ |
1251 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_PORT_MAC_ADDR, |
1252 | cmd_flags, |
1253 | token); |
1254 | cmd_params = (struct dpsw_cmd_if *)cmd.params; |
1255 | cmd_params->if_id = cpu_to_le16(if_id); |
1256 | |
1257 | /* send command to mc*/ |
1258 | err = mc_send_command(mc_io, cmd: &cmd); |
1259 | if (err) |
1260 | return err; |
1261 | |
1262 | /* retrieve response parameters */ |
1263 | rsp_params = (struct dpsw_rsp_if_get_mac_addr *)cmd.params; |
1264 | for (i = 0; i < 6; i++) |
1265 | mac_addr[5 - i] = rsp_params->mac_addr[i]; |
1266 | |
1267 | return 0; |
1268 | } |
1269 | |
1270 | /** |
1271 | * dpsw_ctrl_if_enable() - Enable control interface |
1272 | * @mc_io: Pointer to MC portal's I/O object |
1273 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1274 | * @token: Token of DPSW object |
1275 | * |
1276 | * Return: '0' on Success; Error code otherwise. |
1277 | */ |
1278 | int dpsw_ctrl_if_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) |
1279 | { |
1280 | struct fsl_mc_command cmd = { 0 }; |
1281 | |
1282 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_ENABLE, cmd_flags, |
1283 | token); |
1284 | |
1285 | return mc_send_command(mc_io, cmd: &cmd); |
1286 | } |
1287 | |
1288 | /** |
1289 | * dpsw_ctrl_if_disable() - Function disables control interface |
1290 | * @mc_io: Pointer to MC portal's I/O object |
1291 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1292 | * @token: Token of DPSW object |
1293 | * |
1294 | * Return: '0' on Success; Error code otherwise. |
1295 | */ |
1296 | int dpsw_ctrl_if_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) |
1297 | { |
1298 | struct fsl_mc_command cmd = { 0 }; |
1299 | |
1300 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_DISABLE, |
1301 | cmd_flags, |
1302 | token); |
1303 | |
1304 | return mc_send_command(mc_io, cmd: &cmd); |
1305 | } |
1306 | |
1307 | /** |
1308 | * dpsw_set_egress_flood() - Set egress parameters associated with an FDB ID |
1309 | * @mc_io: Pointer to MC portal's I/O object |
1310 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1311 | * @token: Token of DPSW object |
1312 | * @cfg: Egress flooding configuration |
1313 | * |
1314 | * Return: '0' on Success; Error code otherwise. |
1315 | */ |
1316 | int dpsw_set_egress_flood(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1317 | const struct dpsw_egress_flood_cfg *cfg) |
1318 | { |
1319 | struct dpsw_cmd_set_egress_flood *cmd_params; |
1320 | struct fsl_mc_command cmd = { 0 }; |
1321 | |
1322 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_EGRESS_FLOOD, cmd_flags, token); |
1323 | cmd_params = (struct dpsw_cmd_set_egress_flood *)cmd.params; |
1324 | cmd_params->fdb_id = cpu_to_le16(cfg->fdb_id); |
1325 | cmd_params->flood_type = cfg->flood_type; |
1326 | build_if_id_bitmap(bmap: &cmd_params->if_id, id: cfg->if_id, num_ifs: cfg->num_ifs); |
1327 | |
1328 | return mc_send_command(mc_io, cmd: &cmd); |
1329 | } |
1330 | |
1331 | /** |
1332 | * dpsw_if_set_learning_mode() - Configure the learning mode on an interface. |
1333 | * If this API is used, it will take precedence over the FDB configuration. |
1334 | * @mc_io: Pointer to MC portal's I/O object |
1335 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1336 | * @token: Token of DPSW object |
1337 | * @if_id: InterfaceID |
1338 | * @mode: Learning mode |
1339 | * |
1340 | * Return: Completion status. '0' on Success; Error code otherwise. |
1341 | */ |
1342 | int dpsw_if_set_learning_mode(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1343 | u16 if_id, enum dpsw_learning_mode mode) |
1344 | { |
1345 | struct dpsw_cmd_if_set_learning_mode *cmd_params; |
1346 | struct fsl_mc_command cmd = { 0 }; |
1347 | |
1348 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_LEARNING_MODE, |
1349 | cmd_flags, |
1350 | token); |
1351 | cmd_params = (struct dpsw_cmd_if_set_learning_mode *)cmd.params; |
1352 | cmd_params->if_id = cpu_to_le16(if_id); |
1353 | dpsw_set_field(cmd_params->mode, LEARNING_MODE, mode); |
1354 | |
1355 | return mc_send_command(mc_io, cmd: &cmd); |
1356 | } |
1357 | |
1358 | /** |
1359 | * dpsw_acl_add() - Create an ACL table |
1360 | * @mc_io: Pointer to MC portal's I/O object |
1361 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1362 | * @token: Token of DPSW object |
1363 | * @acl_id: Returned ACL ID, for future references |
1364 | * @cfg: ACL configuration |
1365 | * |
1366 | * Create Access Control List table. Multiple ACLs can be created and |
1367 | * co-exist in L2 switch |
1368 | * |
1369 | * Return: '0' on Success; Error code otherwise. |
1370 | */ |
1371 | int dpsw_acl_add(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 *acl_id, |
1372 | const struct dpsw_acl_cfg *cfg) |
1373 | { |
1374 | struct dpsw_cmd_acl_add *cmd_params; |
1375 | struct dpsw_rsp_acl_add *rsp_params; |
1376 | struct fsl_mc_command cmd = { 0 }; |
1377 | int err; |
1378 | |
1379 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD, cmd_flags, token); |
1380 | cmd_params = (struct dpsw_cmd_acl_add *)cmd.params; |
1381 | cmd_params->max_entries = cpu_to_le16(cfg->max_entries); |
1382 | |
1383 | err = mc_send_command(mc_io, cmd: &cmd); |
1384 | if (err) |
1385 | return err; |
1386 | |
1387 | rsp_params = (struct dpsw_rsp_acl_add *)cmd.params; |
1388 | *acl_id = le16_to_cpu(rsp_params->acl_id); |
1389 | |
1390 | return 0; |
1391 | } |
1392 | |
1393 | /** |
1394 | * dpsw_acl_remove() - Remove an ACL table from L2 switch. |
1395 | * @mc_io: Pointer to MC portal's I/O object |
1396 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1397 | * @token: Token of DPSW object |
1398 | * @acl_id: ACL ID |
1399 | * |
1400 | * Return: '0' on Success; Error code otherwise. |
1401 | */ |
1402 | int dpsw_acl_remove(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1403 | u16 acl_id) |
1404 | { |
1405 | struct dpsw_cmd_acl_remove *cmd_params; |
1406 | struct fsl_mc_command cmd = { 0 }; |
1407 | |
1408 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE, cmd_flags, |
1409 | token); |
1410 | cmd_params = (struct dpsw_cmd_acl_remove *)cmd.params; |
1411 | cmd_params->acl_id = cpu_to_le16(acl_id); |
1412 | |
1413 | return mc_send_command(mc_io, cmd: &cmd); |
1414 | } |
1415 | |
1416 | /** |
1417 | * dpsw_acl_add_if() - Associate interface/interfaces with an ACL table. |
1418 | * @mc_io: Pointer to MC portal's I/O object |
1419 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1420 | * @token: Token of DPSW object |
1421 | * @acl_id: ACL ID |
1422 | * @cfg: Interfaces list |
1423 | * |
1424 | * Return: '0' on Success; Error code otherwise. |
1425 | */ |
1426 | int dpsw_acl_add_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1427 | u16 acl_id, const struct dpsw_acl_if_cfg *cfg) |
1428 | { |
1429 | struct dpsw_cmd_acl_if *cmd_params; |
1430 | struct fsl_mc_command cmd = { 0 }; |
1431 | |
1432 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD_IF, cmd_flags, |
1433 | token); |
1434 | cmd_params = (struct dpsw_cmd_acl_if *)cmd.params; |
1435 | cmd_params->acl_id = cpu_to_le16(acl_id); |
1436 | cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs); |
1437 | build_if_id_bitmap(bmap: &cmd_params->if_id, id: cfg->if_id, num_ifs: cfg->num_ifs); |
1438 | |
1439 | return mc_send_command(mc_io, cmd: &cmd); |
1440 | } |
1441 | |
1442 | /** |
1443 | * dpsw_acl_remove_if() - De-associate interface/interfaces from an ACL table |
1444 | * @mc_io: Pointer to MC portal's I/O object |
1445 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1446 | * @token: Token of DPSW object |
1447 | * @acl_id: ACL ID |
1448 | * @cfg: Interfaces list |
1449 | * |
1450 | * Return: '0' on Success; Error code otherwise. |
1451 | */ |
1452 | int dpsw_acl_remove_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1453 | u16 acl_id, const struct dpsw_acl_if_cfg *cfg) |
1454 | { |
1455 | struct dpsw_cmd_acl_if *cmd_params; |
1456 | struct fsl_mc_command cmd = { 0 }; |
1457 | |
1458 | /* prepare command */ |
1459 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_IF, cmd_flags, |
1460 | token); |
1461 | cmd_params = (struct dpsw_cmd_acl_if *)cmd.params; |
1462 | cmd_params->acl_id = cpu_to_le16(acl_id); |
1463 | cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs); |
1464 | build_if_id_bitmap(bmap: &cmd_params->if_id, id: cfg->if_id, num_ifs: cfg->num_ifs); |
1465 | |
1466 | /* send command to mc*/ |
1467 | return mc_send_command(mc_io, cmd: &cmd); |
1468 | } |
1469 | |
1470 | /** |
1471 | * dpsw_acl_prepare_entry_cfg() - Setup an ACL entry |
1472 | * @key: Key |
1473 | * @entry_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA |
1474 | * |
1475 | * This function has to be called before adding or removing acl_entry |
1476 | * |
1477 | */ |
1478 | void dpsw_acl_prepare_entry_cfg(const struct dpsw_acl_key *key, |
1479 | u8 *entry_cfg_buf) |
1480 | { |
1481 | struct dpsw_prep_acl_entry *ext_params; |
1482 | int i; |
1483 | |
1484 | ext_params = (struct dpsw_prep_acl_entry *)entry_cfg_buf; |
1485 | |
1486 | for (i = 0; i < 6; i++) { |
1487 | ext_params->match_l2_dest_mac[i] = key->match.l2_dest_mac[5 - i]; |
1488 | ext_params->match_l2_source_mac[i] = key->match.l2_source_mac[5 - i]; |
1489 | ext_params->mask_l2_dest_mac[i] = key->mask.l2_dest_mac[5 - i]; |
1490 | ext_params->mask_l2_source_mac[i] = key->mask.l2_source_mac[5 - i]; |
1491 | } |
1492 | |
1493 | ext_params->match_l2_tpid = cpu_to_le16(key->match.l2_tpid); |
1494 | ext_params->match_l2_vlan_id = cpu_to_le16(key->match.l2_vlan_id); |
1495 | ext_params->match_l3_dest_ip = cpu_to_le32(key->match.l3_dest_ip); |
1496 | ext_params->match_l3_source_ip = cpu_to_le32(key->match.l3_source_ip); |
1497 | ext_params->match_l4_dest_port = cpu_to_le16(key->match.l4_dest_port); |
1498 | ext_params->match_l4_source_port = cpu_to_le16(key->match.l4_source_port); |
1499 | ext_params->match_l2_ether_type = cpu_to_le16(key->match.l2_ether_type); |
1500 | ext_params->match_l2_pcp_dei = key->match.l2_pcp_dei; |
1501 | ext_params->match_l3_dscp = key->match.l3_dscp; |
1502 | |
1503 | ext_params->mask_l2_tpid = cpu_to_le16(key->mask.l2_tpid); |
1504 | ext_params->mask_l2_vlan_id = cpu_to_le16(key->mask.l2_vlan_id); |
1505 | ext_params->mask_l3_dest_ip = cpu_to_le32(key->mask.l3_dest_ip); |
1506 | ext_params->mask_l3_source_ip = cpu_to_le32(key->mask.l3_source_ip); |
1507 | ext_params->mask_l4_dest_port = cpu_to_le16(key->mask.l4_dest_port); |
1508 | ext_params->mask_l4_source_port = cpu_to_le16(key->mask.l4_source_port); |
1509 | ext_params->mask_l2_ether_type = cpu_to_le16(key->mask.l2_ether_type); |
1510 | ext_params->mask_l2_pcp_dei = key->mask.l2_pcp_dei; |
1511 | ext_params->mask_l3_dscp = key->mask.l3_dscp; |
1512 | ext_params->match_l3_protocol = key->match.l3_protocol; |
1513 | ext_params->mask_l3_protocol = key->mask.l3_protocol; |
1514 | } |
1515 | |
1516 | /** |
1517 | * dpsw_acl_add_entry() - Add a rule to the ACL table. |
1518 | * @mc_io: Pointer to MC portal's I/O object |
1519 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1520 | * @token: Token of DPSW object |
1521 | * @acl_id: ACL ID |
1522 | * @cfg: Entry configuration |
1523 | * |
1524 | * warning: This function has to be called after dpsw_acl_prepare_entry_cfg() |
1525 | * |
1526 | * Return: '0' on Success; Error code otherwise. |
1527 | */ |
1528 | int dpsw_acl_add_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1529 | u16 acl_id, const struct dpsw_acl_entry_cfg *cfg) |
1530 | { |
1531 | struct dpsw_cmd_acl_entry *cmd_params; |
1532 | struct fsl_mc_command cmd = { 0 }; |
1533 | |
1534 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD_ENTRY, cmd_flags, |
1535 | token); |
1536 | cmd_params = (struct dpsw_cmd_acl_entry *)cmd.params; |
1537 | cmd_params->acl_id = cpu_to_le16(acl_id); |
1538 | cmd_params->result_if_id = cpu_to_le16(cfg->result.if_id); |
1539 | cmd_params->precedence = cpu_to_le32(cfg->precedence); |
1540 | cmd_params->key_iova = cpu_to_le64(cfg->key_iova); |
1541 | dpsw_set_field(cmd_params->result_action, |
1542 | RESULT_ACTION, |
1543 | cfg->result.action); |
1544 | |
1545 | return mc_send_command(mc_io, cmd: &cmd); |
1546 | } |
1547 | |
1548 | /** |
1549 | * dpsw_acl_remove_entry() - Removes an entry from ACL. |
1550 | * @mc_io: Pointer to MC portal's I/O object |
1551 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1552 | * @token: Token of DPSW object |
1553 | * @acl_id: ACL ID |
1554 | * @cfg: Entry configuration |
1555 | * |
1556 | * warning: This function has to be called after dpsw_acl_set_entry_cfg() |
1557 | * |
1558 | * Return: '0' on Success; Error code otherwise. |
1559 | */ |
1560 | int dpsw_acl_remove_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1561 | u16 acl_id, const struct dpsw_acl_entry_cfg *cfg) |
1562 | { |
1563 | struct dpsw_cmd_acl_entry *cmd_params; |
1564 | struct fsl_mc_command cmd = { 0 }; |
1565 | |
1566 | /* prepare command */ |
1567 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_ENTRY, |
1568 | cmd_flags, |
1569 | token); |
1570 | cmd_params = (struct dpsw_cmd_acl_entry *)cmd.params; |
1571 | cmd_params->acl_id = cpu_to_le16(acl_id); |
1572 | cmd_params->result_if_id = cpu_to_le16(cfg->result.if_id); |
1573 | cmd_params->precedence = cpu_to_le32(cfg->precedence); |
1574 | cmd_params->key_iova = cpu_to_le64(cfg->key_iova); |
1575 | dpsw_set_field(cmd_params->result_action, |
1576 | RESULT_ACTION, |
1577 | cfg->result.action); |
1578 | |
1579 | /* send command to mc*/ |
1580 | return mc_send_command(mc_io, cmd: &cmd); |
1581 | } |
1582 | |
1583 | /** |
1584 | * dpsw_set_reflection_if() - Set target interface for traffic mirrored |
1585 | * @mc_io: Pointer to MC portal's I/O object |
1586 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1587 | * @token: Token of DPSW object |
1588 | * @if_id: Interface Id |
1589 | * |
1590 | * Only one mirroring destination is allowed per switch |
1591 | * |
1592 | * Return: Completion status. '0' on Success; Error code otherwise. |
1593 | */ |
1594 | int dpsw_set_reflection_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1595 | u16 if_id) |
1596 | { |
1597 | struct dpsw_cmd_set_reflection_if *cmd_params; |
1598 | struct fsl_mc_command cmd = { 0 }; |
1599 | |
1600 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_REFLECTION_IF, |
1601 | cmd_flags, |
1602 | token); |
1603 | cmd_params = (struct dpsw_cmd_set_reflection_if *)cmd.params; |
1604 | cmd_params->if_id = cpu_to_le16(if_id); |
1605 | |
1606 | return mc_send_command(mc_io, cmd: &cmd); |
1607 | } |
1608 | |
1609 | /** |
1610 | * dpsw_if_add_reflection() - Setup mirroring rule |
1611 | * @mc_io: Pointer to MC portal's I/O object |
1612 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1613 | * @token: Token of DPSW object |
1614 | * @if_id: Interface Identifier |
1615 | * @cfg: Reflection configuration |
1616 | * |
1617 | * Return: Completion status. '0' on Success; Error code otherwise. |
1618 | */ |
1619 | int dpsw_if_add_reflection(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1620 | u16 if_id, const struct dpsw_reflection_cfg *cfg) |
1621 | { |
1622 | struct dpsw_cmd_if_reflection *cmd_params; |
1623 | struct fsl_mc_command cmd = { 0 }; |
1624 | |
1625 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ADD_REFLECTION, |
1626 | cmd_flags, |
1627 | token); |
1628 | cmd_params = (struct dpsw_cmd_if_reflection *)cmd.params; |
1629 | cmd_params->if_id = cpu_to_le16(if_id); |
1630 | cmd_params->vlan_id = cpu_to_le16(cfg->vlan_id); |
1631 | dpsw_set_field(cmd_params->filter, FILTER, cfg->filter); |
1632 | |
1633 | return mc_send_command(mc_io, cmd: &cmd); |
1634 | } |
1635 | |
1636 | /** |
1637 | * dpsw_if_remove_reflection() - Remove mirroring rule |
1638 | * @mc_io: Pointer to MC portal's I/O object |
1639 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
1640 | * @token: Token of DPSW object |
1641 | * @if_id: Interface Identifier |
1642 | * @cfg: Reflection configuration |
1643 | * |
1644 | * Return: Completion status. '0' on Success; Error code otherwise. |
1645 | */ |
1646 | int dpsw_if_remove_reflection(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, |
1647 | u16 if_id, const struct dpsw_reflection_cfg *cfg) |
1648 | { |
1649 | struct dpsw_cmd_if_reflection *cmd_params; |
1650 | struct fsl_mc_command cmd = { 0 }; |
1651 | |
1652 | cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_REMOVE_REFLECTION, |
1653 | cmd_flags, |
1654 | token); |
1655 | cmd_params = (struct dpsw_cmd_if_reflection *)cmd.params; |
1656 | cmd_params->if_id = cpu_to_le16(if_id); |
1657 | cmd_params->vlan_id = cpu_to_le16(cfg->vlan_id); |
1658 | dpsw_set_field(cmd_params->filter, FILTER, cfg->filter); |
1659 | |
1660 | return mc_send_command(mc_io, cmd: &cmd); |
1661 | } |
1662 | |