1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2 * 3 * Copyright 2013-2016 Freescale Semiconductor Inc. 4 * Copyright 2017-2019 NXP 5 * 6 */ 7 #include <fsl_mc_sys.h> 8 #include <fsl_mc_cmd.h> 9 #include <fsl_dpci.h> 10 #include <fsl_dpci_cmd.h> 11 12 /** 13 * dpci_open() - Open a control session for the specified object 14 * @mc_io: Pointer to MC portal's I/O object 15 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 16 * @dpci_id: DPCI unique ID 17 * @token: Returned token; use in subsequent API calls 18 * 19 * This function can be used to open a control session for an 20 * already created object; an object may have been declared in 21 * the DPL or by calling the dpci_create() function. 22 * This function returns a unique authentication token, 23 * associated with the specific object ID and the specific MC 24 * portal; this token must be used in all subsequent commands for 25 * this specific object. 26 * 27 * Return: '0' on Success; Error code otherwise. 28 */ 29 int dpci_open(struct fsl_mc_io *mc_io, 30 uint32_t cmd_flags, 31 int dpci_id, 32 uint16_t *token) 33 { 34 struct dpci_cmd_open *cmd_params; 35 struct mc_command cmd = { 0 }; 36 int err; 37 38 /* prepare command */ 39 cmd.header = mc_encode_cmd_header(DPCI_CMDID_OPEN, 40 cmd_flags, 41 0); 42 cmd_params = (struct dpci_cmd_open *)cmd.params; 43 cmd_params->dpci_id = cpu_to_le32(dpci_id); 44 45 /* send command to mc*/ 46 err = mc_send_command(mc_io, &cmd); 47 if (err) 48 return err; 49 50 /* retrieve response parameters */ 51 *token = mc_cmd_hdr_read_token(&cmd); 52 53 return 0; 54 } 55 56 /** 57 * dpci_close() - Close the control session of the object 58 * @mc_io: Pointer to MC portal's I/O object 59 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 60 * @token: Token of DPCI object 61 * 62 * After this function is called, no further operations are 63 * allowed on the object without opening a new control session. 64 * 65 * Return: '0' on Success; Error code otherwise. 66 */ 67 int dpci_close(struct fsl_mc_io *mc_io, 68 uint32_t cmd_flags, 69 uint16_t token) 70 { 71 struct mc_command cmd = { 0 }; 72 73 /* prepare command */ 74 cmd.header = mc_encode_cmd_header(DPCI_CMDID_CLOSE, 75 cmd_flags, 76 token); 77 78 /* send command to mc*/ 79 return mc_send_command(mc_io, &cmd); 80 } 81 82 /** 83 * dpci_create() - Create the DPCI object. 84 * @mc_io: Pointer to MC portal's I/O object 85 * @dprc_token: Parent container token; '0' for default container 86 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 87 * @cfg: Configuration structure 88 * @obj_id: Returned object id 89 * 90 * Create the DPCI object, allocate required resources and perform required 91 * initialization. 92 * 93 * The object can be created either by declaring it in the 94 * DPL file, or by calling this function. 95 * 96 * The function accepts an authentication token of a parent 97 * container that this object should be assigned to. The token 98 * can be '0' so the object will be assigned to the default container. 99 * The newly created object can be opened with the returned 100 * object id and using the container's associated tokens and MC portals. 101 * 102 * Return: '0' on Success; Error code otherwise. 103 */ 104 int dpci_create(struct fsl_mc_io *mc_io, 105 uint16_t dprc_token, 106 uint32_t cmd_flags, 107 const struct dpci_cfg *cfg, 108 uint32_t *obj_id) 109 { 110 struct dpci_cmd_create *cmd_params; 111 struct mc_command cmd = { 0 }; 112 int err; 113 114 /* prepare command */ 115 cmd.header = mc_encode_cmd_header(DPCI_CMDID_CREATE, 116 cmd_flags, 117 dprc_token); 118 cmd_params = (struct dpci_cmd_create *)cmd.params; 119 cmd_params->num_of_priorities = cfg->num_of_priorities; 120 121 /* send command to mc*/ 122 err = mc_send_command(mc_io, &cmd); 123 if (err) 124 return err; 125 126 /* retrieve response parameters */ 127 *obj_id = mc_cmd_read_object_id(&cmd); 128 129 return 0; 130 } 131 132 /** 133 * dpci_destroy() - Destroy the DPCI object and release all its resources. 134 * @mc_io: Pointer to MC portal's I/O object 135 * @dprc_token: Parent container token; '0' for default container 136 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 137 * @object_id: The object id; it must be a valid id within the container that 138 * created this object; 139 * 140 * The function accepts the authentication token of the parent container that 141 * created the object (not the one that currently owns the object). The object 142 * is searched within parent using the provided 'object_id'. 143 * All tokens to the object must be closed before calling destroy. 144 * 145 * Return: '0' on Success; error code otherwise. 146 */ 147 int dpci_destroy(struct fsl_mc_io *mc_io, 148 uint16_t dprc_token, 149 uint32_t cmd_flags, 150 uint32_t object_id) 151 { 152 struct dpci_cmd_destroy *cmd_params; 153 struct mc_command cmd = { 0 }; 154 155 /* prepare command */ 156 cmd.header = mc_encode_cmd_header(DPCI_CMDID_DESTROY, 157 cmd_flags, 158 dprc_token); 159 cmd_params = (struct dpci_cmd_destroy *)cmd.params; 160 cmd_params->dpci_id = cpu_to_le32(object_id); 161 162 /* send command to mc*/ 163 return mc_send_command(mc_io, &cmd); 164 } 165 166 /** 167 * dpci_enable() - Enable the DPCI, allow sending and receiving frames. 168 * @mc_io: Pointer to MC portal's I/O object 169 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 170 * @token: Token of DPCI object 171 * 172 * Return: '0' on Success; Error code otherwise. 173 */ 174 int dpci_enable(struct fsl_mc_io *mc_io, 175 uint32_t cmd_flags, 176 uint16_t token) 177 { 178 struct mc_command cmd = { 0 }; 179 180 /* prepare command */ 181 cmd.header = mc_encode_cmd_header(DPCI_CMDID_ENABLE, 182 cmd_flags, 183 token); 184 185 /* send command to mc*/ 186 return mc_send_command(mc_io, &cmd); 187 } 188 189 /** 190 * dpci_disable() - Disable the DPCI, stop sending and receiving frames. 191 * @mc_io: Pointer to MC portal's I/O object 192 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 193 * @token: Token of DPCI object 194 * 195 * Return: '0' on Success; Error code otherwise. 196 */ 197 int dpci_disable(struct fsl_mc_io *mc_io, 198 uint32_t cmd_flags, 199 uint16_t token) 200 { 201 struct mc_command cmd = { 0 }; 202 203 /* prepare command */ 204 cmd.header = mc_encode_cmd_header(DPCI_CMDID_DISABLE, 205 cmd_flags, 206 token); 207 208 /* send command to mc*/ 209 return mc_send_command(mc_io, &cmd); 210 } 211 212 /** 213 * dpci_is_enabled() - Check if the DPCI is enabled. 214 * @mc_io: Pointer to MC portal's I/O object 215 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 216 * @token: Token of DPCI object 217 * @en: Returns '1' if object is enabled; '0' otherwise 218 * 219 * Return: '0' on Success; Error code otherwise. 220 */ 221 int dpci_is_enabled(struct fsl_mc_io *mc_io, 222 uint32_t cmd_flags, 223 uint16_t token, 224 int *en) 225 { 226 struct dpci_rsp_is_enabled *rsp_params; 227 struct mc_command cmd = { 0 }; 228 int err; 229 230 /* prepare command */ 231 cmd.header = mc_encode_cmd_header(DPCI_CMDID_IS_ENABLED, cmd_flags, 232 token); 233 234 /* send command to mc*/ 235 err = mc_send_command(mc_io, &cmd); 236 if (err) 237 return err; 238 239 /* retrieve response parameters */ 240 rsp_params = (struct dpci_rsp_is_enabled *)cmd.params; 241 *en = dpci_get_field(rsp_params->en, ENABLE); 242 243 return 0; 244 } 245 246 /** 247 * dpci_reset() - Reset the DPCI, returns the object to initial state. 248 * @mc_io: Pointer to MC portal's I/O object 249 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 250 * @token: Token of DPCI object 251 * 252 * Return: '0' on Success; Error code otherwise. 253 */ 254 int dpci_reset(struct fsl_mc_io *mc_io, 255 uint32_t cmd_flags, 256 uint16_t token) 257 { 258 struct mc_command cmd = { 0 }; 259 260 /* prepare command */ 261 cmd.header = mc_encode_cmd_header(DPCI_CMDID_RESET, 262 cmd_flags, 263 token); 264 265 /* send command to mc*/ 266 return mc_send_command(mc_io, &cmd); 267 } 268 269 /** 270 * dpci_get_attributes() - Retrieve DPCI attributes. 271 * @mc_io: Pointer to MC portal's I/O object 272 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 273 * @token: Token of DPCI object 274 * @attr: Returned object's attributes 275 * 276 * Return: '0' on Success; Error code otherwise. 277 */ 278 int dpci_get_attributes(struct fsl_mc_io *mc_io, 279 uint32_t cmd_flags, 280 uint16_t token, 281 struct dpci_attr *attr) 282 { 283 struct dpci_rsp_get_attr *rsp_params; 284 struct mc_command cmd = { 0 }; 285 int err; 286 287 /* prepare command */ 288 cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_ATTR, 289 cmd_flags, 290 token); 291 292 /* send command to mc*/ 293 err = mc_send_command(mc_io, &cmd); 294 if (err) 295 return err; 296 297 /* retrieve response parameters */ 298 rsp_params = (struct dpci_rsp_get_attr *)cmd.params; 299 attr->id = le32_to_cpu(rsp_params->id); 300 attr->num_of_priorities = rsp_params->num_of_priorities; 301 302 return 0; 303 } 304 305 /** 306 * dpci_set_rx_queue() - Set Rx queue configuration 307 * @mc_io: Pointer to MC portal's I/O object 308 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 309 * @token: Token of DPCI object 310 * @priority: Select the queue relative to number of 311 * priorities configured at DPCI creation; use 312 * DPCI_ALL_QUEUES to configure all Rx queues 313 * identically. 314 * @cfg: Rx queue configuration 315 * 316 * Return: '0' on Success; Error code otherwise. 317 */ 318 int dpci_set_rx_queue(struct fsl_mc_io *mc_io, 319 uint32_t cmd_flags, 320 uint16_t token, 321 uint8_t priority, 322 const struct dpci_rx_queue_cfg *cfg) 323 { 324 struct dpci_cmd_set_rx_queue *cmd_params; 325 struct mc_command cmd = { 0 }; 326 327 /* prepare command */ 328 cmd.header = mc_encode_cmd_header(DPCI_CMDID_SET_RX_QUEUE, 329 cmd_flags, 330 token); 331 cmd_params = (struct dpci_cmd_set_rx_queue *)cmd.params; 332 cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id); 333 cmd_params->dest_priority = cfg->dest_cfg.priority; 334 cmd_params->priority = priority; 335 cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx); 336 cmd_params->options = cpu_to_le32(cfg->options); 337 dpci_set_field(cmd_params->dest_type, 338 DEST_TYPE, 339 cfg->dest_cfg.dest_type); 340 dpci_set_field(cmd_params->dest_type, 341 ORDER_PRESERVATION, 342 cfg->order_preservation_en); 343 344 /* send command to mc*/ 345 return mc_send_command(mc_io, &cmd); 346 } 347 348 /** 349 * dpci_get_rx_queue() - Retrieve Rx queue attributes. 350 * @mc_io: Pointer to MC portal's I/O object 351 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 352 * @token: Token of DPCI object 353 * @priority: Select the queue relative to number of 354 * priorities configured at DPCI creation 355 * @attr: Returned Rx queue attributes 356 * 357 * Return: '0' on Success; Error code otherwise. 358 */ 359 int dpci_get_rx_queue(struct fsl_mc_io *mc_io, 360 uint32_t cmd_flags, 361 uint16_t token, 362 uint8_t priority, 363 struct dpci_rx_queue_attr *attr) 364 { 365 struct dpci_cmd_get_queue *cmd_params; 366 struct dpci_rsp_get_rx_queue *rsp_params; 367 struct mc_command cmd = { 0 }; 368 int err; 369 370 /* prepare command */ 371 cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_RX_QUEUE, 372 cmd_flags, 373 token); 374 cmd_params = (struct dpci_cmd_get_queue *)cmd.params; 375 cmd_params->priority = priority; 376 377 /* send command to mc*/ 378 err = mc_send_command(mc_io, &cmd); 379 if (err) 380 return err; 381 382 /* retrieve response parameters */ 383 rsp_params = (struct dpci_rsp_get_rx_queue *)cmd.params; 384 attr->user_ctx = le64_to_cpu(rsp_params->user_ctx); 385 attr->fqid = le32_to_cpu(rsp_params->fqid); 386 attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id); 387 attr->dest_cfg.priority = rsp_params->dest_priority; 388 attr->dest_cfg.dest_type = dpci_get_field(rsp_params->dest_type, 389 DEST_TYPE); 390 391 return 0; 392 } 393 394 /** 395 * dpci_get_tx_queue() - Retrieve Tx queue attributes. 396 * @mc_io: Pointer to MC portal's I/O object 397 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 398 * @token: Token of DPCI object 399 * @priority: Select the queue relative to number of 400 * priorities of the peer DPCI object 401 * @attr: Returned Tx queue attributes 402 * 403 * Return: '0' on Success; Error code otherwise. 404 */ 405 int dpci_get_tx_queue(struct fsl_mc_io *mc_io, 406 uint32_t cmd_flags, 407 uint16_t token, 408 uint8_t priority, 409 struct dpci_tx_queue_attr *attr) 410 { 411 struct dpci_cmd_get_queue *cmd_params; 412 struct dpci_rsp_get_tx_queue *rsp_params; 413 struct mc_command cmd = { 0 }; 414 int err; 415 416 /* prepare command */ 417 cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_TX_QUEUE, 418 cmd_flags, 419 token); 420 cmd_params = (struct dpci_cmd_get_queue *)cmd.params; 421 cmd_params->priority = priority; 422 423 /* send command to mc*/ 424 err = mc_send_command(mc_io, &cmd); 425 if (err) 426 return err; 427 428 /* retrieve response parameters */ 429 rsp_params = (struct dpci_rsp_get_tx_queue *)cmd.params; 430 attr->fqid = le32_to_cpu(rsp_params->fqid); 431 432 return 0; 433 } 434 435 /** 436 * dpci_get_api_version() - Get communication interface API version 437 * @mc_io: Pointer to MC portal's I/O object 438 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 439 * @major_ver: Major version of data path communication interface API 440 * @minor_ver: Minor version of data path communication interface API 441 * 442 * Return: '0' on Success; Error code otherwise. 443 */ 444 int dpci_get_api_version(struct fsl_mc_io *mc_io, 445 uint32_t cmd_flags, 446 uint16_t *major_ver, 447 uint16_t *minor_ver) 448 { 449 struct dpci_rsp_get_api_version *rsp_params; 450 struct mc_command cmd = { 0 }; 451 int err; 452 453 cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_API_VERSION, 454 cmd_flags, 455 0); 456 457 err = mc_send_command(mc_io, &cmd); 458 if (err) 459 return err; 460 461 rsp_params = (struct dpci_rsp_get_api_version *)cmd.params; 462 *major_ver = le16_to_cpu(rsp_params->major); 463 *minor_ver = le16_to_cpu(rsp_params->minor); 464 465 return 0; 466 } 467 468 /** 469 * dpci_set_opr() - Set Order Restoration configuration. 470 * @mc_io: Pointer to MC portal's I/O object 471 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 472 * @token: Token of DPCI object 473 * @index: The queue index 474 * @options: Configuration mode options 475 * can be OPR_OPT_CREATE or OPR_OPT_RETIRE 476 * @cfg: Configuration options for the OPR 477 * 478 * Return: '0' on Success; Error code otherwise. 479 */ 480 int dpci_set_opr(struct fsl_mc_io *mc_io, 481 uint32_t cmd_flags, 482 uint16_t token, 483 uint8_t index, 484 uint8_t options, 485 struct opr_cfg *cfg) 486 { 487 struct dpci_cmd_set_opr *cmd_params; 488 struct mc_command cmd = { 0 }; 489 490 /* prepare command */ 491 cmd.header = mc_encode_cmd_header(DPCI_CMDID_SET_OPR, 492 cmd_flags, 493 token); 494 cmd_params = (struct dpci_cmd_set_opr *)cmd.params; 495 cmd_params->index = index; 496 cmd_params->options = options; 497 cmd_params->oloe = cfg->oloe; 498 cmd_params->oeane = cfg->oeane; 499 cmd_params->olws = cfg->olws; 500 cmd_params->oa = cfg->oa; 501 cmd_params->oprrws = cfg->oprrws; 502 503 /* send command to mc*/ 504 return mc_send_command(mc_io, &cmd); 505 } 506 507 /** 508 * dpci_get_opr() - Retrieve Order Restoration config and query. 509 * @mc_io: Pointer to MC portal's I/O object 510 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 511 * @token: Token of DPCI object 512 * @index: The queue index 513 * @cfg: Returned OPR configuration 514 * @qry: Returned OPR query 515 * 516 * Return: '0' on Success; Error code otherwise. 517 */ 518 int dpci_get_opr(struct fsl_mc_io *mc_io, 519 uint32_t cmd_flags, 520 uint16_t token, 521 uint8_t index, 522 struct opr_cfg *cfg, 523 struct opr_qry *qry) 524 { 525 struct dpci_rsp_get_opr *rsp_params; 526 struct dpci_cmd_get_opr *cmd_params; 527 struct mc_command cmd = { 0 }; 528 int err; 529 530 /* prepare command */ 531 cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_OPR, 532 cmd_flags, 533 token); 534 cmd_params = (struct dpci_cmd_get_opr *)cmd.params; 535 cmd_params->index = index; 536 537 /* send command to mc*/ 538 err = mc_send_command(mc_io, &cmd); 539 if (err) 540 return err; 541 542 /* retrieve response parameters */ 543 rsp_params = (struct dpci_rsp_get_opr *)cmd.params; 544 cfg->oloe = rsp_params->oloe; 545 cfg->oeane = rsp_params->oeane; 546 cfg->olws = rsp_params->olws; 547 cfg->oa = rsp_params->oa; 548 cfg->oprrws = rsp_params->oprrws; 549 qry->rip = dpci_get_field(rsp_params->flags, RIP); 550 qry->enable = dpci_get_field(rsp_params->flags, OPR_ENABLE); 551 qry->nesn = le16_to_cpu(rsp_params->nesn); 552 qry->ndsn = le16_to_cpu(rsp_params->ndsn); 553 qry->ea_tseq = le16_to_cpu(rsp_params->ea_tseq); 554 qry->tseq_nlis = dpci_get_field(rsp_params->tseq_nlis, TSEQ_NLIS); 555 qry->ea_hseq = le16_to_cpu(rsp_params->ea_hseq); 556 qry->hseq_nlis = dpci_get_field(rsp_params->hseq_nlis, HSEQ_NLIS); 557 qry->ea_hptr = le16_to_cpu(rsp_params->ea_hptr); 558 qry->ea_tptr = le16_to_cpu(rsp_params->ea_tptr); 559 qry->opr_vid = le16_to_cpu(rsp_params->opr_vid); 560 qry->opr_id = le16_to_cpu(rsp_params->opr_id); 561 562 return 0; 563 } 564