1 /******************************************************************************* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * Copyright 2014 QLogic Corporation 22 * The contents of this file are subject to the terms of the 23 * QLogic End User License (the "License"). 24 * You may not use this file except in compliance with the License. 25 * 26 * You can obtain a copy of the License at 27 * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/ 28 * QLogic_End_User_Software_License.txt 29 * See the License for the specific language governing permissions 30 * and limitations under the License. 31 * 32 * 33 * Module Description: 34 * This file contains general LM utility functions 35 * 36 ******************************************************************************/ 37 38 #include "lm5710.h" 39 40 #ifdef _VBD_CMD_ 41 #include "everest_sim.h" 42 #endif 43 44 #define MASK_01010101 (((unsigned int)(-1))/3) 45 #define MASK_00110011 (((unsigned int)(-1))/5) 46 #define MASK_00001111 (((unsigned int)(-1))/17) 47 48 u32_t count_bits(u32_t n) 49 { 50 n = (n & MASK_01010101) + ((n >> 1) & MASK_01010101) ; 51 n = (n & MASK_00110011) + ((n >> 2) & MASK_00110011) ; 52 n = (n & MASK_00001111) + ((n >> 4) & MASK_00001111) ; 53 54 return n % 255 ; 55 } 56 57 unsigned long log2_align(unsigned long n) 58 { 59 unsigned long ret = n ? 1 : 0; 60 unsigned long _n = n >> 1; 61 62 while (_n) 63 { 64 _n >>= 1; 65 ret <<= 1; 66 } 67 68 if (ret < n) 69 ret <<= 1; 70 71 return ret; 72 } 73 /** 74 * @description 75 * Should be moved to a common file. 76 * Calculates the lower align of power 2. 77 * Values lower than 0 are returned directly. 78 * @param n 79 * 80 * @return unsigned long 81 * lower align of power 2. 82 */ 83 unsigned long power2_lower_align(unsigned long n) 84 { 85 unsigned long ret = 0; 86 if(0 == n) 87 { 88 return 0; 89 } 90 91 if(TRUE == POWER_OF_2(n)) 92 { 93 // The number is already a power of 2. 94 return n; 95 } 96 97 //Calculates the lower align of power 2. 98 ret = log2_align(n); 99 DbgBreakIf(FALSE == POWER_OF_2(ret)); 100 ret >>= 1; 101 102 return ret; 103 } 104 /* 105 Log2 106 this function calculates rounded LOG2 of a certain number 107 e.g.: LOG2(1080) = 10 (2^10=1024) 108 */ 109 u32_t LOG2(u32_t v){ 110 u32_t r=0; 111 while (v >>= 1) { 112 r++; 113 } 114 return r; 115 } 116 117 /** 118 * @description 119 * Should be moved to a common place. 120 * Find the next power of 2 that is larger than "num". 121 * @param num - The variable to find a power of 2 that is 122 * larger. 123 * @param num_bits_supported - The largest number of bits 124 * supported 125 * 126 * @return u32_t - The next power of 2 that is larger than 127 * "num". 128 */ 129 u32_t 130 upper_align_power_of_2(IN const u16_t num, 131 IN const u8_t num_bits_supported) 132 { 133 u32_t const largest_power_of_2 = 1 << (num_bits_supported - 1); 134 u32_t prev_power_of_2 = largest_power_of_2; 135 u32_t cur_power_of_2 = 0; 136 u8_t i = 0; 137 138 //This is not realy needed (the for also handles this case) but to avoide confusing 139 if(num >= largest_power_of_2) 140 { 141 DbgBreakMsg("num is larger than num_bits_supported"); 142 return largest_power_of_2; 143 } 144 // Exception case 145 if(0 == num) 146 { 147 return 1; 148 } 149 150 // Look for a value that is smaller than prev_power_of_2 and bigger than cur_power_of_2 151 for (i = (num_bits_supported - 1) ; i != 0 ;i--) 152 { 153 cur_power_of_2 = 1 << (i); 154 if(num > cur_power_of_2) 155 { 156 break; 157 } 158 prev_power_of_2 = cur_power_of_2; 159 } 160 return prev_power_of_2; 161 } 162 163 /** 164 * General function that waits for a certain state to change, 165 * not protocol specific. It takes into account vbd-commander 166 * and reset-is-in-progress 167 * 168 * @param pdev 169 * @param curr_state -> what to poll on 170 * @param new_state -> what we're waiting for 171 * 172 * @return lm_status_t TIMEOUT if state didn't change, SUCCESS 173 * otherwise 174 */ 175 176 177 /** 178 * @param pdev 179 * 180 * @return 0 if device is ASIC. 181 */ 182 int lm_chip_is_slow(struct _lm_device_t *pdev) 183 { 184 u32_t val = 0; 185 186 lm_reg_rd_ind(pdev, MISC_REG_CHIP_REV, &val); 187 188 val = (val & 0xf) << 12; 189 190 if (val > CHIP_REV_Cx) { 191 DbgMessage(pdev, VERBOSEi, "Chip is slow\n"); 192 return 1; 193 } else { 194 return 0; 195 } 196 } 197 198 lm_status_t lm_wait_state_change(struct _lm_device_t *pdev, volatile u32_t * curr_state, u32_t new_state) 199 { 200 u32_t delay_us = 0; 201 u32_t to_cnt = 10000 + 2360; // We'll wait 10,000 times 100us (1 second) + 2360 times 25000us (59sec) = total 60 sec 202 // (Winodws only note) the 25000 wait will cause wait to be without CPU stall (look in win_util.c) 203 lm_status_t lm_status = LM_STATUS_SUCCESS; 204 205 206 #ifdef _VBD_CMD_ 207 if (!GET_FLAGS(*g_everest_sim_flags_ptr, EVEREST_SIM_RAMROD)) 208 { 209 *curr_state = new_state; 210 return lm_status; 211 } 212 #endif 213 214 215 /* wait for state change */ 216 while ((*curr_state != new_state) && to_cnt--) 217 { 218 delay_us = (to_cnt >= 2360) ? 100 : 25000 ; 219 mm_wait(pdev, delay_us); 220 221 #ifdef DOS 222 sleep(0); // rescheduling threads, since we don't have a memory barrier. 223 #elif defined(__LINUX) 224 mm_read_barrier(); // synchronize on eth_con->con_state 225 #endif 226 227 // in case reset in progress 228 // we won't get completion so no need to wait 229 if( lm_reset_is_inprogress(pdev) ) 230 { 231 lm_status = LM_STATUS_ABORTED; 232 break; 233 } 234 } 235 236 if ( *curr_state != new_state) 237 { 238 DbgMessage(pdev, FATAL, 239 "lm_wait_state_change: state change timeout, curr state=%d, expected new state=%d!\n", 240 *curr_state, new_state); 241 if (!lm_reset_is_inprogress(pdev)) { 242 #if defined(_VBD_) 243 DbgBreak(); 244 #endif 245 lm_status = LM_STATUS_TIMEOUT; 246 } 247 } 248 249 return lm_status; 250 } 251 252 /******************************************************************************* 253 * Description: 254 * Calculates crc 32 on a buffer 255 * Note: crc32_length MUST be aligned to 8 256 * Return: 257 ******************************************************************************/ 258 u32_t calc_crc32( u8_t* crc32_packet, u32_t crc32_length, u32_t crc32_seed, u8_t complement) 259 { 260 u32_t byte = 0 ; 261 u32_t bit = 0 ; 262 u8_t msb = 0 ; // 1 263 u32_t temp = 0 ; 264 u32_t shft = 0 ; 265 u8_t current_byte = 0 ; 266 u32_t crc32_result = crc32_seed; 267 const u32_t CRC32_POLY = 0x1edc6f41; 268 if( CHK_NULL( crc32_packet) || ERR_IF( 0 == crc32_length ) || ERR_IF( 0 != ( crc32_length % 8 ) ) ) 269 { 270 return crc32_result ; 271 } 272 for (byte = 0; byte < crc32_length; byte = byte + 1) 273 { 274 current_byte = crc32_packet[byte]; 275 for (bit = 0; bit < 8; bit = bit + 1) 276 { 277 msb = (u8_t)(crc32_result >> 31) ; // msb = crc32_result[31]; 278 crc32_result = crc32_result << 1; 279 if ( msb != ( 0x1 & (current_byte>>bit)) ) // (msb != current_byte[bit]) 280 { 281 crc32_result = crc32_result ^ CRC32_POLY; 282 crc32_result |= 1 ;//crc32_result[0] = 1; 283 } 284 } 285 } 286 // Last step is to "mirror" every bit, swap the 4 bytes, and then complement each bit. 287 // 288 // Mirror: 289 temp = crc32_result ; 290 shft = sizeof(crc32_result) * 8 -1 ; 291 for( crc32_result>>= 1; crc32_result; crc32_result>>= 1 ) 292 { 293 temp <<= 1; 294 temp |= crc32_result & 1; 295 shft-- ; 296 } 297 temp <<= shft ; 298 //temp[31-bit] = crc32_result[bit]; 299 // Swap: 300 // crc32_result = {temp[7:0], temp[15:8], temp[23:16], temp[31:24]}; 301 { 302 u32_t t0, t1, t2, t3 ; 303 t0 = ( ( 0x000000ff ) & ( temp >> 24 ) ) ; // temp >> 24 ; 304 t1 = ( ( 0x0000ff00 ) & ( temp >> 8 ) ) ; 305 t2 = ( ( 0x00ff0000 ) & ( temp << 8 ) ) ; 306 t3 = ( ( 0xff000000 ) & ( temp << 24 ) ) ; 307 crc32_result = t0 | t1 | t2 | t3 ; 308 } 309 // Complement: 310 if (complement) 311 { 312 crc32_result = ~crc32_result ; 313 } 314 return crc32_result ; 315 } 316 317 /** 318 * @brief: convert 4 bytes version into 32 bit BCD formatted version 319 * 320 * 1. Format the product_version string: 321 * a. The "Major, "Minor, "Build and "Sub build" bytes are BCD-encoded, and each byte holds two BCD digits. 322 * b. The semantics of these fields follow the semantics specified in DSP4004. 323 * c. The value 0xF in the most-significant nibble of a BCD-encoded value indicates that the most significant nibble should be ignored and the overall field treated as a single digit value. 324 * d. A value of 0xFF indicates that the entire field is not present. 0xFF is not allowed as a value for the fields. 325 * Example: Version 3.7.10.FF --> 0xF3F710FF 326 * 327 328 * @param[in] CONST u8_t IN ver_arr[4] 329 * 330 * @return u32_t value 331 */ 332 u32_t 333 convert_to_bcd( const u8_t IN ver_arr[4] ) 334 { 335 u32_t ver_32 = 0xffffffff; 336 u8_t idx = 0; 337 u8_t ver_current = 0; 338 339 if ( ver_arr ) 340 { 341 ver_32 = 0; 342 343 // convert to BCD format 344 // We have for sure 4 digits only 345 // ARRSIZE(ver_arr) won't work here since in non x86 compile it is NOT 4.... 346 for( idx = 0; idx < 4; idx++ ) 347 { 348 ver_current = ver_arr[idx]; 349 if ( 0 == ( ver_current & 0xf0 ) ) 350 { 351 ver_current |= 0xf0 ; 352 } 353 ver_32 = ( ver_32<<8 ) | ver_current ; 354 } 355 } 356 357 return ver_32; 358 } 359