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