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 /*
23 * Copyright 2008-2013 Solarflare Communications Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <sys/types.h>
28 #include <sys/ddi.h>
29 #include <sys/sunddi.h>
30 #include <sys/stream.h>
31 #include <sys/dlpi.h>
32
33 #include "sfxge.h"
34
35 int
36 sfxge_bar_init(sfxge_t *sp)
37 {
38 efsys_bar_t *esbp = &(sp->s_bar);
39 ddi_device_acc_attr_t devacc;
40 int rc;
41
42 devacc.devacc_attr_version = DDI_DEVICE_ATTR_V0;
43 devacc.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
44 devacc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
45
46 if (ddi_regs_map_setup(sp->s_dip, EFX_MEM_BAR, &(esbp->esb_base), 0, 0,
47 &devacc, &(esbp->esb_handle)) != DDI_SUCCESS) {
48 rc = ENODEV;
49 goto fail1;
50 }
51
52 mutex_init(&(esbp->esb_lock), NULL, MUTEX_DRIVER, NULL);
53
54 return (0);
55
56 fail1:
57 DTRACE_PROBE1(fail1, int, rc);
58
59 return (rc);
60 }
61
62 int
63 sfxge_bar_ioctl(sfxge_t *sp, sfxge_bar_ioc_t *sbip)
64 {
65 efsys_bar_t *esbp = &(sp->s_bar);
66 efx_oword_t oword;
67 int rc;
68
69 if (!IS_P2ALIGNED(sbip->sbi_addr, sizeof (efx_oword_t))) {
70 rc = EINVAL;
71 goto fail1;
72 }
73
74 switch (sbip->sbi_op) {
75 case SFXGE_BAR_OP_READ:
76 EFSYS_BAR_READO(esbp, sbip->sbi_addr, &oword, B_TRUE);
77
78 sbip->sbi_data[0] = EFX_OWORD_FIELD(oword, EFX_DWORD_0);
79 sbip->sbi_data[1] = EFX_OWORD_FIELD(oword, EFX_DWORD_1);
80 sbip->sbi_data[2] = EFX_OWORD_FIELD(oword, EFX_DWORD_2);
81 sbip->sbi_data[3] = EFX_OWORD_FIELD(oword, EFX_DWORD_3);
82
83 break;
84
85 case SFXGE_BAR_OP_WRITE:
86 EFX_POPULATE_OWORD_4(oword,
87 EFX_DWORD_0, sbip->sbi_data[0],
88 EFX_DWORD_1, sbip->sbi_data[1],
89 EFX_DWORD_2, sbip->sbi_data[2],
90 EFX_DWORD_3, sbip->sbi_data[3]);
91
92 EFSYS_BAR_WRITEO(esbp, sbip->sbi_addr, &oword, B_TRUE);
93 break;
94
95 default:
96 rc = ENOTSUP;
97 goto fail2;
98 }
99
100 return (0);
101
102 fail2:
103 DTRACE_PROBE(fail2);
104 fail1:
105 DTRACE_PROBE1(fail1, int, rc);
106
107 return (rc);
108 }
109
110 void
111 sfxge_bar_fini(sfxge_t *sp)
112 {
113 efsys_bar_t *esbp = &(sp->s_bar);
114
115 ddi_regs_map_free(&(esbp->esb_handle));
116
117 mutex_destroy(&(esbp->esb_lock));
118
119 esbp->esb_base = NULL;
120 esbp->esb_handle = NULL;
121 }