1250661Sdavidcs/* 2250661Sdavidcs * Copyright (c) 2013-2014 Qlogic Corporation 3250661Sdavidcs * All rights reserved. 4250661Sdavidcs * 5250661Sdavidcs * Redistribution and use in source and binary forms, with or without 6250661Sdavidcs * modification, are permitted provided that the following conditions 7250661Sdavidcs * are met: 8250661Sdavidcs * 9250661Sdavidcs * 1. Redistributions of source code must retain the above copyright 10250661Sdavidcs * notice, this list of conditions and the following disclaimer. 11250661Sdavidcs * 2. Redistributions in binary form must reproduce the above copyright 12250661Sdavidcs * notice, this list of conditions and the following disclaimer in the 13250661Sdavidcs * documentation and/or other materials provided with the distribution. 14250661Sdavidcs * 15250661Sdavidcs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16250661Sdavidcs * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17250661Sdavidcs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18250661Sdavidcs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19250661Sdavidcs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20250661Sdavidcs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21250661Sdavidcs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22250661Sdavidcs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23250661Sdavidcs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24250661Sdavidcs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25250661Sdavidcs * POSSIBILITY OF SUCH DAMAGE. 26250661Sdavidcs * 27250661Sdavidcs * $FreeBSD$ 28250661Sdavidcs */ 29250661Sdavidcs/* 30250661Sdavidcs * File: ql_inline.h 31250661Sdavidcs * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656. 32250661Sdavidcs */ 33250661Sdavidcs#ifndef _QL_INLINE_H_ 34250661Sdavidcs#define _QL_INLINE_H_ 35250661Sdavidcs 36250661Sdavidcs 37250661Sdavidcs#define QL8_SEMLOCK_TIMEOUT 1000/* QLA8020 Semaphore Lock Timeout 10ms */ 38250661Sdavidcs 39250661Sdavidcs 40250661Sdavidcs/* 41250661Sdavidcs * Inline functions for hardware semaphores 42250661Sdavidcs */ 43250661Sdavidcs 44250661Sdavidcs/* 45250661Sdavidcs * Name: qla_sem_lock 46250661Sdavidcs * Function: Locks one of the semaphore registers (semaphore 2,3,5 & 7) 47250661Sdavidcs * If the id_reg is valid, then id_val is written into it. 48250661Sdavidcs * This is for debugging purpose 49250661Sdavidcs * Returns: 0 on success; otherwise its failed. 50250661Sdavidcs */ 51250661Sdavidcsstatic __inline int 52250661Sdavidcsqla_sem_lock(qla_host_t *ha, uint32_t sem_reg, uint32_t id_reg, uint32_t id_val) 53250661Sdavidcs{ 54250661Sdavidcs int count = QL8_SEMLOCK_TIMEOUT; 55250661Sdavidcs 56250661Sdavidcs while (count) { 57250661Sdavidcs if ((READ_REG32(ha, sem_reg) & BIT_0)) 58250661Sdavidcs break; 59250661Sdavidcs count--; 60250661Sdavidcs 61250661Sdavidcs if (!count) 62250661Sdavidcs return(-1); 63250661Sdavidcs qla_mdelay(__func__, 10); 64250661Sdavidcs } 65250661Sdavidcs if (id_reg) 66250661Sdavidcs WRITE_REG32(ha, id_reg, id_val); 67250661Sdavidcs 68250661Sdavidcs return(0); 69250661Sdavidcs} 70250661Sdavidcs 71250661Sdavidcs/* 72250661Sdavidcs * Name: qla_sem_unlock 73250661Sdavidcs * Function: Unlocks the semaphore registers (semaphore 2,3,5 & 7) 74250661Sdavidcs * previously locked by qla_sem_lock() 75250661Sdavidcs */ 76250661Sdavidcsstatic __inline void 77250661Sdavidcsqla_sem_unlock(qla_host_t *ha, uint32_t sem_reg) 78250661Sdavidcs{ 79250661Sdavidcs READ_REG32(ha, sem_reg); 80250661Sdavidcs} 81250661Sdavidcs 82250661Sdavidcsstatic __inline int 83250661Sdavidcsqla_get_ifq_snd_maxlen(qla_host_t *ha) 84250661Sdavidcs{ 85250661Sdavidcs return(((NUM_TX_DESCRIPTORS * 4) - 1)); 86250661Sdavidcs} 87250661Sdavidcs 88250661Sdavidcsstatic __inline uint32_t 89250661Sdavidcsqla_get_optics(qla_host_t *ha) 90250661Sdavidcs{ 91250661Sdavidcs uint32_t link_speed; 92250661Sdavidcs 93250661Sdavidcs link_speed = READ_REG32(ha, Q8_LINK_SPEED_0); 94250661Sdavidcs if (ha->pci_func == 0) 95250661Sdavidcs link_speed = link_speed & 0xFF; 96250661Sdavidcs else 97250661Sdavidcs link_speed = (link_speed >> 8) & 0xFF; 98250661Sdavidcs 99250661Sdavidcs switch (link_speed) { 100250661Sdavidcs case 0x1: 101250661Sdavidcs link_speed = IFM_100_FX; 102250661Sdavidcs break; 103250661Sdavidcs 104250661Sdavidcs case 0x10: 105250661Sdavidcs link_speed = IFM_1000_SX; 106250661Sdavidcs break; 107250661Sdavidcs 108250661Sdavidcs default: 109250661Sdavidcs if ((ha->hw.module_type == 0x4) || 110250661Sdavidcs (ha->hw.module_type == 0x5) || 111250661Sdavidcs (ha->hw.module_type == 0x6)) 112250661Sdavidcs link_speed = (IFM_10G_TWINAX); 113250661Sdavidcs else 114250661Sdavidcs link_speed = (IFM_10G_LR | IFM_10G_SR); 115250661Sdavidcs break; 116250661Sdavidcs } 117250661Sdavidcs 118250661Sdavidcs return(link_speed); 119250661Sdavidcs} 120250661Sdavidcs 121250661Sdavidcsstatic __inline uint8_t * 122250661Sdavidcsqla_get_mac_addr(qla_host_t *ha) 123250661Sdavidcs{ 124250661Sdavidcs return (ha->hw.mac_addr); 125250661Sdavidcs} 126250661Sdavidcs 127250661Sdavidcsstatic __inline void 128250661Sdavidcsqla_set_hw_rcv_desc(qla_host_t *ha, uint32_t r_idx, uint32_t index, 129250661Sdavidcs uint32_t handle, bus_addr_t paddr, uint32_t buf_size) 130250661Sdavidcs{ 131250661Sdavidcs volatile q80_recv_desc_t *rcv_desc; 132250661Sdavidcs 133250661Sdavidcs rcv_desc = (q80_recv_desc_t *)ha->hw.dma_buf.rds_ring[r_idx].dma_b; 134250661Sdavidcs 135250661Sdavidcs rcv_desc += index; 136250661Sdavidcs 137250661Sdavidcs rcv_desc->handle = (uint16_t)handle; 138250661Sdavidcs rcv_desc->buf_size = buf_size; 139250661Sdavidcs rcv_desc->buf_addr = paddr; 140250661Sdavidcs 141250661Sdavidcs return; 142250661Sdavidcs} 143250661Sdavidcs 144250661Sdavidcsstatic __inline void 145250661Sdavidcsqla_init_hw_rcv_descriptors(qla_host_t *ha) 146250661Sdavidcs{ 147250661Sdavidcs int i; 148250661Sdavidcs 149250661Sdavidcs for (i = 0; i < ha->hw.num_rds_rings; i++) 150250661Sdavidcs bzero((void *)ha->hw.dma_buf.rds_ring[i].dma_b, 151250661Sdavidcs (sizeof(q80_recv_desc_t) * NUM_RX_DESCRIPTORS)); 152250661Sdavidcs} 153250661Sdavidcs 154250661Sdavidcsstatic __inline int 155250661Sdavidcsqla_lock(qla_host_t *ha, const char *str, uint32_t no_delay) 156250661Sdavidcs{ 157250661Sdavidcs int ret = -1; 158250661Sdavidcs 159250661Sdavidcs while (1) { 160250661Sdavidcs mtx_lock(&ha->hw_lock); 161250661Sdavidcs if (!ha->hw_lock_held) { 162250661Sdavidcs ha->hw_lock_held = 1; 163250661Sdavidcs ha->qla_lock = str; 164250661Sdavidcs ret = 0; 165250661Sdavidcs mtx_unlock(&ha->hw_lock); 166250661Sdavidcs break; 167250661Sdavidcs } 168250661Sdavidcs mtx_unlock(&ha->hw_lock); 169250661Sdavidcs 170250661Sdavidcs if (no_delay) 171250661Sdavidcs break; 172250661Sdavidcs else 173250661Sdavidcs qla_mdelay(__func__, 1); 174250661Sdavidcs } 175250661Sdavidcs return (ret); 176250661Sdavidcs} 177250661Sdavidcs 178250661Sdavidcsstatic __inline void 179250661Sdavidcsqla_unlock(qla_host_t *ha, const char *str) 180250661Sdavidcs{ 181250661Sdavidcs mtx_lock(&ha->hw_lock); 182250661Sdavidcs ha->hw_lock_held = 0; 183250661Sdavidcs ha->qla_unlock = str; 184250661Sdavidcs mtx_unlock(&ha->hw_lock); 185250661Sdavidcs} 186250661Sdavidcs 187250661Sdavidcs#endif /* #ifndef _QL_INLINE_H_ */ 188