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