1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2013-2016 Qlogic Corporation 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 /* 32 * File: ql_inline.h 33 * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656. 34 */ 35 #ifndef _QL_INLINE_H_ 36 #define _QL_INLINE_H_ 37 38 39 #define QL8_SEMLOCK_TIMEOUT 1000/* QLA8020 Semaphore Lock Timeout 10ms */ 40 41 42 /* 43 * Inline functions for hardware semaphores 44 */ 45 46 /* 47 * Name: qla_sem_lock 48 * Function: Locks one of the semaphore registers (semaphore 2,3,5 & 7) 49 * If the id_reg is valid, then id_val is written into it. 50 * This is for debugging purpose 51 * Returns: 0 on success; otherwise its failed. 52 */ 53 static __inline int 54 qla_sem_lock(qla_host_t *ha, uint32_t sem_reg, uint32_t id_reg, uint32_t id_val) 55 { 56 int count = QL8_SEMLOCK_TIMEOUT; 57 58 while (count) { 59 if ((READ_REG32(ha, sem_reg) & BIT_0)) 60 break; 61 count--; 62 63 if (!count) 64 return(-1); 65 qla_mdelay(__func__, 10); 66 } 67 if (id_reg) 68 WRITE_REG32(ha, id_reg, id_val); 69 70 return(0); 71 } 72 73 /* 74 * Name: qla_sem_unlock 75 * Function: Unlocks the semaphore registers (semaphore 2,3,5 & 7) 76 * previously locked by qla_sem_lock() 77 */ 78 static __inline void 79 qla_sem_unlock(qla_host_t *ha, uint32_t sem_reg) 80 { 81 READ_REG32(ha, sem_reg); 82 } 83 84 static __inline int 85 qla_get_ifq_snd_maxlen(qla_host_t *ha) 86 { 87 return(((NUM_TX_DESCRIPTORS * 4) - 1)); 88 } 89 90 static __inline uint32_t 91 qla_get_optics(qla_host_t *ha) 92 { 93 uint32_t link_speed; 94 95 link_speed = READ_REG32(ha, Q8_LINK_SPEED_0); 96 if (ha->pci_func == 0) 97 link_speed = link_speed & 0xFF; 98 else 99 link_speed = (link_speed >> 8) & 0xFF; 100 101 switch (link_speed) { 102 case 0x1: 103 link_speed = IFM_100_FX; 104 break; 105 106 case 0x10: 107 link_speed = IFM_1000_SX; 108 break; 109 110 default: 111 if ((ha->hw.module_type == 0x4) || 112 (ha->hw.module_type == 0x5) || 113 (ha->hw.module_type == 0x6)) 114 link_speed = (IFM_10G_TWINAX); 115 else 116 link_speed = (IFM_10G_LR | IFM_10G_SR); 117 break; 118 } 119 120 return(link_speed); 121 } 122 123 static __inline uint8_t * 124 qla_get_mac_addr(qla_host_t *ha) 125 { 126 return (ha->hw.mac_addr); 127 } 128 129 static __inline void 130 qla_set_hw_rcv_desc(qla_host_t *ha, uint32_t r_idx, uint32_t index, 131 uint32_t handle, bus_addr_t paddr, uint32_t buf_size) 132 { 133 volatile q80_recv_desc_t *rcv_desc; 134 135 rcv_desc = (q80_recv_desc_t *)ha->hw.dma_buf.rds_ring[r_idx].dma_b; 136 137 rcv_desc += index; 138 139 rcv_desc->handle = (uint16_t)handle; 140 rcv_desc->buf_size = buf_size; 141 rcv_desc->buf_addr = paddr; 142 143 return; 144 } 145 146 static __inline void 147 qla_init_hw_rcv_descriptors(qla_host_t *ha) 148 { 149 int i; 150 151 for (i = 0; i < ha->hw.num_rds_rings; i++) 152 bzero((void *)ha->hw.dma_buf.rds_ring[i].dma_b, 153 (sizeof(q80_recv_desc_t) * NUM_RX_DESCRIPTORS)); 154 } 155 156 #define QLA_LOCK_DEFAULT_MS_TIMEOUT 3000 157 158 #ifndef QLA_LOCK_NO_SLEEP 159 #define QLA_LOCK_NO_SLEEP 0 160 #endif 161 162 static __inline int 163 qla_lock(qla_host_t *ha, const char *str, uint32_t timeout_ms, 164 uint32_t no_sleep) 165 { 166 int ret = -1; 167 168 while (1) { 169 mtx_lock(&ha->hw_lock); 170 171 if (ha->qla_detach_active || ha->offline) { 172 mtx_unlock(&ha->hw_lock); 173 break; 174 } 175 176 if (!ha->hw_lock_held) { 177 ha->hw_lock_held = 1; 178 ha->qla_lock = str; 179 ret = 0; 180 mtx_unlock(&ha->hw_lock); 181 break; 182 } 183 mtx_unlock(&ha->hw_lock); 184 185 if (--timeout_ms == 0) { 186 ha->hw_lock_failed++; 187 break; 188 } else { 189 if (no_sleep) 190 DELAY(1000); 191 else 192 qla_mdelay(__func__, 1); 193 } 194 } 195 196 // if (!ha->enable_error_recovery) 197 // device_printf(ha->pci_dev, "%s: %s ret = %d\n", __func__, 198 // str,ret); 199 200 return (ret); 201 } 202 203 static __inline void 204 qla_unlock(qla_host_t *ha, const char *str) 205 { 206 mtx_lock(&ha->hw_lock); 207 ha->hw_lock_held = 0; 208 ha->qla_unlock = str; 209 mtx_unlock(&ha->hw_lock); 210 211 // if (!ha->enable_error_recovery) 212 // device_printf(ha->pci_dev, "%s: %s\n", __func__, str); 213 214 return; 215 } 216 217 #endif /* #ifndef _QL_INLINE_H_ */ 218