1// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2/* Copyright 2013-2016 Freescale Semiconductor Inc.
3 * Copyright 2016 NXP
4 * Copyright 2020 NXP
5 */
6#include <linux/kernel.h>
7#include <linux/errno.h>
8#include <linux/fsl/mc.h>
9#include "dpni.h"
10#include "dpni-cmd.h"
11
12/**
13 * dpni_prepare_key_cfg() - function prepare extract parameters
14 * @cfg: defining a full Key Generation profile (rule)
15 * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
16 *
17 * This function has to be called before the following functions:
18 * - dpni_set_rx_tc_dist()
19 * - dpni_set_qos_table()
20 *
21 * Return: '0' on Success; Error code otherwise.
22 */
23int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg, u8 *key_cfg_buf)
24{
25 int i, j;
26 struct dpni_ext_set_rx_tc_dist *dpni_ext;
27 struct dpni_dist_extract *extr;
28
29 if (cfg->num_extracts > DPKG_MAX_NUM_OF_EXTRACTS)
30 return -EINVAL;
31
32 dpni_ext = (struct dpni_ext_set_rx_tc_dist *)key_cfg_buf;
33 dpni_ext->num_extracts = cfg->num_extracts;
34
35 for (i = 0; i < cfg->num_extracts; i++) {
36 extr = &dpni_ext->extracts[i];
37
38 switch (cfg->extracts[i].type) {
39 case DPKG_EXTRACT_FROM_HDR:
40 extr->prot = cfg->extracts[i].extract.from_hdr.prot;
41 dpni_set_field(extr->efh_type, EFH_TYPE,
42 cfg->extracts[i].extract.from_hdr.type);
43 extr->size = cfg->extracts[i].extract.from_hdr.size;
44 extr->offset = cfg->extracts[i].extract.from_hdr.offset;
45 extr->field = cpu_to_le32(
46 cfg->extracts[i].extract.from_hdr.field);
47 extr->hdr_index =
48 cfg->extracts[i].extract.from_hdr.hdr_index;
49 break;
50 case DPKG_EXTRACT_FROM_DATA:
51 extr->size = cfg->extracts[i].extract.from_data.size;
52 extr->offset =
53 cfg->extracts[i].extract.from_data.offset;
54 break;
55 case DPKG_EXTRACT_FROM_PARSE:
56 extr->size = cfg->extracts[i].extract.from_parse.size;
57 extr->offset =
58 cfg->extracts[i].extract.from_parse.offset;
59 break;
60 default:
61 return -EINVAL;
62 }
63
64 extr->num_of_byte_masks = cfg->extracts[i].num_of_byte_masks;
65 dpni_set_field(extr->extract_type, EXTRACT_TYPE,
66 cfg->extracts[i].type);
67
68 for (j = 0; j < DPKG_NUM_OF_MASKS; j++) {
69 extr->masks[j].mask = cfg->extracts[i].masks[j].mask;
70 extr->masks[j].offset =
71 cfg->extracts[i].masks[j].offset;
72 }
73 }
74
75 return 0;
76}
77
78/**
79 * dpni_open() - Open a control session for the specified object
80 * @mc_io: Pointer to MC portal's I/O object
81 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
82 * @dpni_id: DPNI unique ID
83 * @token: Returned token; use in subsequent API calls
84 *
85 * This function can be used to open a control session for an
86 * already created object; an object may have been declared in
87 * the DPL or by calling the dpni_create() function.
88 * This function returns a unique authentication token,
89 * associated with the specific object ID and the specific MC
90 * portal; this token must be used in all subsequent commands for
91 * this specific object.
92 *
93 * Return: '0' on Success; Error code otherwise.
94 */
95int dpni_open(struct fsl_mc_io *mc_io,
96 u32 cmd_flags,
97 int dpni_id,
98 u16 *token)
99{
100 struct fsl_mc_command cmd = { 0 };
101 struct dpni_cmd_open *cmd_params;
102
103 int err;
104
105 /* prepare command */
106 cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
107 cmd_flags,
108 token: 0);
109 cmd_params = (struct dpni_cmd_open *)cmd.params;
110 cmd_params->dpni_id = cpu_to_le32(dpni_id);
111
112 /* send command to mc*/
113 err = mc_send_command(mc_io, cmd: &cmd);
114 if (err)
115 return err;
116
117 /* retrieve response parameters */
118 *token = mc_cmd_hdr_read_token(cmd: &cmd);
119
120 return 0;
121}
122
123/**
124 * dpni_close() - Close the control session of the object
125 * @mc_io: Pointer to MC portal's I/O object
126 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
127 * @token: Token of DPNI object
128 *
129 * After this function is called, no further operations are
130 * allowed on the object without opening a new control session.
131 *
132 * Return: '0' on Success; Error code otherwise.
133 */
134int dpni_close(struct fsl_mc_io *mc_io,
135 u32 cmd_flags,
136 u16 token)
137{
138 struct fsl_mc_command cmd = { 0 };
139
140 /* prepare command */
141 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
142 cmd_flags,
143 token);
144
145 /* send command to mc*/
146 return mc_send_command(mc_io, cmd: &cmd);
147}
148
149/**
150 * dpni_set_pools() - Set buffer pools configuration
151 * @mc_io: Pointer to MC portal's I/O object
152 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
153 * @token: Token of DPNI object
154 * @cfg: Buffer pools configuration
155 *
156 * mandatory for DPNI operation
157 * warning:Allowed only when DPNI is disabled
158 *
159 * Return: '0' on Success; Error code otherwise.
160 */
161int dpni_set_pools(struct fsl_mc_io *mc_io,
162 u32 cmd_flags,
163 u16 token,
164 const struct dpni_pools_cfg *cfg)
165{
166 struct fsl_mc_command cmd = { 0 };
167 struct dpni_cmd_set_pools *cmd_params;
168 int i;
169
170 /* prepare command */
171 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
172 cmd_flags,
173 token);
174 cmd_params = (struct dpni_cmd_set_pools *)cmd.params;
175 cmd_params->num_dpbp = cfg->num_dpbp;
176 cmd_params->pool_options = cfg->pool_options;
177 for (i = 0; i < DPNI_MAX_DPBP; i++) {
178 cmd_params->pool[i].dpbp_id =
179 cpu_to_le16(cfg->pools[i].dpbp_id);
180 cmd_params->pool[i].priority_mask =
181 cfg->pools[i].priority_mask;
182 cmd_params->buffer_size[i] =
183 cpu_to_le16(cfg->pools[i].buffer_size);
184 cmd_params->backup_pool_mask |=
185 DPNI_BACKUP_POOL(cfg->pools[i].backup_pool, i);
186 }
187
188 /* send command to mc*/
189 return mc_send_command(mc_io, cmd: &cmd);
190}
191
192/**
193 * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
194 * @mc_io: Pointer to MC portal's I/O object
195 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
196 * @token: Token of DPNI object
197 *
198 * Return: '0' on Success; Error code otherwise.
199 */
200int dpni_enable(struct fsl_mc_io *mc_io,
201 u32 cmd_flags,
202 u16 token)
203{
204 struct fsl_mc_command cmd = { 0 };
205
206 /* prepare command */
207 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
208 cmd_flags,
209 token);
210
211 /* send command to mc*/
212 return mc_send_command(mc_io, cmd: &cmd);
213}
214
215/**
216 * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
217 * @mc_io: Pointer to MC portal's I/O object
218 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
219 * @token: Token of DPNI object
220 *
221 * Return: '0' on Success; Error code otherwise.
222 */
223int dpni_disable(struct fsl_mc_io *mc_io,
224 u32 cmd_flags,
225 u16 token)
226{
227 struct fsl_mc_command cmd = { 0 };
228
229 /* prepare command */
230 cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
231 cmd_flags,
232 token);
233
234 /* send command to mc*/
235 return mc_send_command(mc_io, cmd: &cmd);
236}
237
238/**
239 * dpni_is_enabled() - Check if the DPNI is enabled.
240 * @mc_io: Pointer to MC portal's I/O object
241 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
242 * @token: Token of DPNI object
243 * @en: Returns '1' if object is enabled; '0' otherwise
244 *
245 * Return: '0' on Success; Error code otherwise.
246 */
247int dpni_is_enabled(struct fsl_mc_io *mc_io,
248 u32 cmd_flags,
249 u16 token,
250 int *en)
251{
252 struct fsl_mc_command cmd = { 0 };
253 struct dpni_rsp_is_enabled *rsp_params;
254 int err;
255
256 /* prepare command */
257 cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED,
258 cmd_flags,
259 token);
260
261 /* send command to mc*/
262 err = mc_send_command(mc_io, cmd: &cmd);
263 if (err)
264 return err;
265
266 /* retrieve response parameters */
267 rsp_params = (struct dpni_rsp_is_enabled *)cmd.params;
268 *en = dpni_get_field(rsp_params->enabled, ENABLE);
269
270 return 0;
271}
272
273/**
274 * dpni_reset() - Reset the DPNI, returns the object to initial state.
275 * @mc_io: Pointer to MC portal's I/O object
276 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
277 * @token: Token of DPNI object
278 *
279 * Return: '0' on Success; Error code otherwise.
280 */
281int dpni_reset(struct fsl_mc_io *mc_io,
282 u32 cmd_flags,
283 u16 token)
284{
285 struct fsl_mc_command cmd = { 0 };
286
287 /* prepare command */
288 cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
289 cmd_flags,
290 token);
291
292 /* send command to mc*/
293 return mc_send_command(mc_io, cmd: &cmd);
294}
295
296/**
297 * dpni_set_irq_enable() - Set overall interrupt state.
298 * @mc_io: Pointer to MC portal's I/O object
299 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
300 * @token: Token of DPNI object
301 * @irq_index: The interrupt index to configure
302 * @en: Interrupt state: - enable = 1, disable = 0
303 *
304 * Allows GPP software to control when interrupts are generated.
305 * Each interrupt can have up to 32 causes. The enable/disable control's the
306 * overall interrupt state. if the interrupt is disabled no causes will cause
307 * an interrupt.
308 *
309 * Return: '0' on Success; Error code otherwise.
310 */
311int dpni_set_irq_enable(struct fsl_mc_io *mc_io,
312 u32 cmd_flags,
313 u16 token,
314 u8 irq_index,
315 u8 en)
316{
317 struct fsl_mc_command cmd = { 0 };
318 struct dpni_cmd_set_irq_enable *cmd_params;
319
320 /* prepare command */
321 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_IRQ_ENABLE,
322 cmd_flags,
323 token);
324 cmd_params = (struct dpni_cmd_set_irq_enable *)cmd.params;
325 dpni_set_field(cmd_params->enable, ENABLE, en);
326 cmd_params->irq_index = irq_index;
327
328 /* send command to mc*/
329 return mc_send_command(mc_io, cmd: &cmd);
330}
331
332/**
333 * dpni_get_irq_enable() - Get overall interrupt state
334 * @mc_io: Pointer to MC portal's I/O object
335 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
336 * @token: Token of DPNI object
337 * @irq_index: The interrupt index to configure
338 * @en: Returned interrupt state - enable = 1, disable = 0
339 *
340 * Return: '0' on Success; Error code otherwise.
341 */
342int dpni_get_irq_enable(struct fsl_mc_io *mc_io,
343 u32 cmd_flags,
344 u16 token,
345 u8 irq_index,
346 u8 *en)
347{
348 struct fsl_mc_command cmd = { 0 };
349 struct dpni_cmd_get_irq_enable *cmd_params;
350 struct dpni_rsp_get_irq_enable *rsp_params;
351
352 int err;
353
354 /* prepare command */
355 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_ENABLE,
356 cmd_flags,
357 token);
358 cmd_params = (struct dpni_cmd_get_irq_enable *)cmd.params;
359 cmd_params->irq_index = irq_index;
360
361 /* send command to mc*/
362 err = mc_send_command(mc_io, cmd: &cmd);
363 if (err)
364 return err;
365
366 /* retrieve response parameters */
367 rsp_params = (struct dpni_rsp_get_irq_enable *)cmd.params;
368 *en = dpni_get_field(rsp_params->enabled, ENABLE);
369
370 return 0;
371}
372
373/**
374 * dpni_set_irq_mask() - Set interrupt mask.
375 * @mc_io: Pointer to MC portal's I/O object
376 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
377 * @token: Token of DPNI object
378 * @irq_index: The interrupt index to configure
379 * @mask: event mask to trigger interrupt;
380 * each bit:
381 * 0 = ignore event
382 * 1 = consider event for asserting IRQ
383 *
384 * Every interrupt can have up to 32 causes and the interrupt model supports
385 * masking/unmasking each cause independently
386 *
387 * Return: '0' on Success; Error code otherwise.
388 */
389int dpni_set_irq_mask(struct fsl_mc_io *mc_io,
390 u32 cmd_flags,
391 u16 token,
392 u8 irq_index,
393 u32 mask)
394{
395 struct fsl_mc_command cmd = { 0 };
396 struct dpni_cmd_set_irq_mask *cmd_params;
397
398 /* prepare command */
399 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_IRQ_MASK,
400 cmd_flags,
401 token);
402 cmd_params = (struct dpni_cmd_set_irq_mask *)cmd.params;
403 cmd_params->mask = cpu_to_le32(mask);
404 cmd_params->irq_index = irq_index;
405
406 /* send command to mc*/
407 return mc_send_command(mc_io, cmd: &cmd);
408}
409
410/**
411 * dpni_get_irq_mask() - Get interrupt mask.
412 * @mc_io: Pointer to MC portal's I/O object
413 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
414 * @token: Token of DPNI object
415 * @irq_index: The interrupt index to configure
416 * @mask: Returned event mask to trigger interrupt
417 *
418 * Every interrupt can have up to 32 causes and the interrupt model supports
419 * masking/unmasking each cause independently
420 *
421 * Return: '0' on Success; Error code otherwise.
422 */
423int dpni_get_irq_mask(struct fsl_mc_io *mc_io,
424 u32 cmd_flags,
425 u16 token,
426 u8 irq_index,
427 u32 *mask)
428{
429 struct fsl_mc_command cmd = { 0 };
430 struct dpni_cmd_get_irq_mask *cmd_params;
431 struct dpni_rsp_get_irq_mask *rsp_params;
432 int err;
433
434 /* prepare command */
435 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_MASK,
436 cmd_flags,
437 token);
438 cmd_params = (struct dpni_cmd_get_irq_mask *)cmd.params;
439 cmd_params->irq_index = irq_index;
440
441 /* send command to mc*/
442 err = mc_send_command(mc_io, cmd: &cmd);
443 if (err)
444 return err;
445
446 /* retrieve response parameters */
447 rsp_params = (struct dpni_rsp_get_irq_mask *)cmd.params;
448 *mask = le32_to_cpu(rsp_params->mask);
449
450 return 0;
451}
452
453/**
454 * dpni_get_irq_status() - Get the current status of any pending interrupts.
455 * @mc_io: Pointer to MC portal's I/O object
456 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
457 * @token: Token of DPNI object
458 * @irq_index: The interrupt index to configure
459 * @status: Returned interrupts status - one bit per cause:
460 * 0 = no interrupt pending
461 * 1 = interrupt pending
462 *
463 * Return: '0' on Success; Error code otherwise.
464 */
465int dpni_get_irq_status(struct fsl_mc_io *mc_io,
466 u32 cmd_flags,
467 u16 token,
468 u8 irq_index,
469 u32 *status)
470{
471 struct fsl_mc_command cmd = { 0 };
472 struct dpni_cmd_get_irq_status *cmd_params;
473 struct dpni_rsp_get_irq_status *rsp_params;
474 int err;
475
476 /* prepare command */
477 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_STATUS,
478 cmd_flags,
479 token);
480 cmd_params = (struct dpni_cmd_get_irq_status *)cmd.params;
481 cmd_params->status = cpu_to_le32(*status);
482 cmd_params->irq_index = irq_index;
483
484 /* send command to mc*/
485 err = mc_send_command(mc_io, cmd: &cmd);
486 if (err)
487 return err;
488
489 /* retrieve response parameters */
490 rsp_params = (struct dpni_rsp_get_irq_status *)cmd.params;
491 *status = le32_to_cpu(rsp_params->status);
492
493 return 0;
494}
495
496/**
497 * dpni_clear_irq_status() - Clear a pending interrupt's status
498 * @mc_io: Pointer to MC portal's I/O object
499 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
500 * @token: Token of DPNI object
501 * @irq_index: The interrupt index to configure
502 * @status: bits to clear (W1C) - one bit per cause:
503 * 0 = don't change
504 * 1 = clear status bit
505 *
506 * Return: '0' on Success; Error code otherwise.
507 */
508int dpni_clear_irq_status(struct fsl_mc_io *mc_io,
509 u32 cmd_flags,
510 u16 token,
511 u8 irq_index,
512 u32 status)
513{
514 struct fsl_mc_command cmd = { 0 };
515 struct dpni_cmd_clear_irq_status *cmd_params;
516
517 /* prepare command */
518 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLEAR_IRQ_STATUS,
519 cmd_flags,
520 token);
521 cmd_params = (struct dpni_cmd_clear_irq_status *)cmd.params;
522 cmd_params->irq_index = irq_index;
523 cmd_params->status = cpu_to_le32(status);
524
525 /* send command to mc*/
526 return mc_send_command(mc_io, cmd: &cmd);
527}
528
529/**
530 * dpni_get_attributes() - Retrieve DPNI attributes.
531 * @mc_io: Pointer to MC portal's I/O object
532 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
533 * @token: Token of DPNI object
534 * @attr: Object's attributes
535 *
536 * Return: '0' on Success; Error code otherwise.
537 */
538int dpni_get_attributes(struct fsl_mc_io *mc_io,
539 u32 cmd_flags,
540 u16 token,
541 struct dpni_attr *attr)
542{
543 struct fsl_mc_command cmd = { 0 };
544 struct dpni_rsp_get_attr *rsp_params;
545
546 int err;
547
548 /* prepare command */
549 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
550 cmd_flags,
551 token);
552
553 /* send command to mc*/
554 err = mc_send_command(mc_io, cmd: &cmd);
555 if (err)
556 return err;
557
558 /* retrieve response parameters */
559 rsp_params = (struct dpni_rsp_get_attr *)cmd.params;
560 attr->options = le32_to_cpu(rsp_params->options);
561 attr->num_queues = rsp_params->num_queues;
562 attr->num_tcs = rsp_params->num_tcs;
563 attr->mac_filter_entries = rsp_params->mac_filter_entries;
564 attr->vlan_filter_entries = rsp_params->vlan_filter_entries;
565 attr->qos_entries = rsp_params->qos_entries;
566 attr->fs_entries = le16_to_cpu(rsp_params->fs_entries);
567 attr->qos_key_size = rsp_params->qos_key_size;
568 attr->fs_key_size = rsp_params->fs_key_size;
569 attr->wriop_version = le16_to_cpu(rsp_params->wriop_version);
570
571 return 0;
572}
573
574/**
575 * dpni_set_errors_behavior() - Set errors behavior
576 * @mc_io: Pointer to MC portal's I/O object
577 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
578 * @token: Token of DPNI object
579 * @cfg: Errors configuration
580 *
581 * this function may be called numerous times with different
582 * error masks
583 *
584 * Return: '0' on Success; Error code otherwise.
585 */
586int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
587 u32 cmd_flags,
588 u16 token,
589 struct dpni_error_cfg *cfg)
590{
591 struct fsl_mc_command cmd = { 0 };
592 struct dpni_cmd_set_errors_behavior *cmd_params;
593
594 /* prepare command */
595 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
596 cmd_flags,
597 token);
598 cmd_params = (struct dpni_cmd_set_errors_behavior *)cmd.params;
599 cmd_params->errors = cpu_to_le32(cfg->errors);
600 dpni_set_field(cmd_params->flags, ERROR_ACTION, cfg->error_action);
601 dpni_set_field(cmd_params->flags, FRAME_ANN, cfg->set_frame_annotation);
602
603 /* send command to mc*/
604 return mc_send_command(mc_io, cmd: &cmd);
605}
606
607/**
608 * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
609 * @mc_io: Pointer to MC portal's I/O object
610 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
611 * @token: Token of DPNI object
612 * @qtype: Type of queue to retrieve configuration for
613 * @layout: Returns buffer layout attributes
614 *
615 * Return: '0' on Success; Error code otherwise.
616 */
617int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
618 u32 cmd_flags,
619 u16 token,
620 enum dpni_queue_type qtype,
621 struct dpni_buffer_layout *layout)
622{
623 struct fsl_mc_command cmd = { 0 };
624 struct dpni_cmd_get_buffer_layout *cmd_params;
625 struct dpni_rsp_get_buffer_layout *rsp_params;
626 int err;
627
628 /* prepare command */
629 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
630 cmd_flags,
631 token);
632 cmd_params = (struct dpni_cmd_get_buffer_layout *)cmd.params;
633 cmd_params->qtype = qtype;
634
635 /* send command to mc*/
636 err = mc_send_command(mc_io, cmd: &cmd);
637 if (err)
638 return err;
639
640 /* retrieve response parameters */
641 rsp_params = (struct dpni_rsp_get_buffer_layout *)cmd.params;
642 layout->pass_timestamp = dpni_get_field(rsp_params->flags, PASS_TS);
643 layout->pass_parser_result = dpni_get_field(rsp_params->flags, PASS_PR);
644 layout->pass_frame_status = dpni_get_field(rsp_params->flags, PASS_FS);
645 layout->private_data_size = le16_to_cpu(rsp_params->private_data_size);
646 layout->data_align = le16_to_cpu(rsp_params->data_align);
647 layout->data_head_room = le16_to_cpu(rsp_params->head_room);
648 layout->data_tail_room = le16_to_cpu(rsp_params->tail_room);
649
650 return 0;
651}
652
653/**
654 * dpni_set_buffer_layout() - Set buffer layout configuration.
655 * @mc_io: Pointer to MC portal's I/O object
656 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
657 * @token: Token of DPNI object
658 * @qtype: Type of queue this configuration applies to
659 * @layout: Buffer layout configuration
660 *
661 * Return: '0' on Success; Error code otherwise.
662 *
663 * @warning Allowed only when DPNI is disabled
664 */
665int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
666 u32 cmd_flags,
667 u16 token,
668 enum dpni_queue_type qtype,
669 const struct dpni_buffer_layout *layout)
670{
671 struct fsl_mc_command cmd = { 0 };
672 struct dpni_cmd_set_buffer_layout *cmd_params;
673
674 /* prepare command */
675 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
676 cmd_flags,
677 token);
678 cmd_params = (struct dpni_cmd_set_buffer_layout *)cmd.params;
679 cmd_params->qtype = qtype;
680 cmd_params->options = cpu_to_le16(layout->options);
681 dpni_set_field(cmd_params->flags, PASS_TS, layout->pass_timestamp);
682 dpni_set_field(cmd_params->flags, PASS_PR, layout->pass_parser_result);
683 dpni_set_field(cmd_params->flags, PASS_FS, layout->pass_frame_status);
684 cmd_params->private_data_size = cpu_to_le16(layout->private_data_size);
685 cmd_params->data_align = cpu_to_le16(layout->data_align);
686 cmd_params->head_room = cpu_to_le16(layout->data_head_room);
687 cmd_params->tail_room = cpu_to_le16(layout->data_tail_room);
688
689 /* send command to mc*/
690 return mc_send_command(mc_io, cmd: &cmd);
691}
692
693/**
694 * dpni_set_offload() - Set DPNI offload configuration.
695 * @mc_io: Pointer to MC portal's I/O object
696 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
697 * @token: Token of DPNI object
698 * @type: Type of DPNI offload
699 * @config: Offload configuration.
700 * For checksum offloads, non-zero value enables the offload
701 *
702 * Return: '0' on Success; Error code otherwise.
703 *
704 * @warning Allowed only when DPNI is disabled
705 */
706
707int dpni_set_offload(struct fsl_mc_io *mc_io,
708 u32 cmd_flags,
709 u16 token,
710 enum dpni_offload type,
711 u32 config)
712{
713 struct fsl_mc_command cmd = { 0 };
714 struct dpni_cmd_set_offload *cmd_params;
715
716 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
717 cmd_flags,
718 token);
719 cmd_params = (struct dpni_cmd_set_offload *)cmd.params;
720 cmd_params->dpni_offload = type;
721 cmd_params->config = cpu_to_le32(config);
722
723 return mc_send_command(mc_io, cmd: &cmd);
724}
725
726int dpni_get_offload(struct fsl_mc_io *mc_io,
727 u32 cmd_flags,
728 u16 token,
729 enum dpni_offload type,
730 u32 *config)
731{
732 struct fsl_mc_command cmd = { 0 };
733 struct dpni_cmd_get_offload *cmd_params;
734 struct dpni_rsp_get_offload *rsp_params;
735 int err;
736
737 /* prepare command */
738 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
739 cmd_flags,
740 token);
741 cmd_params = (struct dpni_cmd_get_offload *)cmd.params;
742 cmd_params->dpni_offload = type;
743
744 /* send command to mc*/
745 err = mc_send_command(mc_io, cmd: &cmd);
746 if (err)
747 return err;
748
749 /* retrieve response parameters */
750 rsp_params = (struct dpni_rsp_get_offload *)cmd.params;
751 *config = le32_to_cpu(rsp_params->config);
752
753 return 0;
754}
755
756/**
757 * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
758 * for enqueue operations
759 * @mc_io: Pointer to MC portal's I/O object
760 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
761 * @token: Token of DPNI object
762 * @qtype: Type of queue to receive QDID for
763 * @qdid: Returned virtual QDID value that should be used as an argument
764 * in all enqueue operations
765 *
766 * Return: '0' on Success; Error code otherwise.
767 */
768int dpni_get_qdid(struct fsl_mc_io *mc_io,
769 u32 cmd_flags,
770 u16 token,
771 enum dpni_queue_type qtype,
772 u16 *qdid)
773{
774 struct fsl_mc_command cmd = { 0 };
775 struct dpni_cmd_get_qdid *cmd_params;
776 struct dpni_rsp_get_qdid *rsp_params;
777 int err;
778
779 /* prepare command */
780 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
781 cmd_flags,
782 token);
783 cmd_params = (struct dpni_cmd_get_qdid *)cmd.params;
784 cmd_params->qtype = qtype;
785
786 /* send command to mc*/
787 err = mc_send_command(mc_io, cmd: &cmd);
788 if (err)
789 return err;
790
791 /* retrieve response parameters */
792 rsp_params = (struct dpni_rsp_get_qdid *)cmd.params;
793 *qdid = le16_to_cpu(rsp_params->qdid);
794
795 return 0;
796}
797
798/**
799 * dpni_get_tx_data_offset() - Get the Tx data offset (from start of buffer)
800 * @mc_io: Pointer to MC portal's I/O object
801 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
802 * @token: Token of DPNI object
803 * @data_offset: Tx data offset (from start of buffer)
804 *
805 * Return: '0' on Success; Error code otherwise.
806 */
807int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io,
808 u32 cmd_flags,
809 u16 token,
810 u16 *data_offset)
811{
812 struct fsl_mc_command cmd = { 0 };
813 struct dpni_rsp_get_tx_data_offset *rsp_params;
814 int err;
815
816 /* prepare command */
817 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_DATA_OFFSET,
818 cmd_flags,
819 token);
820
821 /* send command to mc*/
822 err = mc_send_command(mc_io, cmd: &cmd);
823 if (err)
824 return err;
825
826 /* retrieve response parameters */
827 rsp_params = (struct dpni_rsp_get_tx_data_offset *)cmd.params;
828 *data_offset = le16_to_cpu(rsp_params->data_offset);
829
830 return 0;
831}
832
833/**
834 * dpni_set_link_cfg() - set the link configuration.
835 * @mc_io: Pointer to MC portal's I/O object
836 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
837 * @token: Token of DPNI object
838 * @cfg: Link configuration
839 *
840 * Return: '0' on Success; Error code otherwise.
841 */
842int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
843 u32 cmd_flags,
844 u16 token,
845 const struct dpni_link_cfg *cfg)
846{
847 struct fsl_mc_command cmd = { 0 };
848 struct dpni_cmd_link_cfg *cmd_params;
849
850 /* prepare command */
851 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG,
852 cmd_flags,
853 token);
854 cmd_params = (struct dpni_cmd_link_cfg *)cmd.params;
855 cmd_params->rate = cpu_to_le32(cfg->rate);
856 cmd_params->options = cpu_to_le64(cfg->options);
857
858 /* send command to mc*/
859 return mc_send_command(mc_io, cmd: &cmd);
860}
861
862/**
863 * dpni_get_link_cfg() - return the link configuration
864 * @mc_io: Pointer to MC portal's I/O object
865 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
866 * @token: Token of DPNI object
867 * @cfg: Link configuration from dpni object
868 *
869 * Return: '0' on Success; Error code otherwise.
870 */
871int dpni_get_link_cfg(struct fsl_mc_io *mc_io,
872 u32 cmd_flags,
873 u16 token,
874 struct dpni_link_cfg *cfg)
875{
876 struct fsl_mc_command cmd = { 0 };
877 struct dpni_cmd_link_cfg *rsp_params;
878 int err;
879
880 /* prepare command */
881 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_CFG,
882 cmd_flags,
883 token);
884
885 /* send command to mc*/
886 err = mc_send_command(mc_io, cmd: &cmd);
887 if (err)
888 return err;
889
890 /* retrieve response parameters */
891 rsp_params = (struct dpni_cmd_link_cfg *)cmd.params;
892 cfg->rate = le32_to_cpu(rsp_params->rate);
893 cfg->options = le64_to_cpu(rsp_params->options);
894
895 return err;
896}
897
898/**
899 * dpni_get_link_state() - Return the link state (either up or down)
900 * @mc_io: Pointer to MC portal's I/O object
901 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
902 * @token: Token of DPNI object
903 * @state: Returned link state;
904 *
905 * Return: '0' on Success; Error code otherwise.
906 */
907int dpni_get_link_state(struct fsl_mc_io *mc_io,
908 u32 cmd_flags,
909 u16 token,
910 struct dpni_link_state *state)
911{
912 struct fsl_mc_command cmd = { 0 };
913 struct dpni_rsp_get_link_state *rsp_params;
914 int err;
915
916 /* prepare command */
917 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
918 cmd_flags,
919 token);
920
921 /* send command to mc*/
922 err = mc_send_command(mc_io, cmd: &cmd);
923 if (err)
924 return err;
925
926 /* retrieve response parameters */
927 rsp_params = (struct dpni_rsp_get_link_state *)cmd.params;
928 state->up = dpni_get_field(rsp_params->flags, LINK_STATE);
929 state->rate = le32_to_cpu(rsp_params->rate);
930 state->options = le64_to_cpu(rsp_params->options);
931
932 return 0;
933}
934
935/**
936 * dpni_set_max_frame_length() - Set the maximum received frame length.
937 * @mc_io: Pointer to MC portal's I/O object
938 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
939 * @token: Token of DPNI object
940 * @max_frame_length: Maximum received frame length (in
941 * bytes); frame is discarded if its
942 * length exceeds this value
943 *
944 * Return: '0' on Success; Error code otherwise.
945 */
946int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
947 u32 cmd_flags,
948 u16 token,
949 u16 max_frame_length)
950{
951 struct fsl_mc_command cmd = { 0 };
952 struct dpni_cmd_set_max_frame_length *cmd_params;
953
954 /* prepare command */
955 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
956 cmd_flags,
957 token);
958 cmd_params = (struct dpni_cmd_set_max_frame_length *)cmd.params;
959 cmd_params->max_frame_length = cpu_to_le16(max_frame_length);
960
961 /* send command to mc*/
962 return mc_send_command(mc_io, cmd: &cmd);
963}
964
965/**
966 * dpni_get_max_frame_length() - Get the maximum received frame length.
967 * @mc_io: Pointer to MC portal's I/O object
968 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
969 * @token: Token of DPNI object
970 * @max_frame_length: Maximum received frame length (in
971 * bytes); frame is discarded if its
972 * length exceeds this value
973 *
974 * Return: '0' on Success; Error code otherwise.
975 */
976int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
977 u32 cmd_flags,
978 u16 token,
979 u16 *max_frame_length)
980{
981 struct fsl_mc_command cmd = { 0 };
982 struct dpni_rsp_get_max_frame_length *rsp_params;
983 int err;
984
985 /* prepare command */
986 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
987 cmd_flags,
988 token);
989
990 /* send command to mc*/
991 err = mc_send_command(mc_io, cmd: &cmd);
992 if (err)
993 return err;
994
995 /* retrieve response parameters */
996 rsp_params = (struct dpni_rsp_get_max_frame_length *)cmd.params;
997 *max_frame_length = le16_to_cpu(rsp_params->max_frame_length);
998
999 return 0;
1000}
1001
1002/**
1003 * dpni_set_multicast_promisc() - Enable/disable multicast promiscuous mode
1004 * @mc_io: Pointer to MC portal's I/O object
1005 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1006 * @token: Token of DPNI object
1007 * @en: Set to '1' to enable; '0' to disable
1008 *
1009 * Return: '0' on Success; Error code otherwise.
1010 */
1011int dpni_set_multicast_promisc(struct fsl_mc_io *mc_io,
1012 u32 cmd_flags,
1013 u16 token,
1014 int en)
1015{
1016 struct fsl_mc_command cmd = { 0 };
1017 struct dpni_cmd_set_multicast_promisc *cmd_params;
1018
1019 /* prepare command */
1020 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MCAST_PROMISC,
1021 cmd_flags,
1022 token);
1023 cmd_params = (struct dpni_cmd_set_multicast_promisc *)cmd.params;
1024 dpni_set_field(cmd_params->enable, ENABLE, en);
1025
1026 /* send command to mc*/
1027 return mc_send_command(mc_io, cmd: &cmd);
1028}
1029
1030/**
1031 * dpni_get_multicast_promisc() - Get multicast promiscuous mode
1032 * @mc_io: Pointer to MC portal's I/O object
1033 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1034 * @token: Token of DPNI object
1035 * @en: Returns '1' if enabled; '0' otherwise
1036 *
1037 * Return: '0' on Success; Error code otherwise.
1038 */
1039int dpni_get_multicast_promisc(struct fsl_mc_io *mc_io,
1040 u32 cmd_flags,
1041 u16 token,
1042 int *en)
1043{
1044 struct fsl_mc_command cmd = { 0 };
1045 struct dpni_rsp_get_multicast_promisc *rsp_params;
1046 int err;
1047
1048 /* prepare command */
1049 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MCAST_PROMISC,
1050 cmd_flags,
1051 token);
1052
1053 /* send command to mc*/
1054 err = mc_send_command(mc_io, cmd: &cmd);
1055 if (err)
1056 return err;
1057
1058 /* retrieve response parameters */
1059 rsp_params = (struct dpni_rsp_get_multicast_promisc *)cmd.params;
1060 *en = dpni_get_field(rsp_params->enabled, ENABLE);
1061
1062 return 0;
1063}
1064
1065/**
1066 * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
1067 * @mc_io: Pointer to MC portal's I/O object
1068 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1069 * @token: Token of DPNI object
1070 * @en: Set to '1' to enable; '0' to disable
1071 *
1072 * Return: '0' on Success; Error code otherwise.
1073 */
1074int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
1075 u32 cmd_flags,
1076 u16 token,
1077 int en)
1078{
1079 struct fsl_mc_command cmd = { 0 };
1080 struct dpni_cmd_set_unicast_promisc *cmd_params;
1081
1082 /* prepare command */
1083 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
1084 cmd_flags,
1085 token);
1086 cmd_params = (struct dpni_cmd_set_unicast_promisc *)cmd.params;
1087 dpni_set_field(cmd_params->enable, ENABLE, en);
1088
1089 /* send command to mc*/
1090 return mc_send_command(mc_io, cmd: &cmd);
1091}
1092
1093/**
1094 * dpni_get_unicast_promisc() - Get unicast promiscuous mode
1095 * @mc_io: Pointer to MC portal's I/O object
1096 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1097 * @token: Token of DPNI object
1098 * @en: Returns '1' if enabled; '0' otherwise
1099 *
1100 * Return: '0' on Success; Error code otherwise.
1101 */
1102int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
1103 u32 cmd_flags,
1104 u16 token,
1105 int *en)
1106{
1107 struct fsl_mc_command cmd = { 0 };
1108 struct dpni_rsp_get_unicast_promisc *rsp_params;
1109 int err;
1110
1111 /* prepare command */
1112 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
1113 cmd_flags,
1114 token);
1115
1116 /* send command to mc*/
1117 err = mc_send_command(mc_io, cmd: &cmd);
1118 if (err)
1119 return err;
1120
1121 /* retrieve response parameters */
1122 rsp_params = (struct dpni_rsp_get_unicast_promisc *)cmd.params;
1123 *en = dpni_get_field(rsp_params->enabled, ENABLE);
1124
1125 return 0;
1126}
1127
1128/**
1129 * dpni_set_primary_mac_addr() - Set the primary MAC address
1130 * @mc_io: Pointer to MC portal's I/O object
1131 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1132 * @token: Token of DPNI object
1133 * @mac_addr: MAC address to set as primary address
1134 *
1135 * Return: '0' on Success; Error code otherwise.
1136 */
1137int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
1138 u32 cmd_flags,
1139 u16 token,
1140 const u8 mac_addr[6])
1141{
1142 struct fsl_mc_command cmd = { 0 };
1143 struct dpni_cmd_set_primary_mac_addr *cmd_params;
1144 int i;
1145
1146 /* prepare command */
1147 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
1148 cmd_flags,
1149 token);
1150 cmd_params = (struct dpni_cmd_set_primary_mac_addr *)cmd.params;
1151 for (i = 0; i < 6; i++)
1152 cmd_params->mac_addr[i] = mac_addr[5 - i];
1153
1154 /* send command to mc*/
1155 return mc_send_command(mc_io, cmd: &cmd);
1156}
1157
1158/**
1159 * dpni_get_primary_mac_addr() - Get the primary MAC address
1160 * @mc_io: Pointer to MC portal's I/O object
1161 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1162 * @token: Token of DPNI object
1163 * @mac_addr: Returned MAC address
1164 *
1165 * Return: '0' on Success; Error code otherwise.
1166 */
1167int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
1168 u32 cmd_flags,
1169 u16 token,
1170 u8 mac_addr[6])
1171{
1172 struct fsl_mc_command cmd = { 0 };
1173 struct dpni_rsp_get_primary_mac_addr *rsp_params;
1174 int i, err;
1175
1176 /* prepare command */
1177 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
1178 cmd_flags,
1179 token);
1180
1181 /* send command to mc*/
1182 err = mc_send_command(mc_io, cmd: &cmd);
1183 if (err)
1184 return err;
1185
1186 /* retrieve response parameters */
1187 rsp_params = (struct dpni_rsp_get_primary_mac_addr *)cmd.params;
1188 for (i = 0; i < 6; i++)
1189 mac_addr[5 - i] = rsp_params->mac_addr[i];
1190
1191 return 0;
1192}
1193
1194/**
1195 * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
1196 * port the DPNI is attached to
1197 * @mc_io: Pointer to MC portal's I/O object
1198 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1199 * @token: Token of DPNI object
1200 * @mac_addr: MAC address of the physical port, if any, otherwise 0
1201 *
1202 * The primary MAC address is not cleared by this operation.
1203 *
1204 * Return: '0' on Success; Error code otherwise.
1205 */
1206int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
1207 u32 cmd_flags,
1208 u16 token,
1209 u8 mac_addr[6])
1210{
1211 struct fsl_mc_command cmd = { 0 };
1212 struct dpni_rsp_get_port_mac_addr *rsp_params;
1213 int i, err;
1214
1215 /* prepare command */
1216 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PORT_MAC_ADDR,
1217 cmd_flags,
1218 token);
1219
1220 /* send command to mc*/
1221 err = mc_send_command(mc_io, cmd: &cmd);
1222 if (err)
1223 return err;
1224
1225 /* retrieve response parameters */
1226 rsp_params = (struct dpni_rsp_get_port_mac_addr *)cmd.params;
1227 for (i = 0; i < 6; i++)
1228 mac_addr[5 - i] = rsp_params->mac_addr[i];
1229
1230 return 0;
1231}
1232
1233/**
1234 * dpni_enable_vlan_filter() - Enable/disable VLAN filtering mode
1235 * @mc_io: Pointer to MC portal's I/O object
1236 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1237 * @token: Token of DPNI object
1238 * @en: Set to '1' to enable; '0' to disable
1239 *
1240 * Return: '0' on Success; Error code otherwise.
1241 */
1242int dpni_enable_vlan_filter(struct fsl_mc_io *mc_io,
1243 u32 cmd_flags,
1244 u16 token,
1245 u32 en)
1246{
1247 struct dpni_cmd_enable_vlan_filter *cmd_params;
1248 struct fsl_mc_command cmd = { 0 };
1249
1250 /* prepare command */
1251 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE_VLAN_FILTER,
1252 cmd_flags,
1253 token);
1254 cmd_params = (struct dpni_cmd_enable_vlan_filter *)cmd.params;
1255 dpni_set_field(cmd_params->en, ENABLE, en);
1256
1257 /* send command to mc*/
1258 return mc_send_command(mc_io, cmd: &cmd);
1259}
1260
1261/**
1262 * dpni_add_vlan_id() - Add VLAN ID filter
1263 * @mc_io: Pointer to MC portal's I/O object
1264 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1265 * @token: Token of DPNI object
1266 * @vlan_id: VLAN ID to add
1267 * @flags: 0 - tc_id and flow_id will be ignored.
1268 * Pkt with this vlan_id will be passed to the next
1269 * classification stages
1270 * DPNI_VLAN_SET_QUEUE_ACTION
1271 * Pkt with this vlan_id will be forward directly to
1272 * queue defined by the tc_id and flow_id
1273 *
1274 * @tc_id: Traffic class selection (0-7)
1275 * @flow_id: Selects the specific queue out of the set allocated for the
1276 * same as tc_id. Value must be in range 0 to NUM_QUEUES - 1
1277 *
1278 * Return: '0' on Success; Error code otherwise.
1279 */
1280int dpni_add_vlan_id(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
1281 u16 vlan_id, u8 flags, u8 tc_id, u8 flow_id)
1282{
1283 struct dpni_cmd_vlan_id *cmd_params;
1284 struct fsl_mc_command cmd = { 0 };
1285
1286 /* prepare command */
1287 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_VLAN_ID,
1288 cmd_flags,
1289 token);
1290 cmd_params = (struct dpni_cmd_vlan_id *)cmd.params;
1291 cmd_params->flags = flags;
1292 cmd_params->tc_id = tc_id;
1293 cmd_params->flow_id = flow_id;
1294 cmd_params->vlan_id = cpu_to_le16(vlan_id);
1295
1296 /* send command to mc*/
1297 return mc_send_command(mc_io, cmd: &cmd);
1298}
1299
1300/**
1301 * dpni_remove_vlan_id() - Remove VLAN ID filter
1302 * @mc_io: Pointer to MC portal's I/O object
1303 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1304 * @token: Token of DPNI object
1305 * @vlan_id: VLAN ID to remove
1306 *
1307 * Return: '0' on Success; Error code otherwise.
1308 */
1309int dpni_remove_vlan_id(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
1310 u16 vlan_id)
1311{
1312 struct dpni_cmd_vlan_id *cmd_params;
1313 struct fsl_mc_command cmd = { 0 };
1314
1315 /* prepare command */
1316 cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_VLAN_ID,
1317 cmd_flags,
1318 token);
1319 cmd_params = (struct dpni_cmd_vlan_id *)cmd.params;
1320 cmd_params->vlan_id = cpu_to_le16(vlan_id);
1321
1322 /* send command to mc*/
1323 return mc_send_command(mc_io, cmd: &cmd);
1324}
1325
1326/**
1327 * dpni_add_mac_addr() - Add MAC address filter
1328 * @mc_io: Pointer to MC portal's I/O object
1329 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1330 * @token: Token of DPNI object
1331 * @mac_addr: MAC address to add
1332 *
1333 * Return: '0' on Success; Error code otherwise.
1334 */
1335int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
1336 u32 cmd_flags,
1337 u16 token,
1338 const u8 mac_addr[6])
1339{
1340 struct fsl_mc_command cmd = { 0 };
1341 struct dpni_cmd_add_mac_addr *cmd_params;
1342 int i;
1343
1344 /* prepare command */
1345 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_MAC_ADDR,
1346 cmd_flags,
1347 token);
1348 cmd_params = (struct dpni_cmd_add_mac_addr *)cmd.params;
1349 for (i = 0; i < 6; i++)
1350 cmd_params->mac_addr[i] = mac_addr[5 - i];
1351
1352 /* send command to mc*/
1353 return mc_send_command(mc_io, cmd: &cmd);
1354}
1355
1356/**
1357 * dpni_remove_mac_addr() - Remove MAC address filter
1358 * @mc_io: Pointer to MC portal's I/O object
1359 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1360 * @token: Token of DPNI object
1361 * @mac_addr: MAC address to remove
1362 *
1363 * Return: '0' on Success; Error code otherwise.
1364 */
1365int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
1366 u32 cmd_flags,
1367 u16 token,
1368 const u8 mac_addr[6])
1369{
1370 struct fsl_mc_command cmd = { 0 };
1371 struct dpni_cmd_remove_mac_addr *cmd_params;
1372 int i;
1373
1374 /* prepare command */
1375 cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_MAC_ADDR,
1376 cmd_flags,
1377 token);
1378 cmd_params = (struct dpni_cmd_remove_mac_addr *)cmd.params;
1379 for (i = 0; i < 6; i++)
1380 cmd_params->mac_addr[i] = mac_addr[5 - i];
1381
1382 /* send command to mc*/
1383 return mc_send_command(mc_io, cmd: &cmd);
1384}
1385
1386/**
1387 * dpni_clear_mac_filters() - Clear all unicast and/or multicast MAC filters
1388 * @mc_io: Pointer to MC portal's I/O object
1389 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1390 * @token: Token of DPNI object
1391 * @unicast: Set to '1' to clear unicast addresses
1392 * @multicast: Set to '1' to clear multicast addresses
1393 *
1394 * The primary MAC address is not cleared by this operation.
1395 *
1396 * Return: '0' on Success; Error code otherwise.
1397 */
1398int dpni_clear_mac_filters(struct fsl_mc_io *mc_io,
1399 u32 cmd_flags,
1400 u16 token,
1401 int unicast,
1402 int multicast)
1403{
1404 struct fsl_mc_command cmd = { 0 };
1405 struct dpni_cmd_clear_mac_filters *cmd_params;
1406
1407 /* prepare command */
1408 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_MAC_FILTERS,
1409 cmd_flags,
1410 token);
1411 cmd_params = (struct dpni_cmd_clear_mac_filters *)cmd.params;
1412 dpni_set_field(cmd_params->flags, UNICAST_FILTERS, unicast);
1413 dpni_set_field(cmd_params->flags, MULTICAST_FILTERS, multicast);
1414
1415 /* send command to mc*/
1416 return mc_send_command(mc_io, cmd: &cmd);
1417}
1418
1419/**
1420 * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
1421 * @mc_io: Pointer to MC portal's I/O object
1422 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1423 * @token: Token of DPNI object
1424 * @tc_id: Traffic class selection (0-7)
1425 * @cfg: Traffic class distribution configuration
1426 *
1427 * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()
1428 * first to prepare the key_cfg_iova parameter
1429 *
1430 * Return: '0' on Success; error code otherwise.
1431 */
1432int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
1433 u32 cmd_flags,
1434 u16 token,
1435 u8 tc_id,
1436 const struct dpni_rx_tc_dist_cfg *cfg)
1437{
1438 struct fsl_mc_command cmd = { 0 };
1439 struct dpni_cmd_set_rx_tc_dist *cmd_params;
1440
1441 /* prepare command */
1442 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
1443 cmd_flags,
1444 token);
1445 cmd_params = (struct dpni_cmd_set_rx_tc_dist *)cmd.params;
1446 cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
1447 cmd_params->tc_id = tc_id;
1448 dpni_set_field(cmd_params->flags, DIST_MODE, cfg->dist_mode);
1449 dpni_set_field(cmd_params->flags, MISS_ACTION, cfg->fs_cfg.miss_action);
1450 cmd_params->default_flow_id = cpu_to_le16(cfg->fs_cfg.default_flow_id);
1451 cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1452
1453 /* send command to mc*/
1454 return mc_send_command(mc_io, cmd: &cmd);
1455}
1456
1457/**
1458 * dpni_set_congestion_notification() - Set traffic class congestion
1459 * notification configuration
1460 * @mc_io: Pointer to MC portal's I/O object
1461 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1462 * @token: Token of DPNI object
1463 * @qtype: Type of queue - Rx, Tx and Tx confirm types are supported
1464 * @tc_id: Traffic class selection (0-7)
1465 * @cfg: Congestion notification configuration
1466 *
1467 * Return: '0' on Success; error code otherwise.
1468 */
1469int dpni_set_congestion_notification(
1470 struct fsl_mc_io *mc_io,
1471 u32 cmd_flags,
1472 u16 token,
1473 enum dpni_queue_type qtype,
1474 u8 tc_id,
1475 const struct dpni_congestion_notification_cfg *cfg)
1476{
1477 struct dpni_cmd_set_congestion_notification *cmd_params;
1478 struct fsl_mc_command cmd = { 0 };
1479
1480 /* prepare command */
1481 cmd.header =
1482 mc_encode_cmd_header(DPNI_CMDID_SET_CONGESTION_NOTIFICATION,
1483 cmd_flags,
1484 token);
1485 cmd_params = (struct dpni_cmd_set_congestion_notification *)cmd.params;
1486 cmd_params->qtype = qtype;
1487 cmd_params->tc = tc_id;
1488 cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
1489 cmd_params->notification_mode = cpu_to_le16(cfg->notification_mode);
1490 cmd_params->dest_priority = cfg->dest_cfg.priority;
1491 dpni_set_field(cmd_params->type_units, DEST_TYPE,
1492 cfg->dest_cfg.dest_type);
1493 dpni_set_field(cmd_params->type_units, CONG_UNITS, cfg->units);
1494 cmd_params->message_iova = cpu_to_le64(cfg->message_iova);
1495 cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx);
1496 cmd_params->threshold_entry = cpu_to_le32(cfg->threshold_entry);
1497 cmd_params->threshold_exit = cpu_to_le32(cfg->threshold_exit);
1498
1499 /* send command to mc*/
1500 return mc_send_command(mc_io, cmd: &cmd);
1501}
1502
1503/**
1504 * dpni_set_queue() - Set queue parameters
1505 * @mc_io: Pointer to MC portal's I/O object
1506 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1507 * @token: Token of DPNI object
1508 * @qtype: Type of queue - all queue types are supported, although
1509 * the command is ignored for Tx
1510 * @tc: Traffic class, in range 0 to NUM_TCS - 1
1511 * @index: Selects the specific queue out of the set allocated for the
1512 * same TC. Value must be in range 0 to NUM_QUEUES - 1
1513 * @options: A combination of DPNI_QUEUE_OPT_ values that control what
1514 * configuration options are set on the queue
1515 * @queue: Queue structure
1516 *
1517 * Return: '0' on Success; Error code otherwise.
1518 */
1519int dpni_set_queue(struct fsl_mc_io *mc_io,
1520 u32 cmd_flags,
1521 u16 token,
1522 enum dpni_queue_type qtype,
1523 u8 tc,
1524 u8 index,
1525 u8 options,
1526 const struct dpni_queue *queue)
1527{
1528 struct fsl_mc_command cmd = { 0 };
1529 struct dpni_cmd_set_queue *cmd_params;
1530
1531 /* prepare command */
1532 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
1533 cmd_flags,
1534 token);
1535 cmd_params = (struct dpni_cmd_set_queue *)cmd.params;
1536 cmd_params->qtype = qtype;
1537 cmd_params->tc = tc;
1538 cmd_params->index = index;
1539 cmd_params->options = options;
1540 cmd_params->dest_id = cpu_to_le32(queue->destination.id);
1541 cmd_params->dest_prio = queue->destination.priority;
1542 dpni_set_field(cmd_params->flags, DEST_TYPE, queue->destination.type);
1543 dpni_set_field(cmd_params->flags, STASH_CTRL, queue->flc.stash_control);
1544 dpni_set_field(cmd_params->flags, HOLD_ACTIVE,
1545 queue->destination.hold_active);
1546 cmd_params->flc = cpu_to_le64(queue->flc.value);
1547 cmd_params->user_context = cpu_to_le64(queue->user_context);
1548
1549 /* send command to mc */
1550 return mc_send_command(mc_io, cmd: &cmd);
1551}
1552
1553/**
1554 * dpni_get_queue() - Get queue parameters
1555 * @mc_io: Pointer to MC portal's I/O object
1556 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1557 * @token: Token of DPNI object
1558 * @qtype: Type of queue - all queue types are supported
1559 * @tc: Traffic class, in range 0 to NUM_TCS - 1
1560 * @index: Selects the specific queue out of the set allocated for the
1561 * same TC. Value must be in range 0 to NUM_QUEUES - 1
1562 * @queue: Queue configuration structure
1563 * @qid: Queue identification
1564 *
1565 * Return: '0' on Success; Error code otherwise.
1566 */
1567int dpni_get_queue(struct fsl_mc_io *mc_io,
1568 u32 cmd_flags,
1569 u16 token,
1570 enum dpni_queue_type qtype,
1571 u8 tc,
1572 u8 index,
1573 struct dpni_queue *queue,
1574 struct dpni_queue_id *qid)
1575{
1576 struct fsl_mc_command cmd = { 0 };
1577 struct dpni_cmd_get_queue *cmd_params;
1578 struct dpni_rsp_get_queue *rsp_params;
1579 int err;
1580
1581 /* prepare command */
1582 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
1583 cmd_flags,
1584 token);
1585 cmd_params = (struct dpni_cmd_get_queue *)cmd.params;
1586 cmd_params->qtype = qtype;
1587 cmd_params->tc = tc;
1588 cmd_params->index = index;
1589
1590 /* send command to mc */
1591 err = mc_send_command(mc_io, cmd: &cmd);
1592 if (err)
1593 return err;
1594
1595 /* retrieve response parameters */
1596 rsp_params = (struct dpni_rsp_get_queue *)cmd.params;
1597 queue->destination.id = le32_to_cpu(rsp_params->dest_id);
1598 queue->destination.priority = rsp_params->dest_prio;
1599 queue->destination.type = dpni_get_field(rsp_params->flags,
1600 DEST_TYPE);
1601 queue->flc.stash_control = dpni_get_field(rsp_params->flags,
1602 STASH_CTRL);
1603 queue->destination.hold_active = dpni_get_field(rsp_params->flags,
1604 HOLD_ACTIVE);
1605 queue->flc.value = le64_to_cpu(rsp_params->flc);
1606 queue->user_context = le64_to_cpu(rsp_params->user_context);
1607 qid->fqid = le32_to_cpu(rsp_params->fqid);
1608 qid->qdbin = le16_to_cpu(rsp_params->qdbin);
1609
1610 return 0;
1611}
1612
1613/**
1614 * dpni_get_statistics() - Get DPNI statistics
1615 * @mc_io: Pointer to MC portal's I/O object
1616 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1617 * @token: Token of DPNI object
1618 * @page: Selects the statistics page to retrieve, see
1619 * DPNI_GET_STATISTICS output. Pages are numbered 0 to 6.
1620 * @stat: Structure containing the statistics
1621 *
1622 * Return: '0' on Success; Error code otherwise.
1623 */
1624int dpni_get_statistics(struct fsl_mc_io *mc_io,
1625 u32 cmd_flags,
1626 u16 token,
1627 u8 page,
1628 union dpni_statistics *stat)
1629{
1630 struct fsl_mc_command cmd = { 0 };
1631 struct dpni_cmd_get_statistics *cmd_params;
1632 struct dpni_rsp_get_statistics *rsp_params;
1633 int i, err;
1634
1635 /* prepare command */
1636 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
1637 cmd_flags,
1638 token);
1639 cmd_params = (struct dpni_cmd_get_statistics *)cmd.params;
1640 cmd_params->page_number = page;
1641
1642 /* send command to mc */
1643 err = mc_send_command(mc_io, cmd: &cmd);
1644 if (err)
1645 return err;
1646
1647 /* retrieve response parameters */
1648 rsp_params = (struct dpni_rsp_get_statistics *)cmd.params;
1649 for (i = 0; i < DPNI_STATISTICS_CNT; i++)
1650 stat->raw.counter[i] = le64_to_cpu(rsp_params->counter[i]);
1651
1652 return 0;
1653}
1654
1655/**
1656 * dpni_set_taildrop() - Set taildrop per queue or TC
1657 * @mc_io: Pointer to MC portal's I/O object
1658 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1659 * @token: Token of DPNI object
1660 * @cg_point: Congestion point
1661 * @qtype: Queue type on which the taildrop is configured.
1662 * Only Rx queues are supported for now
1663 * @tc: Traffic class to apply this taildrop to
1664 * @index: Index of the queue if the DPNI supports multiple queues for
1665 * traffic distribution. Ignored if CONGESTION_POINT is not 0.
1666 * @taildrop: Taildrop structure
1667 *
1668 * Return: '0' on Success; Error code otherwise.
1669 */
1670int dpni_set_taildrop(struct fsl_mc_io *mc_io,
1671 u32 cmd_flags,
1672 u16 token,
1673 enum dpni_congestion_point cg_point,
1674 enum dpni_queue_type qtype,
1675 u8 tc,
1676 u8 index,
1677 struct dpni_taildrop *taildrop)
1678{
1679 struct fsl_mc_command cmd = { 0 };
1680 struct dpni_cmd_set_taildrop *cmd_params;
1681
1682 /* prepare command */
1683 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TAILDROP,
1684 cmd_flags,
1685 token);
1686 cmd_params = (struct dpni_cmd_set_taildrop *)cmd.params;
1687 cmd_params->congestion_point = cg_point;
1688 cmd_params->qtype = qtype;
1689 cmd_params->tc = tc;
1690 cmd_params->index = index;
1691 dpni_set_field(cmd_params->enable, ENABLE, taildrop->enable);
1692 cmd_params->units = taildrop->units;
1693 cmd_params->threshold = cpu_to_le32(taildrop->threshold);
1694
1695 /* send command to mc */
1696 return mc_send_command(mc_io, cmd: &cmd);
1697}
1698
1699/**
1700 * dpni_get_taildrop() - Get taildrop information
1701 * @mc_io: Pointer to MC portal's I/O object
1702 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1703 * @token: Token of DPNI object
1704 * @cg_point: Congestion point
1705 * @qtype: Queue type on which the taildrop is configured.
1706 * Only Rx queues are supported for now
1707 * @tc: Traffic class to apply this taildrop to
1708 * @index: Index of the queue if the DPNI supports multiple queues for
1709 * traffic distribution. Ignored if CONGESTION_POINT is not 0.
1710 * @taildrop: Taildrop structure
1711 *
1712 * Return: '0' on Success; Error code otherwise.
1713 */
1714int dpni_get_taildrop(struct fsl_mc_io *mc_io,
1715 u32 cmd_flags,
1716 u16 token,
1717 enum dpni_congestion_point cg_point,
1718 enum dpni_queue_type qtype,
1719 u8 tc,
1720 u8 index,
1721 struct dpni_taildrop *taildrop)
1722{
1723 struct fsl_mc_command cmd = { 0 };
1724 struct dpni_cmd_get_taildrop *cmd_params;
1725 struct dpni_rsp_get_taildrop *rsp_params;
1726 int err;
1727
1728 /* prepare command */
1729 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TAILDROP,
1730 cmd_flags,
1731 token);
1732 cmd_params = (struct dpni_cmd_get_taildrop *)cmd.params;
1733 cmd_params->congestion_point = cg_point;
1734 cmd_params->qtype = qtype;
1735 cmd_params->tc = tc;
1736 cmd_params->index = index;
1737
1738 /* send command to mc */
1739 err = mc_send_command(mc_io, cmd: &cmd);
1740 if (err)
1741 return err;
1742
1743 /* retrieve response parameters */
1744 rsp_params = (struct dpni_rsp_get_taildrop *)cmd.params;
1745 taildrop->enable = dpni_get_field(rsp_params->enable, ENABLE);
1746 taildrop->units = rsp_params->units;
1747 taildrop->threshold = le32_to_cpu(rsp_params->threshold);
1748
1749 return 0;
1750}
1751
1752/**
1753 * dpni_get_api_version() - Get Data Path Network Interface API version
1754 * @mc_io: Pointer to MC portal's I/O object
1755 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1756 * @major_ver: Major version of data path network interface API
1757 * @minor_ver: Minor version of data path network interface API
1758 *
1759 * Return: '0' on Success; Error code otherwise.
1760 */
1761int dpni_get_api_version(struct fsl_mc_io *mc_io,
1762 u32 cmd_flags,
1763 u16 *major_ver,
1764 u16 *minor_ver)
1765{
1766 struct dpni_rsp_get_api_version *rsp_params;
1767 struct fsl_mc_command cmd = { 0 };
1768 int err;
1769
1770 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
1771 cmd_flags, token: 0);
1772
1773 err = mc_send_command(mc_io, cmd: &cmd);
1774 if (err)
1775 return err;
1776
1777 rsp_params = (struct dpni_rsp_get_api_version *)cmd.params;
1778 *major_ver = le16_to_cpu(rsp_params->major);
1779 *minor_ver = le16_to_cpu(rsp_params->minor);
1780
1781 return 0;
1782}
1783
1784/**
1785 * dpni_set_rx_fs_dist() - Set Rx flow steering distribution
1786 * @mc_io: Pointer to MC portal's I/O object
1787 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1788 * @token: Token of DPNI object
1789 * @cfg: Distribution configuration
1790 *
1791 * If the FS is already enabled with a previous call the classification
1792 * key will be changed but all the table rules are kept. If the
1793 * existing rules do not match the key the results will not be
1794 * predictable. It is the user responsibility to keep key integrity.
1795 * If cfg.enable is set to 1 the command will create a flow steering table
1796 * and will classify packets according to this table. The packets that
1797 * miss all the table rules will be classified according to settings
1798 * made in dpni_set_rx_hash_dist()
1799 * If cfg.enable is set to 0 the command will clear flow steering table.
1800 * The packets will be classified according to settings made in
1801 * dpni_set_rx_hash_dist()
1802 *
1803 * Return: '0' on Success; Error code otherwise.
1804 */
1805int dpni_set_rx_fs_dist(struct fsl_mc_io *mc_io,
1806 u32 cmd_flags,
1807 u16 token,
1808 const struct dpni_rx_dist_cfg *cfg)
1809{
1810 struct dpni_cmd_set_rx_fs_dist *cmd_params;
1811 struct fsl_mc_command cmd = { 0 };
1812
1813 /* prepare command */
1814 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_FS_DIST,
1815 cmd_flags,
1816 token);
1817 cmd_params = (struct dpni_cmd_set_rx_fs_dist *)cmd.params;
1818 cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
1819 dpni_set_field(cmd_params->enable, RX_FS_DIST_ENABLE, cfg->enable);
1820 cmd_params->tc = cfg->tc;
1821 cmd_params->miss_flow_id = cpu_to_le16(cfg->fs_miss_flow_id);
1822 cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1823
1824 /* send command to mc*/
1825 return mc_send_command(mc_io, cmd: &cmd);
1826}
1827
1828/**
1829 * dpni_set_rx_hash_dist() - Set Rx hash distribution
1830 * @mc_io: Pointer to MC portal's I/O object
1831 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1832 * @token: Token of DPNI object
1833 * @cfg: Distribution configuration
1834 * If cfg.enable is set to 1 the packets will be classified using a hash
1835 * function based on the key received in cfg.key_cfg_iova parameter.
1836 * If cfg.enable is set to 0 the packets will be sent to the default queue
1837 *
1838 * Return: '0' on Success; Error code otherwise.
1839 */
1840int dpni_set_rx_hash_dist(struct fsl_mc_io *mc_io,
1841 u32 cmd_flags,
1842 u16 token,
1843 const struct dpni_rx_dist_cfg *cfg)
1844{
1845 struct dpni_cmd_set_rx_hash_dist *cmd_params;
1846 struct fsl_mc_command cmd = { 0 };
1847
1848 /* prepare command */
1849 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_HASH_DIST,
1850 cmd_flags,
1851 token);
1852 cmd_params = (struct dpni_cmd_set_rx_hash_dist *)cmd.params;
1853 cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
1854 dpni_set_field(cmd_params->enable, RX_HASH_DIST_ENABLE, cfg->enable);
1855 cmd_params->tc = cfg->tc;
1856 cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1857
1858 /* send command to mc*/
1859 return mc_send_command(mc_io, cmd: &cmd);
1860}
1861
1862/**
1863 * dpni_add_fs_entry() - Add Flow Steering entry for a specific traffic class
1864 * (to select a flow ID)
1865 * @mc_io: Pointer to MC portal's I/O object
1866 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1867 * @token: Token of DPNI object
1868 * @tc_id: Traffic class selection (0-7)
1869 * @index: Location in the FS table where to insert the entry.
1870 * Only relevant if MASKING is enabled for FS
1871 * classification on this DPNI, it is ignored for exact match.
1872 * @cfg: Flow steering rule to add
1873 * @action: Action to be taken as result of a classification hit
1874 *
1875 * Return: '0' on Success; Error code otherwise.
1876 */
1877int dpni_add_fs_entry(struct fsl_mc_io *mc_io,
1878 u32 cmd_flags,
1879 u16 token,
1880 u8 tc_id,
1881 u16 index,
1882 const struct dpni_rule_cfg *cfg,
1883 const struct dpni_fs_action_cfg *action)
1884{
1885 struct dpni_cmd_add_fs_entry *cmd_params;
1886 struct fsl_mc_command cmd = { 0 };
1887
1888 /* prepare command */
1889 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_FS_ENT,
1890 cmd_flags,
1891 token);
1892 cmd_params = (struct dpni_cmd_add_fs_entry *)cmd.params;
1893 cmd_params->tc_id = tc_id;
1894 cmd_params->key_size = cfg->key_size;
1895 cmd_params->index = cpu_to_le16(index);
1896 cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
1897 cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
1898 cmd_params->options = cpu_to_le16(action->options);
1899 cmd_params->flow_id = cpu_to_le16(action->flow_id);
1900 cmd_params->flc = cpu_to_le64(action->flc);
1901
1902 /* send command to mc*/
1903 return mc_send_command(mc_io, cmd: &cmd);
1904}
1905
1906/**
1907 * dpni_remove_fs_entry() - Remove Flow Steering entry from a specific
1908 * traffic class
1909 * @mc_io: Pointer to MC portal's I/O object
1910 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1911 * @token: Token of DPNI object
1912 * @tc_id: Traffic class selection (0-7)
1913 * @cfg: Flow steering rule to remove
1914 *
1915 * Return: '0' on Success; Error code otherwise.
1916 */
1917int dpni_remove_fs_entry(struct fsl_mc_io *mc_io,
1918 u32 cmd_flags,
1919 u16 token,
1920 u8 tc_id,
1921 const struct dpni_rule_cfg *cfg)
1922{
1923 struct dpni_cmd_remove_fs_entry *cmd_params;
1924 struct fsl_mc_command cmd = { 0 };
1925
1926 /* prepare command */
1927 cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_FS_ENT,
1928 cmd_flags,
1929 token);
1930 cmd_params = (struct dpni_cmd_remove_fs_entry *)cmd.params;
1931 cmd_params->tc_id = tc_id;
1932 cmd_params->key_size = cfg->key_size;
1933 cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
1934 cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
1935
1936 /* send command to mc*/
1937 return mc_send_command(mc_io, cmd: &cmd);
1938}
1939
1940/**
1941 * dpni_set_qos_table() - Set QoS mapping table
1942 * @mc_io: Pointer to MC portal's I/O object
1943 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1944 * @token: Token of DPNI object
1945 * @cfg: QoS table configuration
1946 *
1947 * This function and all QoS-related functions require that
1948 *'max_tcs > 1' was set at DPNI creation.
1949 *
1950 * warning: Before calling this function, call dpkg_prepare_key_cfg() to
1951 * prepare the key_cfg_iova parameter
1952 *
1953 * Return: '0' on Success; Error code otherwise.
1954 */
1955int dpni_set_qos_table(struct fsl_mc_io *mc_io,
1956 u32 cmd_flags,
1957 u16 token,
1958 const struct dpni_qos_tbl_cfg *cfg)
1959{
1960 struct dpni_cmd_set_qos_table *cmd_params;
1961 struct fsl_mc_command cmd = { 0 };
1962
1963 /* prepare command */
1964 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QOS_TBL,
1965 cmd_flags,
1966 token);
1967 cmd_params = (struct dpni_cmd_set_qos_table *)cmd.params;
1968 cmd_params->default_tc = cfg->default_tc;
1969 cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1970 dpni_set_field(cmd_params->discard_on_miss, DISCARD_ON_MISS,
1971 cfg->discard_on_miss);
1972
1973 /* send command to mc*/
1974 return mc_send_command(mc_io, cmd: &cmd);
1975}
1976
1977/**
1978 * dpni_add_qos_entry() - Add QoS mapping entry (to select a traffic class)
1979 * @mc_io: Pointer to MC portal's I/O object
1980 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1981 * @token: Token of DPNI object
1982 * @cfg: QoS rule to add
1983 * @tc_id: Traffic class selection (0-7)
1984 * @index: Location in the QoS table where to insert the entry.
1985 * Only relevant if MASKING is enabled for QoS classification on
1986 * this DPNI, it is ignored for exact match.
1987 *
1988 * Return: '0' on Success; Error code otherwise.
1989 */
1990int dpni_add_qos_entry(struct fsl_mc_io *mc_io,
1991 u32 cmd_flags,
1992 u16 token,
1993 const struct dpni_rule_cfg *cfg,
1994 u8 tc_id,
1995 u16 index)
1996{
1997 struct dpni_cmd_add_qos_entry *cmd_params;
1998 struct fsl_mc_command cmd = { 0 };
1999
2000 /* prepare command */
2001 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_QOS_ENT,
2002 cmd_flags,
2003 token);
2004 cmd_params = (struct dpni_cmd_add_qos_entry *)cmd.params;
2005 cmd_params->tc_id = tc_id;
2006 cmd_params->key_size = cfg->key_size;
2007 cmd_params->index = cpu_to_le16(index);
2008 cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
2009 cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
2010
2011 /* send command to mc*/
2012 return mc_send_command(mc_io, cmd: &cmd);
2013}
2014
2015/**
2016 * dpni_remove_qos_entry() - Remove QoS mapping entry
2017 * @mc_io: Pointer to MC portal's I/O object
2018 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2019 * @token: Token of DPNI object
2020 * @cfg: QoS rule to remove
2021 *
2022 * Return: '0' on Success; Error code otherwise.
2023 */
2024int dpni_remove_qos_entry(struct fsl_mc_io *mc_io,
2025 u32 cmd_flags,
2026 u16 token,
2027 const struct dpni_rule_cfg *cfg)
2028{
2029 struct dpni_cmd_remove_qos_entry *cmd_params;
2030 struct fsl_mc_command cmd = { 0 };
2031
2032 /* prepare command */
2033 cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_QOS_ENT,
2034 cmd_flags,
2035 token);
2036 cmd_params = (struct dpni_cmd_remove_qos_entry *)cmd.params;
2037 cmd_params->key_size = cfg->key_size;
2038 cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
2039 cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
2040
2041 /* send command to mc*/
2042 return mc_send_command(mc_io, cmd: &cmd);
2043}
2044
2045/**
2046 * dpni_clear_qos_table() - Clear all QoS mapping entries
2047 * @mc_io: Pointer to MC portal's I/O object
2048 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2049 * @token: Token of DPNI object
2050 *
2051 * Following this function call, all frames are directed to
2052 * the default traffic class (0)
2053 *
2054 * Return: '0' on Success; Error code otherwise.
2055 */
2056int dpni_clear_qos_table(struct fsl_mc_io *mc_io,
2057 u32 cmd_flags,
2058 u16 token)
2059{
2060 struct fsl_mc_command cmd = { 0 };
2061
2062 /* prepare command */
2063 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_QOS_TBL,
2064 cmd_flags,
2065 token);
2066
2067 /* send command to mc*/
2068 return mc_send_command(mc_io, cmd: &cmd);
2069}
2070
2071/**
2072 * dpni_set_tx_shaping() - Set the transmit shaping
2073 * @mc_io: Pointer to MC portal's I/O object
2074 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2075 * @token: Token of DPNI object
2076 * @tx_cr_shaper: TX committed rate shaping configuration
2077 * @tx_er_shaper: TX excess rate shaping configuration
2078 * @coupled: Committed and excess rate shapers are coupled
2079 *
2080 * Return: '0' on Success; Error code otherwise.
2081 */
2082int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,
2083 u32 cmd_flags,
2084 u16 token,
2085 const struct dpni_tx_shaping_cfg *tx_cr_shaper,
2086 const struct dpni_tx_shaping_cfg *tx_er_shaper,
2087 int coupled)
2088{
2089 struct dpni_cmd_set_tx_shaping *cmd_params;
2090 struct fsl_mc_command cmd = { 0 };
2091
2092 /* prepare command */
2093 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_SHAPING,
2094 cmd_flags,
2095 token);
2096 cmd_params = (struct dpni_cmd_set_tx_shaping *)cmd.params;
2097 cmd_params->tx_cr_max_burst_size = cpu_to_le16(tx_cr_shaper->max_burst_size);
2098 cmd_params->tx_er_max_burst_size = cpu_to_le16(tx_er_shaper->max_burst_size);
2099 cmd_params->tx_cr_rate_limit = cpu_to_le32(tx_cr_shaper->rate_limit);
2100 cmd_params->tx_er_rate_limit = cpu_to_le32(tx_er_shaper->rate_limit);
2101 dpni_set_field(cmd_params->coupled, COUPLED, coupled);
2102
2103 /* send command to mc*/
2104 return mc_send_command(mc_io, cmd: &cmd);
2105}
2106
2107/**
2108 * dpni_get_single_step_cfg() - return current configuration for
2109 * single step PTP
2110 * @mc_io: Pointer to MC portal's I/O object
2111 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2112 * @token: Token of DPNI object
2113 * @ptp_cfg: ptp single step configuration
2114 *
2115 * Return: '0' on Success; Error code otherwise.
2116 *
2117 */
2118int dpni_get_single_step_cfg(struct fsl_mc_io *mc_io,
2119 u32 cmd_flags,
2120 u16 token,
2121 struct dpni_single_step_cfg *ptp_cfg)
2122{
2123 struct dpni_rsp_single_step_cfg *rsp_params;
2124 struct fsl_mc_command cmd = { 0 };
2125 int err;
2126
2127 /* prepare command */
2128 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_SINGLE_STEP_CFG,
2129 cmd_flags, token);
2130 /* send command to mc*/
2131 err = mc_send_command(mc_io, cmd: &cmd);
2132 if (err)
2133 return err;
2134
2135 /* read command response */
2136 rsp_params = (struct dpni_rsp_single_step_cfg *)cmd.params;
2137 ptp_cfg->offset = le16_to_cpu(rsp_params->offset);
2138 ptp_cfg->en = dpni_get_field(le16_to_cpu(rsp_params->flags),
2139 PTP_ENABLE) ? 1 : 0;
2140 ptp_cfg->ch_update = dpni_get_field(le16_to_cpu(rsp_params->flags),
2141 PTP_CH_UPDATE) ? 1 : 0;
2142 ptp_cfg->peer_delay = le32_to_cpu(rsp_params->peer_delay);
2143 ptp_cfg->ptp_onestep_reg_base =
2144 le32_to_cpu(rsp_params->ptp_onestep_reg_base);
2145
2146 return err;
2147}
2148
2149/**
2150 * dpni_set_single_step_cfg() - enable/disable and configure single step PTP
2151 * @mc_io: Pointer to MC portal's I/O object
2152 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2153 * @token: Token of DPNI object
2154 * @ptp_cfg: ptp single step configuration
2155 *
2156 * Return: '0' on Success; Error code otherwise.
2157 *
2158 * The function has effect only when dpni object is connected to a dpmac
2159 * object. If the dpni is not connected to a dpmac the configuration will
2160 * be stored inside and applied when connection is made.
2161 */
2162int dpni_set_single_step_cfg(struct fsl_mc_io *mc_io,
2163 u32 cmd_flags,
2164 u16 token,
2165 struct dpni_single_step_cfg *ptp_cfg)
2166{
2167 struct dpni_cmd_single_step_cfg *cmd_params;
2168 struct fsl_mc_command cmd = { 0 };
2169 u16 flags;
2170
2171 /* prepare command */
2172 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_SINGLE_STEP_CFG,
2173 cmd_flags, token);
2174 cmd_params = (struct dpni_cmd_single_step_cfg *)cmd.params;
2175 cmd_params->offset = cpu_to_le16(ptp_cfg->offset);
2176 cmd_params->peer_delay = cpu_to_le32(ptp_cfg->peer_delay);
2177
2178 flags = le16_to_cpu(cmd_params->flags);
2179 dpni_set_field(flags, PTP_ENABLE, !!ptp_cfg->en);
2180 dpni_set_field(flags, PTP_CH_UPDATE, !!ptp_cfg->ch_update);
2181 cmd_params->flags = cpu_to_le16(flags);
2182
2183 /* send command to mc*/
2184 return mc_send_command(mc_io, cmd: &cmd);
2185}
2186

source code of linux/drivers/net/ethernet/freescale/dpaa2/dpni.c