Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5a43355 authored by Priit Laes's avatar Priit Laes Committed by Kalle Valo
Browse files

b43: Use cordic algorithm from kernel library



Kernel library has a common cordic algorithm which is identical
to internally implemented one, so use it and drop the duplicate
implementation.

Acked-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: default avatarPriit Laes <plaes@plaes.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 8ea3819c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ config B43
	select BCMA if B43_BCMA
	select SSB if B43_SSB
	select FW_LOADER
	select CORDIC
	---help---
	  b43 is a driver for the Broadcom 43xx series wireless devices.

+0 −47
Original line number Diff line number Diff line
@@ -604,50 +604,3 @@ void b43_phy_force_clock(struct b43_wldev *dev, bool force)
#endif
	}
}

/* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */
struct b43_c32 b43_cordic(int theta)
{
	static const u32 arctg[] = {
		2949120, 1740967, 919879, 466945, 234379, 117304,
		  58666,   29335,  14668,   7334,   3667,   1833,
		    917,     458,    229,    115,     57,     29,
	};
	u8 i;
	s32 tmp;
	s8 signx = 1;
	s32 angle = 0;
	struct b43_c32 ret = { .i = 39797, .q = 0, };

	while (theta > (180 << 16))
		theta -= (360 << 16);
	while (theta < -(180 << 16))
		theta += (360 << 16);

	if (theta > (90 << 16)) {
		theta -= (180 << 16);
		signx = -1;
	} else if (theta < -(90 << 16)) {
		theta += (180 << 16);
		signx = -1;
	}

	for (i = 0; i <= 17; i++) {
		if (theta > angle) {
			tmp = ret.i - (ret.q >> i);
			ret.q += ret.i >> i;
			ret.i = tmp;
			angle += arctg[i];
		} else {
			tmp = ret.i + (ret.q >> i);
			ret.q -= ret.i >> i;
			ret.i = tmp;
			angle -= arctg[i];
		}
	}

	ret.i *= signx;
	ret.q *= signx;

	return ret;
}
+0 −9
Original line number Diff line number Diff line
@@ -7,13 +7,6 @@

struct b43_wldev;

/* Complex number using 2 32-bit signed integers */
struct b43_c32 { s32 i, q; };

#define CORDIC_CONVERT(value)	(((value) >= 0) ? \
				 ((((value) >> 15) + 1) >> 1) : \
				 -((((-(value)) >> 15) + 1) >> 1))

/* PHY register routing bits */
#define B43_PHYROUTE			0x0C00 /* PHY register routing bits mask */
#define  B43_PHYROUTE_BASE		0x0000 /* Base registers */
@@ -450,6 +443,4 @@ bool b43_is_40mhz(struct b43_wldev *dev);

void b43_phy_force_clock(struct b43_wldev *dev, bool force);

struct b43_c32 b43_cordic(int theta);

#endif /* LINUX_B43_PHY_COMMON_H_ */
+7 −6
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@

*/

#include <linux/cordic.h>
#include <linux/slab.h>

#include "b43.h"
@@ -1780,9 +1781,9 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
{
	struct b43_phy_lp *lpphy = dev->phy.lp;
	u16 buf[64];
	int i, samples = 0, angle = 0;
	int i, samples = 0, theta = 0;
	int rotation = (((36 * freq) / 20) << 16) / 100;
	struct b43_c32 sample;
	struct cordic_iq sample;

	lpphy->tx_tone_freq = freq;

@@ -1798,10 +1799,10 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
	}

	for (i = 0; i < samples; i++) {
		sample = b43_cordic(angle);
		angle += rotation;
		buf[i] = CORDIC_CONVERT((sample.i * max) & 0xFF) << 8;
		buf[i] |= CORDIC_CONVERT((sample.q * max) & 0xFF);
		sample = cordic_calc_iq(CORDIC_FIXED(theta));
		theta += rotation;
		buf[i] = CORDIC_FLOAT((sample.i * max) & 0xFF) << 8;
		buf[i] |= CORDIC_FLOAT((sample.q * max) & 0xFF);
	}

	b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf);
+7 −6
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@

*/

#include <linux/cordic.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -1513,7 +1514,7 @@ static void b43_radio_init2055(struct b43_wldev *dev)

/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */
static int b43_nphy_load_samples(struct b43_wldev *dev,
					struct b43_c32 *samples, u16 len) {
					struct cordic_iq *samples, u16 len) {
	struct b43_phy_n *nphy = dev->phy.n;
	u16 i;
	u32 *data;
@@ -1544,7 +1545,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
{
	int i;
	u16 bw, len, rot, angle;
	struct b43_c32 *samples;
	struct cordic_iq *samples;

	bw = b43_is_40mhz(dev) ? 40 : 20;
	len = bw << 3;
@@ -1561,7 +1562,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
		len = bw << 1;
	}

	samples = kcalloc(len, sizeof(struct b43_c32), GFP_KERNEL);
	samples = kcalloc(len, sizeof(struct cordic_iq), GFP_KERNEL);
	if (!samples) {
		b43err(dev->wl, "allocation for samples generation failed\n");
		return 0;
@@ -1570,10 +1571,10 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
	angle = 0;

	for (i = 0; i < len; i++) {
		samples[i] = b43_cordic(angle);
		samples[i] = cordic_calc_iq(CORDIC_FIXED(angle));
		angle += rot;
		samples[i].q = CORDIC_CONVERT(samples[i].q * max);
		samples[i].i = CORDIC_CONVERT(samples[i].i * max);
		samples[i].q = CORDIC_FLOAT(samples[i].q * max);
		samples[i].i = CORDIC_FLOAT(samples[i].i * max);
	}

	i = b43_nphy_load_samples(dev, samples, len);