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 }