xref: /illumos-gate/usr/src/uts/common/io/hxge/hpi_rxdma.c (revision 24b9abbad58fdd63dad716fd35a99a7944c4e3eb)
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