1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <hpi_rxdma.h> 29 #include <hxge_common.h> 30 #include <hxge_impl.h> 31 32 #define RXDMA_RESET_TRY_COUNT 5 33 #define RXDMA_RESET_DELAY 5 34 35 #define RXDMA_OP_DISABLE 0 36 #define RXDMA_OP_ENABLE 1 37 #define RXDMA_OP_RESET 2 38 39 #define RCR_TIMEOUT_ENABLE 1 40 #define RCR_TIMEOUT_DISABLE 2 41 #define RCR_THRESHOLD 4 42 43 hpi_status_t 44 hpi_rxdma_cfg_logical_page_handle(hpi_handle_t handle, uint8_t rdc, 45 uint64_t page_handle) 46 { 47 rdc_page_handle_t page_hdl; 48 49 if (!RXDMA_CHANNEL_VALID(rdc)) { 50 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 51 "rxdma_cfg_logical_page_handle" 52 " Illegal RDC number %d \n", rdc)); 53 return (HPI_RXDMA_RDC_INVALID); 54 } 55 56 page_hdl.value = 0; 57 page_hdl.bits.handle = (uint32_t)page_handle; 58 59 RXDMA_REG_WRITE64(handle, RDC_PAGE_HANDLE, rdc, page_hdl.value); 60 61 return (HPI_SUCCESS); 62 } 63 64 65 /* RX DMA functions */ 66 static hpi_status_t 67 hpi_rxdma_cfg_rdc_ctl(hpi_handle_t handle, uint8_t rdc, uint8_t op) 68 { 69 rdc_rx_cfg1_t cfg; 70 uint32_t count = RXDMA_RESET_TRY_COUNT; 71 uint32_t delay_time = RXDMA_RESET_DELAY; 72 uint32_t error = HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RESET_ERR, rdc); 73 74 if (!RXDMA_CHANNEL_VALID(rdc)) { 75 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 76 "hpi_rxdma_cfg_rdc_ctl Illegal RDC number %d \n", rdc)); 77 return (HPI_RXDMA_RDC_INVALID); 78 } 79 80 switch (op) { 81 case RXDMA_OP_ENABLE: 82 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 83 cfg.bits.enable = 1; 84 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value); 85 86 HXGE_DELAY(delay_time); 87 88 break; 89 case RXDMA_OP_DISABLE: 90 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 91 cfg.bits.enable = 0; 92 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value); 93 94 HXGE_DELAY(delay_time); 95 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 96 97 while ((count--) && (cfg.bits.qst == 0)) { 98 HXGE_DELAY(delay_time); 99 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 100 } 101 if (cfg.bits.qst == 0) { 102 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 103 " hpi_rxdma_cfg_rdc_ctl" 104 " RXDMA_OP_DISABLE Failed for RDC %d \n", 105 rdc)); 106 return (error); 107 } 108 109 break; 110 case RXDMA_OP_RESET: 111 cfg.value = 0; 112 cfg.bits.reset = 1; 113 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value); 114 HXGE_DELAY(delay_time); 115 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 116 117 while ((count--) && (cfg.bits.qst == 0)) { 118 HXGE_DELAY(delay_time); 119 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 120 } 121 if (count == 0) { 122 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 123 " hpi_rxdma_cfg_rdc_ctl" 124 " Reset Failed for RDC %d \n", rdc)); 125 return (error); 126 } 127 128 break; 129 default: 130 return (HPI_RXDMA_SW_PARAM_ERROR); 131 } 132 133 return (HPI_SUCCESS); 134 } 135 136 hpi_status_t 137 hpi_rxdma_cfg_rdc_enable(hpi_handle_t handle, uint8_t rdc) 138 { 139 return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_ENABLE)); 140 } 141 142 hpi_status_t 143 hpi_rxdma_cfg_rdc_disable(hpi_handle_t handle, uint8_t rdc) 144 { 145 return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_DISABLE)); 146 } 147 148 hpi_status_t 149 hpi_rxdma_cfg_rdc_reset(hpi_handle_t handle, uint8_t rdc) 150 { 151 return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_RESET)); 152 } 153 154 static hpi_status_t 155 hpi_rxdma_cfg_rdc_rcr_ctl(hpi_handle_t handle, uint8_t rdc, 156 uint8_t op, uint16_t param) 157 { 158 rdc_rcr_cfg_b_t rcr_cfgb; 159 160 if (!RXDMA_CHANNEL_VALID(rdc)) { 161 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 162 "rxdma_cfg_rdc_rcr_ctl Illegal RDC number %d \n", rdc)); 163 return (HPI_RXDMA_RDC_INVALID); 164 } 165 166 RXDMA_REG_READ64(handle, RDC_RCR_CFG_B, rdc, &rcr_cfgb.value); 167 168 switch (op) { 169 case RCR_TIMEOUT_ENABLE: 170 rcr_cfgb.bits.timeout = (uint8_t)param; 171 rcr_cfgb.bits.entout = 1; 172 break; 173 174 case RCR_THRESHOLD: 175 rcr_cfgb.bits.pthres = param; 176 break; 177 178 case RCR_TIMEOUT_DISABLE: 179 rcr_cfgb.bits.entout = 0; 180 break; 181 182 default: 183 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 184 "rxdma_cfg_rdc_rcr_ctl Illegal opcode %x \n", op)); 185 return (HPI_RXDMA_OPCODE_INVALID(rdc)); 186 } 187 188 RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_B, rdc, rcr_cfgb.value); 189 return (HPI_SUCCESS); 190 } 191 192 hpi_status_t 193 hpi_rxdma_cfg_rdc_rcr_threshold(hpi_handle_t handle, uint8_t rdc, 194 uint16_t rcr_threshold) 195 { 196 return (hpi_rxdma_cfg_rdc_rcr_ctl(handle, rdc, 197 RCR_THRESHOLD, rcr_threshold)); 198 } 199 200 hpi_status_t 201 hpi_rxdma_cfg_rdc_rcr_timeout(hpi_handle_t handle, uint8_t rdc, 202 uint8_t rcr_timeout) 203 { 204 return (hpi_rxdma_cfg_rdc_rcr_ctl(handle, rdc, 205 RCR_TIMEOUT_ENABLE, rcr_timeout)); 206 } 207 208 /* 209 * Configure The RDC channel Rcv Buffer Ring 210 */ 211 hpi_status_t 212 hpi_rxdma_cfg_rdc_ring(hpi_handle_t handle, uint8_t rdc, 213 rdc_desc_cfg_t *rdc_desc_cfg) 214 { 215 rdc_rbr_cfg_a_t cfga; 216 rdc_rbr_cfg_b_t cfgb; 217 rdc_rx_cfg1_t cfg1; 218 rdc_rx_cfg2_t cfg2; 219 rdc_rcr_cfg_a_t rcr_cfga; 220 rdc_rcr_cfg_b_t rcr_cfgb; 221 rdc_page_handle_t page_handle; 222 223 if (!RXDMA_CHANNEL_VALID(rdc)) { 224 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 225 "rxdma_cfg_rdc_ring Illegal RDC number %d \n", rdc)); 226 return (HPI_RXDMA_RDC_INVALID); 227 } 228 229 cfga.value = 0; 230 cfgb.value = 0; 231 cfg1.value = 0; 232 cfg2.value = 0; 233 page_handle.value = 0; 234 235 if (rdc_desc_cfg->mbox_enable == 1) { 236 cfg1.bits.mbaddr_h = (rdc_desc_cfg->mbox_addr >> 32) & 0xfff; 237 cfg2.bits.mbaddr_l = ((rdc_desc_cfg->mbox_addr & 238 RXDMA_CFIG2_MBADDR_L_MASK) >> RXDMA_CFIG2_MBADDR_L_SHIFT); 239 240 /* 241 * Only after all the configurations are set, then 242 * enable the RDC or else configuration fatal error 243 * will be returned (especially if the Hypervisor 244 * set up the logical pages with non-zero values. 245 * This HPI function only sets up the configuration. 246 * Call the enable function to enable the RDMC! 247 */ 248 } 249 250 if (rdc_desc_cfg->full_hdr == 1) 251 cfg2.bits.full_hdr = 1; 252 253 if (RXDMA_BUFF_OFFSET_VALID(rdc_desc_cfg->offset)) { 254 cfg2.bits.offset = rdc_desc_cfg->offset; 255 } else { 256 cfg2.bits.offset = SW_OFFSET_NO_OFFSET; 257 } 258 259 /* rbr config */ 260 cfga.value = (rdc_desc_cfg->rbr_addr & 261 (RBR_CFIG_A_STDADDR_MASK | RBR_CFIG_A_STDADDR_BASE_MASK)); 262 263 /* The remaining 20 bits in the DMA address form the handle */ 264 page_handle.bits.handle = (rdc_desc_cfg->rbr_addr >> 44) && 0xfffff; 265 266 /* 267 * The RBR ring size must be multiple of 64. 268 */ 269 if ((rdc_desc_cfg->rbr_len < RBR_DEFAULT_MIN_LEN) || 270 (rdc_desc_cfg->rbr_len > RBR_DEFAULT_MAX_LEN) || 271 (rdc_desc_cfg->rbr_len % 64)) { 272 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 273 "hpi_rxdma_cfg_rdc_ring Illegal RBR Queue Length %d \n", 274 rdc_desc_cfg->rbr_len)); 275 return (HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RBRSZIE_INVALID, rdc)); 276 } 277 278 /* 279 * The lower 6 bits are hardcoded to 0 and the higher 10 bits are 280 * stored in len. 281 */ 282 cfga.bits.len = rdc_desc_cfg->rbr_len >> 6; 283 HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL, 284 "hpi_rxdma_cfg_rdc_ring CFGA 0x%llx len %d (RBR LEN %d)\n", 285 cfga.value, cfga.bits.len, rdc_desc_cfg->rbr_len)); 286 287 /* 288 * bksize is 1 bit 289 * Buffer Block Size. b0 - 4K; b1 - 8K. 290 */ 291 if (rdc_desc_cfg->page_size == SIZE_4KB) 292 cfgb.bits.bksize = RBR_BKSIZE_4K; 293 else if (rdc_desc_cfg->page_size == SIZE_8KB) 294 cfgb.bits.bksize = RBR_BKSIZE_8K; 295 else { 296 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 297 "rxdma_cfg_rdc_ring blksize: Illegal buffer size %d \n", 298 rdc_desc_cfg->page_size)); 299 return (HPI_RXDMA_BUFSZIE_INVALID); 300 } 301 302 /* 303 * Size 0 of packet buffer. b00 - 256; b01 - 512; b10 - 1K; b11 - resvd. 304 */ 305 if (rdc_desc_cfg->valid0) { 306 if (rdc_desc_cfg->size0 == SIZE_256B) 307 cfgb.bits.bufsz0 = RBR_BUFSZ0_256B; 308 else if (rdc_desc_cfg->size0 == SIZE_512B) 309 cfgb.bits.bufsz0 = RBR_BUFSZ0_512B; 310 else if (rdc_desc_cfg->size0 == SIZE_1KB) 311 cfgb.bits.bufsz0 = RBR_BUFSZ0_1K; 312 else { 313 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 314 " rxdma_cfg_rdc_ring" 315 " blksize0: Illegal buffer size %x \n", 316 rdc_desc_cfg->size0)); 317 return (HPI_RXDMA_BUFSZIE_INVALID); 318 } 319 cfgb.bits.vld0 = 1; 320 } else { 321 cfgb.bits.vld0 = 0; 322 } 323 324 /* 325 * Size 1 of packet buffer. b0 - 1K; b1 - 2K. 326 */ 327 if (rdc_desc_cfg->valid1) { 328 if (rdc_desc_cfg->size1 == SIZE_1KB) 329 cfgb.bits.bufsz1 = RBR_BUFSZ1_1K; 330 else if (rdc_desc_cfg->size1 == SIZE_2KB) 331 cfgb.bits.bufsz1 = RBR_BUFSZ1_2K; 332 else { 333 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 334 " rxdma_cfg_rdc_ring" 335 " blksize1: Illegal buffer size %x \n", 336 rdc_desc_cfg->size1)); 337 return (HPI_RXDMA_BUFSZIE_INVALID); 338 } 339 cfgb.bits.vld1 = 1; 340 } else { 341 cfgb.bits.vld1 = 0; 342 } 343 344 /* 345 * Size 2 of packet buffer. b0 - 2K; b1 - 4K. 346 */ 347 if (rdc_desc_cfg->valid2) { 348 if (rdc_desc_cfg->size2 == SIZE_2KB) 349 cfgb.bits.bufsz2 = RBR_BUFSZ2_2K; 350 else if (rdc_desc_cfg->size2 == SIZE_4KB) 351 cfgb.bits.bufsz2 = RBR_BUFSZ2_4K; 352 else { 353 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 354 " rxdma_cfg_rdc_ring" 355 " blksize2: Illegal buffer size %x \n", 356 rdc_desc_cfg->size2)); 357 return (HPI_RXDMA_BUFSZIE_INVALID); 358 } 359 cfgb.bits.vld2 = 1; 360 } else { 361 cfgb.bits.vld2 = 0; 362 } 363 364 rcr_cfga.value = (rdc_desc_cfg->rcr_addr & 365 (RCRCFIG_A_STADDR_MASK | RCRCFIG_A_STADDR_BASE_MASK)); 366 367 /* 368 * The rcr len must be multiple of 32. 369 */ 370 if ((rdc_desc_cfg->rcr_len < RCR_DEFAULT_MIN_LEN) || 371 (rdc_desc_cfg->rcr_len > HXGE_RCR_MAX) || 372 (rdc_desc_cfg->rcr_len % 32)) { 373 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 374 " rxdma_cfg_rdc_ring Illegal RCR Queue Length %d \n", 375 rdc_desc_cfg->rcr_len)); 376 return (HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RCRSZIE_INVALID, rdc)); 377 } 378 379 /* 380 * Bits 15:5 of the maximum number of 8B entries in RCR. Bits 4:0 are 381 * hard-coded to zero. The maximum size is 2^16 - 32. 382 */ 383 rcr_cfga.bits.len = rdc_desc_cfg->rcr_len >> 5; 384 385 rcr_cfgb.value = 0; 386 if (rdc_desc_cfg->rcr_timeout_enable == 1) { 387 /* check if the rcr timeout value is valid */ 388 389 if (RXDMA_RCR_TO_VALID(rdc_desc_cfg->rcr_timeout)) { 390 rcr_cfgb.bits.timeout = rdc_desc_cfg->rcr_timeout; 391 rcr_cfgb.bits.entout = 1; 392 } else { 393 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 394 " rxdma_cfg_rdc_ring" 395 " Illegal RCR Timeout value %d \n", 396 rdc_desc_cfg->rcr_timeout)); 397 rcr_cfgb.bits.entout = 0; 398 } 399 } else { 400 rcr_cfgb.bits.entout = 0; 401 } 402 403 /* check if the rcr threshold value is valid */ 404 if (RXDMA_RCR_THRESH_VALID(rdc_desc_cfg->rcr_threshold)) { 405 rcr_cfgb.bits.pthres = rdc_desc_cfg->rcr_threshold; 406 } else { 407 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 408 " rxdma_cfg_rdc_ring Illegal RCR Threshold value %d \n", 409 rdc_desc_cfg->rcr_threshold)); 410 rcr_cfgb.bits.pthres = 1; 411 } 412 413 /* now do the actual HW configuration */ 414 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg1.value); 415 RXDMA_REG_WRITE64(handle, RDC_RX_CFG2, rdc, cfg2.value); 416 417 RXDMA_REG_WRITE64(handle, RDC_RBR_CFG_A, rdc, cfga.value); 418 RXDMA_REG_WRITE64(handle, RDC_RBR_CFG_B, rdc, cfgb.value); 419 420 RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_A, rdc, rcr_cfga.value); 421 RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_B, rdc, rcr_cfgb.value); 422 423 RXDMA_REG_WRITE64(handle, RDC_PAGE_HANDLE, rdc, page_handle.value); 424 425 return (HPI_SUCCESS); 426 } 427 428 hpi_status_t 429 hpi_rxdma_ring_perr_stat_get(hpi_handle_t handle, 430 rdc_pref_par_log_t *pre_log, rdc_pref_par_log_t *sha_log) 431 { 432 /* 433 * Hydra doesn't have details about these errors. 434 * It only provides the addresses of the errors. 435 */ 436 HXGE_REG_RD64(handle, RDC_PREF_PAR_LOG, &pre_log->value); 437 HXGE_REG_RD64(handle, RDC_SHADOW_PAR_LOG, &sha_log->value); 438 439 return (HPI_SUCCESS); 440 } 441 442 443 /* system wide conf functions */ 444 445 hpi_status_t 446 hpi_rxdma_cfg_clock_div_set(hpi_handle_t handle, uint16_t count) 447 { 448 uint64_t offset; 449 rdc_clock_div_t clk_div; 450 451 offset = RDC_CLOCK_DIV; 452 453 clk_div.value = 0; 454 clk_div.bits.count = count; 455 HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL, 456 " hpi_rxdma_cfg_clock_div_set: add 0x%llx " 457 "handle 0x%llx value 0x%llx", 458 handle.regp, handle.regh, clk_div.value)); 459 460 HXGE_REG_WR64(handle, offset, clk_div.value); 461 462 return (HPI_SUCCESS); 463 } 464 465 466 hpi_status_t 467 hpi_rxdma_rdc_rbr_stat_get(hpi_handle_t handle, uint8_t rdc, 468 rdc_rbr_qlen_t *rbr_stat) 469 { 470 if (!RXDMA_CHANNEL_VALID(rdc)) { 471 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 472 " rxdma_rdc_rbr_stat_get Illegal RDC Number %d \n", rdc)); 473 return (HPI_RXDMA_RDC_INVALID); 474 } 475 476 RXDMA_REG_READ64(handle, RDC_RBR_QLEN, rdc, &rbr_stat->value); 477 return (HPI_SUCCESS); 478 } 479 480 481 hpi_status_t 482 hpi_rxdma_rdc_rcr_qlen_get(hpi_handle_t handle, uint8_t rdc, 483 uint16_t *rcr_qlen) 484 { 485 rdc_rcr_qlen_t stats; 486 487 if (!RXDMA_CHANNEL_VALID(rdc)) { 488 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 489 " rxdma_rdc_rcr_qlen_get Illegal RDC Number %d \n", rdc)); 490 return (HPI_RXDMA_RDC_INVALID); 491 } 492 493 RXDMA_REG_READ64(handle, RDC_RCR_QLEN, rdc, &stats.value); 494 *rcr_qlen = stats.bits.qlen; 495 HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL, 496 " rxdma_rdc_rcr_qlen_get RDC %d qlen %x qlen %x\n", 497 rdc, *rcr_qlen, stats.bits.qlen)); 498 return (HPI_SUCCESS); 499 } 500 501 hpi_status_t 502 hpi_rxdma_channel_rbr_empty_clear(hpi_handle_t handle, uint8_t channel) 503 { 504 rdc_stat_t cs; 505 506 if (!RXDMA_CHANNEL_VALID(channel)) { 507 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 508 " hpi_rxdma_channel_rbr_empty_clear", " channel", channel)); 509 return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel)); 510 } 511 512 RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value); 513 cs.bits.rbr_empty = 1; 514 RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs.value); 515 516 return (HPI_SUCCESS); 517 } 518 519 /* 520 * This function is called to operate on the control and status register. 521 */ 522 hpi_status_t 523 hpi_rxdma_control_status(hpi_handle_t handle, io_op_t op_mode, uint8_t channel, 524 rdc_stat_t *cs_p) 525 { 526 int status = HPI_SUCCESS; 527 rdc_stat_t cs; 528 529 if (!RXDMA_CHANNEL_VALID(channel)) { 530 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 531 "hpi_rxdma_control_status", "channel", channel)); 532 return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel)); 533 } 534 535 switch (op_mode) { 536 case OP_GET: 537 RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs_p->value); 538 break; 539 540 case OP_SET: 541 RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs_p->value); 542 break; 543 544 case OP_UPDATE: 545 RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value); 546 RXDMA_REG_WRITE64(handle, RDC_STAT, channel, 547 cs_p->value | cs.value); 548 break; 549 550 default: 551 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 552 "hpi_rxdma_control_status", "control", op_mode)); 553 return (HPI_FAILURE | HPI_RXDMA_OPCODE_INVALID(channel)); 554 } 555 556 return (status); 557 } 558 559 /* 560 * This function is called to operate on the event mask 561 * register which is used for generating interrupts. 562 */ 563 hpi_status_t 564 hpi_rxdma_event_mask(hpi_handle_t handle, io_op_t op_mode, uint8_t channel, 565 rdc_int_mask_t *mask_p) 566 { 567 int status = HPI_SUCCESS; 568 rdc_int_mask_t mask; 569 570 if (!RXDMA_CHANNEL_VALID(channel)) { 571 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 572 "hpi_rxdma_event_mask", "channel", channel)); 573 return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel)); 574 } 575 576 switch (op_mode) { 577 case OP_GET: 578 RXDMA_REG_READ64(handle, RDC_INT_MASK, channel, &mask_p->value); 579 break; 580 581 case OP_SET: 582 RXDMA_REG_WRITE64(handle, RDC_INT_MASK, channel, mask_p->value); 583 break; 584 585 case OP_UPDATE: 586 RXDMA_REG_READ64(handle, RDC_INT_MASK, channel, &mask.value); 587 RXDMA_REG_WRITE64(handle, RDC_INT_MASK, channel, 588 mask_p->value | mask.value); 589 break; 590 591 default: 592 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 593 "hpi_rxdma_event_mask", "eventmask", op_mode)); 594 return (HPI_FAILURE | HPI_RXDMA_OPCODE_INVALID(channel)); 595 } 596 597 return (status); 598 } 599