1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2011-2013 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 /* 30 * File: qla_inline.h 31 * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656. 32 */ 33 #ifndef _QLA_INLINE_H_ 34 #define _QLA_INLINE_H_ 35 36 /* 37 * Function: qla_hw_reset 38 */ 39 static __inline void qla_hw_reset(qla_host_t *ha) 40 { 41 WRITE_OFFSET32(ha, Q8_ASIC_RESET, 0xFFFFFFFF); 42 } 43 44 #define QL8_SEMLOCK_TIMEOUT 1000/* QLA8020 Semaphore Lock Timeout 10ms */ 45 46 /* 47 * Inline functions for hardware semaphores 48 */ 49 50 /* 51 * Name: qla_sem_lock 52 * Function: Locks one of the semaphore registers (semaphore 2,3,5 & 7) 53 * If the id_reg is valid, then id_val is written into it. 54 * This is for debugging purpose 55 * Returns: 0 on success; otherwise its failed. 56 */ 57 static __inline int 58 qla_sem_lock(qla_host_t *ha, uint32_t sem_reg, uint32_t id_reg, uint32_t id_val) 59 { 60 int count = QL8_SEMLOCK_TIMEOUT; 61 62 while (count) { 63 if ((READ_REG32(ha, sem_reg) & SEM_LOCK_BIT)) 64 break; 65 count--; 66 67 if (!count) 68 return(-1); 69 qla_mdelay(__func__, 10); 70 } 71 if (id_reg) 72 WRITE_OFFSET32(ha, id_reg, id_val); 73 74 return(0); 75 } 76 77 /* 78 * Name: qla_sem_unlock 79 * Function: Unlocks the semaphore registers (semaphore 2,3,5 & 7) 80 * previously locked by qla_sem_lock() 81 */ 82 static __inline void 83 qla_sem_unlock(qla_host_t *ha, uint32_t sem_reg) 84 { 85 READ_REG32(ha, sem_reg); 86 } 87 88 static __inline int 89 qla_get_ifq_snd_maxlen(qla_host_t *ha) 90 { 91 return((NUM_TX_DESCRIPTORS - 1)); 92 } 93 94 static __inline uint32_t 95 qla_get_optics(qla_host_t *ha) 96 { 97 uint32_t link_speed; 98 99 link_speed = READ_REG32(ha, Q8_LINK_SPEED_0); 100 if (ha->pci_func == 0) 101 link_speed = link_speed & 0xFF; 102 else 103 link_speed = (link_speed >> 8) & 0xFF; 104 105 switch (link_speed) { 106 case 0x1: 107 link_speed = IFM_100_FX; 108 break; 109 110 case 0x10: 111 link_speed = IFM_1000_SX; 112 break; 113 114 default: 115 link_speed = (IFM_10G_LR | IFM_10G_SR); 116 break; 117 } 118 119 return(link_speed); 120 } 121 122 static __inline uint8_t * 123 qla_get_mac_addr(qla_host_t *ha) 124 { 125 return (ha->hw.mac_addr); 126 } 127 128 static __inline void 129 qla_read_mac_addr(qla_host_t *ha) 130 { 131 uint32_t mac_crb_addr; 132 uint32_t mac_lo; 133 uint32_t mac_hi; 134 uint8_t *macp; 135 136 mac_crb_addr = Q8_CRB_MAC_BLOCK_START + 137 (((ha->pci_func >> 1) * 3) << 2) + ((ha->pci_func & 0x01) << 2); 138 139 mac_lo = READ_REG32(ha, mac_crb_addr); 140 mac_hi = READ_REG32(ha, (mac_crb_addr + 0x4)); 141 142 if (ha->pci_func & 0x01) { 143 mac_lo = mac_lo >> 16; 144 145 macp = (uint8_t *)&mac_lo; 146 147 ha->hw.mac_addr[5] = macp[0]; 148 ha->hw.mac_addr[4] = macp[1]; 149 150 macp = (uint8_t *)&mac_hi; 151 152 ha->hw.mac_addr[3] = macp[0]; 153 ha->hw.mac_addr[2] = macp[1]; 154 ha->hw.mac_addr[1] = macp[2]; 155 ha->hw.mac_addr[0] = macp[3]; 156 } else { 157 macp = (uint8_t *)&mac_lo; 158 159 ha->hw.mac_addr[5] = macp[0]; 160 ha->hw.mac_addr[4] = macp[1]; 161 ha->hw.mac_addr[3] = macp[2]; 162 ha->hw.mac_addr[2] = macp[3]; 163 164 macp = (uint8_t *)&mac_hi; 165 166 ha->hw.mac_addr[1] = macp[0]; 167 ha->hw.mac_addr[0] = macp[1]; 168 } 169 return; 170 } 171 172 static __inline void 173 qla_set_hw_rcv_desc(qla_host_t *ha, uint32_t ridx, uint32_t index, 174 uint32_t handle, bus_addr_t paddr, uint32_t buf_size) 175 { 176 q80_recv_desc_t *rcv_desc; 177 178 rcv_desc = (q80_recv_desc_t *)ha->hw.dma_buf.rds_ring[ridx].dma_b; 179 180 rcv_desc += index; 181 182 rcv_desc->handle = (uint16_t)handle; 183 rcv_desc->buf_size = buf_size; 184 rcv_desc->buf_addr = paddr; 185 186 return; 187 } 188 189 static __inline void 190 qla_init_hw_rcv_descriptors(qla_host_t *ha, uint32_t ridx) 191 { 192 if (ridx == RDS_RING_INDEX_NORMAL) 193 bzero((void *)ha->hw.dma_buf.rds_ring[ridx].dma_b, 194 (sizeof(q80_recv_desc_t) * NUM_RX_DESCRIPTORS)); 195 else if (ridx == RDS_RING_INDEX_JUMBO) 196 bzero((void *)ha->hw.dma_buf.rds_ring[ridx].dma_b, 197 (sizeof(q80_recv_desc_t) * NUM_RX_JUMBO_DESCRIPTORS)); 198 else 199 QL_ASSERT(0, ("%s: invalid rds index [%d]\n", __func__, ridx)); 200 } 201 202 static __inline void 203 qla_lock(qla_host_t *ha, const char *str) 204 { 205 while (1) { 206 mtx_lock(&ha->hw_lock); 207 if (!ha->hw_lock_held) { 208 ha->hw_lock_held = 1; 209 ha->qla_lock = str; 210 mtx_unlock(&ha->hw_lock); 211 break; 212 } 213 mtx_unlock(&ha->hw_lock); 214 qla_mdelay(__func__, 1); 215 } 216 return; 217 } 218 219 static __inline void 220 qla_unlock(qla_host_t *ha, const char *str) 221 { 222 mtx_lock(&ha->hw_lock); 223 ha->hw_lock_held = 0; 224 ha->qla_unlock = str; 225 mtx_unlock(&ha->hw_lock); 226 } 227 228 #endif /* #ifndef _QLA_INLINE_H_ */ 229