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