 5b435de0d7
			
		
	
	
	5b435de0d7
	
	
	
		
			
			Add the brcm80211 tree to drivers/net/wireless, and disable the version that's in drivers/staging. This version includes the sources currently in staging, plus any changes that have been sent out for review. Sources in staging will be deleted in a followup patch. Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
		
			
				
	
	
		
			308 lines
		
	
	
	
		
			7.9 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			308 lines
		
	
	
	
		
			7.9 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2010 Broadcom Corporation
 | |
|  *
 | |
|  * Permission to use, copy, modify, and/or distribute this software for any
 | |
|  * purpose with or without fee is hereby granted, provided that the above
 | |
|  * copyright notice and this permission notice appear in all copies.
 | |
|  *
 | |
|  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | |
|  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | |
|  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | |
|  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | |
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | |
|  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | |
|  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | |
|  */
 | |
| 
 | |
| #include "phy_qmath.h"
 | |
| 
 | |
| /*
 | |
|  * Description: This function make 16 bit unsigned multiplication.
 | |
|  * To fit the output into 16 bits the 32 bit multiplication result is right
 | |
|  * shifted by 16 bits.
 | |
|  */
 | |
| u16 qm_mulu16(u16 op1, u16 op2)
 | |
| {
 | |
| 	return (u16) (((u32) op1 * (u32) op2) >> 16);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Description: This function make 16 bit multiplication and return the result
 | |
|  * in 16 bits. To fit the multiplication result into 16 bits the multiplication
 | |
|  * result is right shifted by 15 bits. Right shifting 15 bits instead of 16 bits
 | |
|  * is done to remove the extra sign bit formed due to the multiplication.
 | |
|  * When both the 16bit inputs are 0x8000 then the output is saturated to
 | |
|  * 0x7fffffff.
 | |
|  */
 | |
| s16 qm_muls16(s16 op1, s16 op2)
 | |
| {
 | |
| 	s32 result;
 | |
| 	if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000)
 | |
| 		result = 0x7fffffff;
 | |
| 	else
 | |
| 		result = ((s32) (op1) * (s32) (op2));
 | |
| 
 | |
| 	return (s16) (result >> 15);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Description: This function add two 32 bit numbers and return the 32bit
 | |
|  * result. If the result overflow 32 bits, the output will be saturated to
 | |
|  * 32bits.
 | |
|  */
 | |
| s32 qm_add32(s32 op1, s32 op2)
 | |
| {
 | |
| 	s32 result;
 | |
| 	result = op1 + op2;
 | |
| 	if (op1 < 0 && op2 < 0 && result > 0)
 | |
| 		result = 0x80000000;
 | |
| 	else if (op1 > 0 && op2 > 0 && result < 0)
 | |
| 		result = 0x7fffffff;
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Description: This function add two 16 bit numbers and return the 16bit
 | |
|  * result. If the result overflow 16 bits, the output will be saturated to
 | |
|  * 16bits.
 | |
|  */
 | |
| s16 qm_add16(s16 op1, s16 op2)
 | |
| {
 | |
| 	s16 result;
 | |
| 	s32 temp = (s32) op1 + (s32) op2;
 | |
| 	if (temp > (s32) 0x7fff)
 | |
| 		result = (s16) 0x7fff;
 | |
| 	else if (temp < (s32) 0xffff8000)
 | |
| 		result = (s16) 0xffff8000;
 | |
| 	else
 | |
| 		result = (s16) temp;
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Description: This function make 16 bit subtraction and return the 16bit
 | |
|  * result. If the result overflow 16 bits, the output will be saturated to
 | |
|  * 16bits.
 | |
|  */
 | |
| s16 qm_sub16(s16 op1, s16 op2)
 | |
| {
 | |
| 	s16 result;
 | |
| 	s32 temp = (s32) op1 - (s32) op2;
 | |
| 	if (temp > (s32) 0x7fff)
 | |
| 		result = (s16) 0x7fff;
 | |
| 	else if (temp < (s32) 0xffff8000)
 | |
| 		result = (s16) 0xffff8000;
 | |
| 	else
 | |
| 		result = (s16) temp;
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Description: This function make a 32 bit saturated left shift when the
 | |
|  * specified shift is +ve. This function will make a 32 bit right shift when
 | |
|  * the specified shift is -ve. This function return the result after shifting
 | |
|  * operation.
 | |
|  */
 | |
| s32 qm_shl32(s32 op, int shift)
 | |
| {
 | |
| 	int i;
 | |
| 	s32 result;
 | |
| 	result = op;
 | |
| 	if (shift > 31)
 | |
| 		shift = 31;
 | |
| 	else if (shift < -31)
 | |
| 		shift = -31;
 | |
| 	if (shift >= 0) {
 | |
| 		for (i = 0; i < shift; i++)
 | |
| 			result = qm_add32(result, result);
 | |
| 	} else {
 | |
| 		result = result >> (-shift);
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Description: This function make a 16 bit saturated left shift when the
 | |
|  * specified shift is +ve. This function will make a 16 bit right shift when
 | |
|  * the specified shift is -ve. This function return the result after shifting
 | |
|  * operation.
 | |
|  */
 | |
| s16 qm_shl16(s16 op, int shift)
 | |
| {
 | |
| 	int i;
 | |
| 	s16 result;
 | |
| 	result = op;
 | |
| 	if (shift > 15)
 | |
| 		shift = 15;
 | |
| 	else if (shift < -15)
 | |
| 		shift = -15;
 | |
| 	if (shift > 0) {
 | |
| 		for (i = 0; i < shift; i++)
 | |
| 			result = qm_add16(result, result);
 | |
| 	} else {
 | |
| 		result = result >> (-shift);
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Description: This function make a 16 bit right shift when shift is +ve.
 | |
|  * This function make a 16 bit saturated left shift when shift is -ve. This
 | |
|  * function return the result of the shift operation.
 | |
|  */
 | |
| s16 qm_shr16(s16 op, int shift)
 | |
| {
 | |
| 	return qm_shl16(op, -shift);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Description: This function return the number of redundant sign bits in a
 | |
|  * 32 bit number. Example: qm_norm32(0x00000080) = 23
 | |
|  */
 | |
| s16 qm_norm32(s32 op)
 | |
| {
 | |
| 	u16 u16extraSignBits;
 | |
| 	if (op == 0) {
 | |
| 		return 31;
 | |
| 	} else {
 | |
| 		u16extraSignBits = 0;
 | |
| 		while ((op >> 31) == (op >> 30)) {
 | |
| 			u16extraSignBits++;
 | |
| 			op = op << 1;
 | |
| 		}
 | |
| 	}
 | |
| 	return u16extraSignBits;
 | |
| }
 | |
| 
 | |
| /* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
 | |
| static const s16 log_table[] = {
 | |
| 	0,
 | |
| 	1455,
 | |
| 	2866,
 | |
| 	4236,
 | |
| 	5568,
 | |
| 	6863,
 | |
| 	8124,
 | |
| 	9352,
 | |
| 	10549,
 | |
| 	11716,
 | |
| 	12855,
 | |
| 	13968,
 | |
| 	15055,
 | |
| 	16117,
 | |
| 	17156,
 | |
| 	18173,
 | |
| 	19168,
 | |
| 	20143,
 | |
| 	21098,
 | |
| 	22034,
 | |
| 	22952,
 | |
| 	23852,
 | |
| 	24736,
 | |
| 	25604,
 | |
| 	26455,
 | |
| 	27292,
 | |
| 	28114,
 | |
| 	28922,
 | |
| 	29717,
 | |
| 	30498,
 | |
| 	31267,
 | |
| 	32024
 | |
| };
 | |
| 
 | |
| #define LOG_TABLE_SIZE 32       /* log_table size */
 | |
| #define LOG2_LOG_TABLE_SIZE 5   /* log2(log_table size) */
 | |
| #define Q_LOG_TABLE 15          /* qformat of log_table */
 | |
| #define LOG10_2         19728   /* log10(2) in q.16 */
 | |
| 
 | |
| /*
 | |
|  * Description:
 | |
|  * This routine takes the input number N and its q format qN and compute
 | |
|  * the log10(N). This routine first normalizes the input no N.	Then N is in
 | |
|  * mag*(2^x) format. mag is any number in the range 2^30-(2^31 - 1).
 | |
|  * Then log2(mag * 2^x) = log2(mag) + x is computed. From that
 | |
|  * log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
 | |
|  * This routine looks the log2 value in the table considering
 | |
|  * LOG2_LOG_TABLE_SIZE+1 MSBs. As the MSB is always 1, only next
 | |
|  * LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. Next 16 MSBs are used
 | |
|  * for interpolation.
 | |
|  * Inputs:
 | |
|  * N - number to which log10 has to be found.
 | |
|  * qN - q format of N
 | |
|  * log10N - address where log10(N) will be written.
 | |
|  * qLog10N - address where log10N qformat will be written.
 | |
|  * Note/Problem:
 | |
|  * For accurate results input should be in normalized or near normalized form.
 | |
|  */
 | |
| void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
 | |
| {
 | |
| 	s16 s16norm, s16tableIndex, s16errorApproximation;
 | |
| 	u16 u16offset;
 | |
| 	s32 s32log;
 | |
| 
 | |
| 	/* normalize the N. */
 | |
| 	s16norm = qm_norm32(N);
 | |
| 	N = N << s16norm;
 | |
| 
 | |
| 	/* The qformat of N after normalization.
 | |
| 	 * -30 is added to treat the no as between 1.0 to 2.0
 | |
| 	 * i.e. after adding the -30 to the qformat the decimal point will be
 | |
| 	 * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
 | |
| 	 * at the right side of 30th bit.
 | |
| 	 */
 | |
| 	qN = qN + s16norm - 30;
 | |
| 
 | |
| 	/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the
 | |
| 	 * MSB */
 | |
| 	s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
 | |
| 
 | |
| 	/* remove the MSB. the MSB is always 1 after normalization. */
 | |
| 	s16tableIndex =
 | |
| 		s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
 | |
| 
 | |
| 	/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
 | |
| 	N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
 | |
| 
 | |
| 	/* take the offset as the 16 MSBS after table index.
 | |
| 	 */
 | |
| 	u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
 | |
| 
 | |
| 	/* look the log value in the table. */
 | |
| 	s32log = log_table[s16tableIndex];      /* q.15 format */
 | |
| 
 | |
| 	/* interpolate using the offset. q.15 format. */
 | |
| 	s16errorApproximation = (s16) qm_mulu16(u16offset,
 | |
| 				(u16) (log_table[s16tableIndex + 1] -
 | |
| 				       log_table[s16tableIndex]));
 | |
| 
 | |
| 	 /* q.15 format */
 | |
| 	s32log = qm_add16((s16) s32log, s16errorApproximation);
 | |
| 
 | |
| 	/* adjust for the qformat of the N as
 | |
| 	 * log2(mag * 2^x) = log2(mag) + x
 | |
| 	 */
 | |
| 	s32log = qm_add32(s32log, ((s32) -qN) << 15);   /* q.15 format */
 | |
| 
 | |
| 	/* normalize the result. */
 | |
| 	s16norm = qm_norm32(s32log);
 | |
| 
 | |
| 	/* bring all the important bits into lower 16 bits */
 | |
| 	/* q.15+s16norm-16 format */
 | |
| 	s32log = qm_shl32(s32log, s16norm - 16);
 | |
| 
 | |
| 	/* compute the log10(N) by multiplying log2(N) with log10(2).
 | |
| 	 * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
 | |
| 	 * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
 | |
| 	 */
 | |
| 	*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
 | |
| 
 | |
| 	/* write the q format of the result. */
 | |
| 	*qLog10N = 15 + s16norm - 16 + 1;
 | |
| 
 | |
| 	return;
 | |
| }
 |