2186 lines · c
1// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)2/* Copyright 2013-2016 Freescale Semiconductor Inc.3 * Copyright 2016 NXP4 * Copyright 2020 NXP5 */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 parameters14 * @cfg: defining a full Key Generation profile (rule)15 * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA16 *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 object80 * @mc_io: Pointer to MC portal's I/O object81 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'82 * @dpni_id: DPNI unique ID83 * @token: Returned token; use in subsequent API calls84 *85 * This function can be used to open a control session for an86 * already created object; an object may have been declared in87 * 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 MC90 * portal; this token must be used in all subsequent commands for91 * 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 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);114 if (err)115 return err;116 117 /* retrieve response parameters */118 *token = mc_cmd_hdr_read_token(&cmd);119 120 return 0;121}122 123/**124 * dpni_close() - Close the control session of the object125 * @mc_io: Pointer to MC portal's I/O object126 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'127 * @token: Token of DPNI object128 *129 * After this function is called, no further operations are130 * 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);147}148 149/**150 * dpni_set_pools() - Set buffer pools configuration151 * @mc_io: Pointer to MC portal's I/O object152 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'153 * @token: Token of DPNI object154 * @cfg: Buffer pools configuration155 *156 * mandatory for DPNI operation157 * warning:Allowed only when DPNI is disabled158 *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);190}191 192/**193 * dpni_enable() - Enable the DPNI, allow sending and receiving frames.194 * @mc_io: Pointer to MC portal's I/O object195 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'196 * @token: Token of DPNI object197 *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);213}214 215/**216 * dpni_disable() - Disable the DPNI, stop sending and receiving frames.217 * @mc_io: Pointer to MC portal's I/O object218 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'219 * @token: Token of DPNI object220 *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);236}237 238/**239 * dpni_is_enabled() - Check if the DPNI is enabled.240 * @mc_io: Pointer to MC portal's I/O object241 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'242 * @token: Token of DPNI object243 * @en: Returns '1' if object is enabled; '0' otherwise244 *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);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 object276 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'277 * @token: Token of DPNI object278 *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);294}295 296/**297 * dpni_set_irq_enable() - Set overall interrupt state.298 * @mc_io: Pointer to MC portal's I/O object299 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'300 * @token: Token of DPNI object301 * @irq_index: The interrupt index to configure302 * @en: Interrupt state: - enable = 1, disable = 0303 *304 * Allows GPP software to control when interrupts are generated.305 * Each interrupt can have up to 32 causes. The enable/disable control's the306 * overall interrupt state. if the interrupt is disabled no causes will cause307 * 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);330}331 332/**333 * dpni_get_irq_enable() - Get overall interrupt state334 * @mc_io: Pointer to MC portal's I/O object335 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'336 * @token: Token of DPNI object337 * @irq_index: The interrupt index to configure338 * @en: Returned interrupt state - enable = 1, disable = 0339 *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);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 object376 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'377 * @token: Token of DPNI object378 * @irq_index: The interrupt index to configure379 * @mask: event mask to trigger interrupt;380 * each bit:381 * 0 = ignore event382 * 1 = consider event for asserting IRQ383 *384 * Every interrupt can have up to 32 causes and the interrupt model supports385 * masking/unmasking each cause independently386 *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);408}409 410/**411 * dpni_get_irq_mask() - Get interrupt mask.412 * @mc_io: Pointer to MC portal's I/O object413 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'414 * @token: Token of DPNI object415 * @irq_index: The interrupt index to configure416 * @mask: Returned event mask to trigger interrupt417 *418 * Every interrupt can have up to 32 causes and the interrupt model supports419 * masking/unmasking each cause independently420 *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);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 object456 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'457 * @token: Token of DPNI object458 * @irq_index: The interrupt index to configure459 * @status: Returned interrupts status - one bit per cause:460 * 0 = no interrupt pending461 * 1 = interrupt pending462 *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);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 status498 * @mc_io: Pointer to MC portal's I/O object499 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'500 * @token: Token of DPNI object501 * @irq_index: The interrupt index to configure502 * @status: bits to clear (W1C) - one bit per cause:503 * 0 = don't change504 * 1 = clear status bit505 *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);527}528 529/**530 * dpni_get_attributes() - Retrieve DPNI attributes.531 * @mc_io: Pointer to MC portal's I/O object532 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'533 * @token: Token of DPNI object534 * @attr: Object's attributes535 *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);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 behavior576 * @mc_io: Pointer to MC portal's I/O object577 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'578 * @token: Token of DPNI object579 * @cfg: Errors configuration580 *581 * this function may be called numerous times with different582 * error masks583 *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);605}606 607/**608 * dpni_get_buffer_layout() - Retrieve buffer layout attributes.609 * @mc_io: Pointer to MC portal's I/O object610 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'611 * @token: Token of DPNI object612 * @qtype: Type of queue to retrieve configuration for613 * @layout: Returns buffer layout attributes614 *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);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 object656 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'657 * @token: Token of DPNI object658 * @qtype: Type of queue this configuration applies to659 * @layout: Buffer layout configuration660 *661 * Return: '0' on Success; Error code otherwise.662 *663 * @warning Allowed only when DPNI is disabled664 */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);691}692 693/**694 * dpni_set_offload() - Set DPNI offload configuration.695 * @mc_io: Pointer to MC portal's I/O object696 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'697 * @token: Token of DPNI object698 * @type: Type of DPNI offload699 * @config: Offload configuration.700 * For checksum offloads, non-zero value enables the offload701 *702 * Return: '0' on Success; Error code otherwise.703 *704 * @warning Allowed only when DPNI is disabled705 */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);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);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 used758 * for enqueue operations759 * @mc_io: Pointer to MC portal's I/O object760 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'761 * @token: Token of DPNI object762 * @qtype: Type of queue to receive QDID for763 * @qdid: Returned virtual QDID value that should be used as an argument764 * in all enqueue operations765 *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);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 object801 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'802 * @token: Token of DPNI object803 * @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);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 object836 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'837 * @token: Token of DPNI object838 * @cfg: Link configuration839 *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);860}861 862/**863 * dpni_get_link_cfg() - return the link configuration864 * @mc_io: Pointer to MC portal's I/O object865 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'866 * @token: Token of DPNI object867 * @cfg: Link configuration from dpni object868 *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);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 object901 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'902 * @token: Token of DPNI object903 * @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);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 object938 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'939 * @token: Token of DPNI object940 * @max_frame_length: Maximum received frame length (in941 * bytes); frame is discarded if its942 * length exceeds this value943 *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);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 object968 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'969 * @token: Token of DPNI object970 * @max_frame_length: Maximum received frame length (in971 * bytes); frame is discarded if its972 * length exceeds this value973 *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);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 mode1004 * @mc_io: Pointer to MC portal's I/O object1005 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1006 * @token: Token of DPNI object1007 * @en: Set to '1' to enable; '0' to disable1008 *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);1028}1029 1030/**1031 * dpni_get_multicast_promisc() - Get multicast promiscuous mode1032 * @mc_io: Pointer to MC portal's I/O object1033 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1034 * @token: Token of DPNI object1035 * @en: Returns '1' if enabled; '0' otherwise1036 *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);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 mode1067 * @mc_io: Pointer to MC portal's I/O object1068 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1069 * @token: Token of DPNI object1070 * @en: Set to '1' to enable; '0' to disable1071 *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);1091}1092 1093/**1094 * dpni_get_unicast_promisc() - Get unicast promiscuous mode1095 * @mc_io: Pointer to MC portal's I/O object1096 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1097 * @token: Token of DPNI object1098 * @en: Returns '1' if enabled; '0' otherwise1099 *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);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 address1130 * @mc_io: Pointer to MC portal's I/O object1131 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1132 * @token: Token of DPNI object1133 * @mac_addr: MAC address to set as primary address1134 *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);1156}1157 1158/**1159 * dpni_get_primary_mac_addr() - Get the primary MAC address1160 * @mc_io: Pointer to MC portal's I/O object1161 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1162 * @token: Token of DPNI object1163 * @mac_addr: Returned MAC address1164 *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);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 physical1196 * port the DPNI is attached to1197 * @mc_io: Pointer to MC portal's I/O object1198 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1199 * @token: Token of DPNI object1200 * @mac_addr: MAC address of the physical port, if any, otherwise 01201 *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);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 mode1235 * @mc_io: Pointer to MC portal's I/O object1236 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1237 * @token: Token of DPNI object1238 * @en: Set to '1' to enable; '0' to disable1239 *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);1259}1260 1261/**1262 * dpni_add_vlan_id() - Add VLAN ID filter1263 * @mc_io: Pointer to MC portal's I/O object1264 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1265 * @token: Token of DPNI object1266 * @vlan_id: VLAN ID to add1267 * @flags: 0 - tc_id and flow_id will be ignored.1268 * Pkt with this vlan_id will be passed to the next1269 * classification stages1270 * DPNI_VLAN_SET_QUEUE_ACTION1271 * Pkt with this vlan_id will be forward directly to1272 * queue defined by the tc_id and flow_id1273 *1274 * @tc_id: Traffic class selection (0-7)1275 * @flow_id: Selects the specific queue out of the set allocated for the1276 * same as tc_id. Value must be in range 0 to NUM_QUEUES - 11277 *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);1298}1299 1300/**1301 * dpni_remove_vlan_id() - Remove VLAN ID filter1302 * @mc_io: Pointer to MC portal's I/O object1303 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1304 * @token: Token of DPNI object1305 * @vlan_id: VLAN ID to remove1306 *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);1324}1325 1326/**1327 * dpni_add_mac_addr() - Add MAC address filter1328 * @mc_io: Pointer to MC portal's I/O object1329 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1330 * @token: Token of DPNI object1331 * @mac_addr: MAC address to add1332 *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);1354}1355 1356/**1357 * dpni_remove_mac_addr() - Remove MAC address filter1358 * @mc_io: Pointer to MC portal's I/O object1359 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1360 * @token: Token of DPNI object1361 * @mac_addr: MAC address to remove1362 *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);1384}1385 1386/**1387 * dpni_clear_mac_filters() - Clear all unicast and/or multicast MAC filters1388 * @mc_io: Pointer to MC portal's I/O object1389 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1390 * @token: Token of DPNI object1391 * @unicast: Set to '1' to clear unicast addresses1392 * @multicast: Set to '1' to clear multicast addresses1393 *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);1417}1418 1419/**1420 * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration1421 * @mc_io: Pointer to MC portal's I/O object1422 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1423 * @token: Token of DPNI object1424 * @tc_id: Traffic class selection (0-7)1425 * @cfg: Traffic class distribution configuration1426 *1427 * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()1428 * first to prepare the key_cfg_iova parameter1429 *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);1455}1456 1457/**1458 * dpni_set_congestion_notification() - Set traffic class congestion1459 * notification configuration1460 * @mc_io: Pointer to MC portal's I/O object1461 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1462 * @token: Token of DPNI object1463 * @qtype: Type of queue - Rx, Tx and Tx confirm types are supported1464 * @tc_id: Traffic class selection (0-7)1465 * @cfg: Congestion notification configuration1466 *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);1501}1502 1503/**1504 * dpni_set_queue() - Set queue parameters1505 * @mc_io: Pointer to MC portal's I/O object1506 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1507 * @token: Token of DPNI object1508 * @qtype: Type of queue - all queue types are supported, although1509 * the command is ignored for Tx1510 * @tc: Traffic class, in range 0 to NUM_TCS - 11511 * @index: Selects the specific queue out of the set allocated for the1512 * same TC. Value must be in range 0 to NUM_QUEUES - 11513 * @options: A combination of DPNI_QUEUE_OPT_ values that control what1514 * configuration options are set on the queue1515 * @queue: Queue structure1516 *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);1551}1552 1553/**1554 * dpni_get_queue() - Get queue parameters1555 * @mc_io: Pointer to MC portal's I/O object1556 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1557 * @token: Token of DPNI object1558 * @qtype: Type of queue - all queue types are supported1559 * @tc: Traffic class, in range 0 to NUM_TCS - 11560 * @index: Selects the specific queue out of the set allocated for the1561 * same TC. Value must be in range 0 to NUM_QUEUES - 11562 * @queue: Queue configuration structure1563 * @qid: Queue identification1564 *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);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 statistics1615 * @mc_io: Pointer to MC portal's I/O object1616 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1617 * @token: Token of DPNI object1618 * @page: Selects the statistics page to retrieve, see1619 * DPNI_GET_STATISTICS output. Pages are numbered 0 to 6.1620 * @stat: Structure containing the statistics1621 *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);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 TC1657 * @mc_io: Pointer to MC portal's I/O object1658 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1659 * @token: Token of DPNI object1660 * @cg_point: Congestion point1661 * @qtype: Queue type on which the taildrop is configured.1662 * Only Rx queues are supported for now1663 * @tc: Traffic class to apply this taildrop to1664 * @index: Index of the queue if the DPNI supports multiple queues for1665 * traffic distribution. Ignored if CONGESTION_POINT is not 0.1666 * @taildrop: Taildrop structure1667 *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);1697}1698 1699/**1700 * dpni_get_taildrop() - Get taildrop information1701 * @mc_io: Pointer to MC portal's I/O object1702 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1703 * @token: Token of DPNI object1704 * @cg_point: Congestion point1705 * @qtype: Queue type on which the taildrop is configured.1706 * Only Rx queues are supported for now1707 * @tc: Traffic class to apply this taildrop to1708 * @index: Index of the queue if the DPNI supports multiple queues for1709 * traffic distribution. Ignored if CONGESTION_POINT is not 0.1710 * @taildrop: Taildrop structure1711 *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);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 version1754 * @mc_io: Pointer to MC portal's I/O object1755 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1756 * @major_ver: Major version of data path network interface API1757 * @minor_ver: Minor version of data path network interface API1758 *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, 0);1772 1773 err = mc_send_command(mc_io, &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 distribution1786 * @mc_io: Pointer to MC portal's I/O object1787 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1788 * @token: Token of DPNI object1789 * @cfg: Distribution configuration1790 *1791 * If the FS is already enabled with a previous call the classification1792 * key will be changed but all the table rules are kept. If the1793 * existing rules do not match the key the results will not be1794 * 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 table1796 * and will classify packets according to this table. The packets that1797 * miss all the table rules will be classified according to settings1798 * 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 in1801 * 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);1826}1827 1828/**1829 * dpni_set_rx_hash_dist() - Set Rx hash distribution1830 * @mc_io: Pointer to MC portal's I/O object1831 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1832 * @token: Token of DPNI object1833 * @cfg: Distribution configuration1834 * If cfg.enable is set to 1 the packets will be classified using a hash1835 * 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 queue1837 *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);1860}1861 1862/**1863 * dpni_add_fs_entry() - Add Flow Steering entry for a specific traffic class1864 * (to select a flow ID)1865 * @mc_io: Pointer to MC portal's I/O object1866 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1867 * @token: Token of DPNI object1868 * @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 FS1871 * classification on this DPNI, it is ignored for exact match.1872 * @cfg: Flow steering rule to add1873 * @action: Action to be taken as result of a classification hit1874 *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);1904}1905 1906/**1907 * dpni_remove_fs_entry() - Remove Flow Steering entry from a specific1908 * traffic class1909 * @mc_io: Pointer to MC portal's I/O object1910 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1911 * @token: Token of DPNI object1912 * @tc_id: Traffic class selection (0-7)1913 * @cfg: Flow steering rule to remove1914 *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);1938}1939 1940/**1941 * dpni_set_qos_table() - Set QoS mapping table1942 * @mc_io: Pointer to MC portal's I/O object1943 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1944 * @token: Token of DPNI object1945 * @cfg: QoS table configuration1946 *1947 * This function and all QoS-related functions require that1948 *'max_tcs > 1' was set at DPNI creation.1949 *1950 * warning: Before calling this function, call dpkg_prepare_key_cfg() to1951 * prepare the key_cfg_iova parameter1952 *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);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 object1980 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1981 * @token: Token of DPNI object1982 * @cfg: QoS rule to add1983 * @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 on1986 * 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);2013}2014 2015/**2016 * dpni_remove_qos_entry() - Remove QoS mapping entry2017 * @mc_io: Pointer to MC portal's I/O object2018 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'2019 * @token: Token of DPNI object2020 * @cfg: QoS rule to remove2021 *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);2043}2044 2045/**2046 * dpni_clear_qos_table() - Clear all QoS mapping entries2047 * @mc_io: Pointer to MC portal's I/O object2048 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'2049 * @token: Token of DPNI object2050 *2051 * Following this function call, all frames are directed to2052 * 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);2069}2070 2071/**2072 * dpni_set_tx_shaping() - Set the transmit shaping2073 * @mc_io: Pointer to MC portal's I/O object2074 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'2075 * @token: Token of DPNI object2076 * @tx_cr_shaper: TX committed rate shaping configuration2077 * @tx_er_shaper: TX excess rate shaping configuration2078 * @coupled: Committed and excess rate shapers are coupled2079 *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);2105}2106 2107/**2108 * dpni_get_single_step_cfg() - return current configuration for2109 * single step PTP2110 * @mc_io: Pointer to MC portal's I/O object2111 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'2112 * @token: Token of DPNI object2113 * @ptp_cfg: ptp single step configuration2114 *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);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 PTP2151 * @mc_io: Pointer to MC portal's I/O object2152 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'2153 * @token: Token of DPNI object2154 * @ptp_cfg: ptp single step configuration2155 *2156 * Return: '0' on Success; Error code otherwise.2157 *2158 * The function has effect only when dpni object is connected to a dpmac2159 * object. If the dpni is not connected to a dpmac the configuration will2160 * 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);2185}2186