d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/*******************************************************************************
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * CDDL HEADER START
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * The contents of this file are subject to the terms of the
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Common Development and Distribution License (the "License").
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * You may not use this file except in compliance with the License.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * or http://www.opensolaris.org/os/licensing.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * See the License for the specific language governing permissions
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * and limitations under the License.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * When distributing Covered Code, include this CDDL HEADER in each
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * If applicable, add the following below this CDDL HEADER, with the
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * fields enclosed by brackets "[]" replaced with your own identifying
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * information: Portions Copyright [yyyy] [name of copyright owner]
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * CDDL HEADER END
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Copyright 2014 QLogic Corporation
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * The contents of this file are subject to the terms of the
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * QLogic End User License (the "License").
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * You may not use this file except in compliance with the License.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * You can obtain a copy of the License at
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * QLogic_End_User_Software_License.txt
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * See the License for the specific language governing permissions
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * and limitations under the License.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Module Description:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * This file contains general LM utility functions
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ******************************************************************************/
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#include "lm5710.h"
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#ifdef _VBD_CMD_
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#include "everest_sim.h"
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#endif
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define MASK_01010101 (((unsigned int)(-1))/3)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define MASK_00110011 (((unsigned int)(-1))/5)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define MASK_00001111 (((unsigned int)(-1))/17)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiu32_t count_bits(u32_t n)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi n = (n & MASK_01010101) + ((n >> 1) & MASK_01010101) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi n = (n & MASK_00110011) + ((n >> 2) & MASK_00110011) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi n = (n & MASK_00001111) + ((n >> 4) & MASK_00001111) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return n % 255 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiunsigned long log2_align(unsigned long n)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi unsigned long ret = n ? 1 : 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi unsigned long _n = n >> 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi while (_n)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi _n >>= 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ret <<= 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (ret < n)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ret <<= 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return ret;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/**
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @description
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Should be moved to a common file.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Calculates the lower align of power 2.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Values lower than 0 are returned directly.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @param n
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @return unsigned long
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * lower align of power 2.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiunsigned long power2_lower_align(unsigned long n)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi unsigned long ret = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if(0 == n)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if(TRUE == POWER_OF_2(n))
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // The number is already a power of 2.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return n;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi //Calculates the lower align of power 2.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ret = log2_align(n);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf(FALSE == POWER_OF_2(ret));
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ret >>= 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return ret;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/*
d14abf155341d55053c76eeec58b787a456b753bRobert MustacchiLog2
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchithis function calculates rounded LOG2 of a certain number
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchie.g.: LOG2(1080) = 10 (2^10=1024)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi*/
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiu32_t LOG2(u32_t v){
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t r=0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi while (v >>= 1) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi r++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return r;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/**
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @description
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Should be moved to a common place.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Find the next power of 2 that is larger than "num".
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @param num - The variable to find a power of 2 that is
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * larger.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @param num_bits_supported - The largest number of bits
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * supported
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @return u32_t - The next power of 2 that is larger than
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * "num".
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiu32_t
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiupper_align_power_of_2(IN const u16_t num,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi IN const u8_t num_bits_supported)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t const largest_power_of_2 = 1 << (num_bits_supported - 1);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t prev_power_of_2 = largest_power_of_2;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t cur_power_of_2 = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t i = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi //This is not realy needed (the for also handles this case) but to avoide confusing
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if(num >= largest_power_of_2)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakMsg("num is larger than num_bits_supported");
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return largest_power_of_2;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // Exception case
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if(0 == num)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // Look for a value that is smaller than prev_power_of_2 and bigger than cur_power_of_2
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi for (i = (num_bits_supported - 1) ; i != 0 ;i--)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi cur_power_of_2 = 1 << (i);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if(num > cur_power_of_2)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi break;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi prev_power_of_2 = cur_power_of_2;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return prev_power_of_2;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/**
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * General function that waits for a certain state to change,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * not protocol specific. It takes into account vbd-commander
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * and reset-is-in-progress
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @param pdev
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @param curr_state -> what to poll on
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @param new_state -> what we're waiting for
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @return lm_status_t TIMEOUT if state didn't change, SUCCESS
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * otherwise
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/**
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @param pdev
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @return 0 if device is ASIC.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiint lm_chip_is_slow(struct _lm_device_t *pdev)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t val = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_reg_rd_ind(pdev, MISC_REG_CHIP_REV, &val);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi val = (val & 0xf) << 12;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (val > CHIP_REV_Cx) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgMessage(pdev, VERBOSEi, "Chip is slow\n");
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi } else {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchilm_status_t lm_wait_state_change(struct _lm_device_t *pdev, volatile u32_t * curr_state, u32_t new_state)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t delay_us = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t to_cnt = 10000 + 2360; // We'll wait 10,000 times 100us (1 second) + 2360 times 25000us (59sec) = total 60 sec
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // (Winodws only note) the 25000 wait will cause wait to be without CPU stall (look in win_util.c)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_status_t lm_status = LM_STATUS_SUCCESS;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#ifdef _VBD_CMD_
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (!GET_FLAGS(*g_everest_sim_flags_ptr, EVEREST_SIM_RAMROD))
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *curr_state = new_state;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return lm_status;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#endif
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* wait for state change */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi while ((*curr_state != new_state) && to_cnt--)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi delay_us = (to_cnt >= 2360) ? 100 : 25000 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi mm_wait(pdev, delay_us);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi #ifdef DOS
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi sleep(0); // rescheduling threads, since we don't have a memory barrier.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi #elif defined(__LINUX)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi mm_read_barrier(); // synchronize on eth_con->con_state
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi #endif
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // in case reset in progress
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // we won't get completion so no need to wait
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if( lm_reset_is_inprogress(pdev) )
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_status = LM_STATUS_ABORTED;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi break;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if ( *curr_state != new_state)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgMessage(pdev, FATAL,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi "lm_wait_state_change: state change timeout, curr state=%d, expected new state=%d!\n",
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *curr_state, new_state);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (!lm_reset_is_inprogress(pdev)) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi #if defined(_VBD_)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreak();
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi #endif
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_status = LM_STATUS_TIMEOUT;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return lm_status;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/*******************************************************************************
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Description:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Calculates crc 32 on a buffer
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Note: crc32_length MUST be aligned to 8
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Return:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ******************************************************************************/
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiu32_t calc_crc32( u8_t* crc32_packet, u32_t crc32_length, u32_t crc32_seed, u8_t complement)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t byte = 0 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t bit = 0 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t msb = 0 ; // 1
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t temp = 0 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t shft = 0 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t current_byte = 0 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t crc32_result = crc32_seed;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi const u32_t CRC32_POLY = 0x1edc6f41;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if( CHK_NULL( crc32_packet) || ERR_IF( 0 == crc32_length ) || ERR_IF( 0 != ( crc32_length % 8 ) ) )
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return crc32_result ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi for (byte = 0; byte < crc32_length; byte = byte + 1)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi current_byte = crc32_packet[byte];
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi for (bit = 0; bit < 8; bit = bit + 1)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi msb = (u8_t)(crc32_result >> 31) ; // msb = crc32_result[31];
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi crc32_result = crc32_result << 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if ( msb != ( 0x1 & (current_byte>>bit)) ) // (msb != current_byte[bit])
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi crc32_result = crc32_result ^ CRC32_POLY;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi crc32_result |= 1 ;//crc32_result[0] = 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // Last step is to "mirror" every bit, swap the 4 bytes, and then complement each bit.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi //
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // Mirror:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi temp = crc32_result ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi shft = sizeof(crc32_result) * 8 -1 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi for( crc32_result>>= 1; crc32_result; crc32_result>>= 1 )
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi temp <<= 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi temp |= crc32_result & 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi shft-- ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi temp <<= shft ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi //temp[31-bit] = crc32_result[bit];
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // Swap:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // crc32_result = {temp[7:0], temp[15:8], temp[23:16], temp[31:24]};
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t t0, t1, t2, t3 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi t0 = ( ( 0x000000ff ) & ( temp >> 24 ) ) ; // temp >> 24 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi t1 = ( ( 0x0000ff00 ) & ( temp >> 8 ) ) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi t2 = ( ( 0x00ff0000 ) & ( temp << 8 ) ) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi t3 = ( ( 0xff000000 ) & ( temp << 24 ) ) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi crc32_result = t0 | t1 | t2 | t3 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // Complement:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (complement)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi crc32_result = ~crc32_result ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return crc32_result ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/**
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @brief: convert 4 bytes version into 32 bit BCD formatted version
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * 1. Format the product_version string:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * a. The "Major, "Minor, "Build and "Sub build" bytes are BCD-encoded, and each byte holds two BCD digits.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * b. The semantics of these fields follow the semantics specified in DSP4004.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * 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.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * d. A value of 0xFF indicates that the entire field is not present. 0xFF is not allowed as a value for the fields.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Example: Version 3.7.10.FF --> 0xF3F710FF
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @param[in] CONST u8_t IN ver_arr[4]
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * @return u32_t value
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiu32_t
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiconvert_to_bcd( const u8_t IN ver_arr[4] )
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t ver_32 = 0xffffffff;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t idx = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t ver_current = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if ( ver_arr )
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ver_32 = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // convert to BCD format
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // We have for sure 4 digits only
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // ARRSIZE(ver_arr) won't work here since in non x86 compile it is NOT 4....
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi for( idx = 0; idx < 4; idx++ )
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ver_current = ver_arr[idx];
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if ( 0 == ( ver_current & 0xf0 ) )
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ver_current |= 0xf0 ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ver_32 = ( ver_32<<8 ) | ver_current ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return ver_32;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}