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

Commit d987160b authored by Michael Buesch's avatar Michael Buesch Committed by David S. Miller
Browse files

b43: Fix rxheader channel parsing



This patch fixes the parsing of the RX data header channel field.

The current code parses the header incorrectly and passes a wrong
channel number and frequency for each frame to mac80211.
The FIXMEs added by this patch don't matter for now as the code
where they live won't get executed anyway. They will be fixed later.

Signed-off-by: default avatarMichael Buesch <mb@bu3sch.de>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 9e8d6f89
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -273,6 +273,8 @@ enum {
#define B43_PHYTYPE_A			0x00
#define B43_PHYTYPE_B			0x01
#define B43_PHYTYPE_G			0x02
#define B43_PHYTYPE_N			0x04
#define B43_PHYTYPE_LP			0x05

/* PHYRegisters */
#define B43_PHY_ILT_A_CTRL		0x0072
+4 −16
Original line number Diff line number Diff line
@@ -39,11 +39,11 @@
#define PAD_BYTES(nr_bytes)		P4D_BYTES( __LINE__ , (nr_bytes))

/* Lightweight function to convert a frequency (in Mhz) to a channel number. */
static inline u8 b43_freq_to_channel_a(int freq)
static inline u8 b43_freq_to_channel_5ghz(int freq)
{
	return ((freq - 5000) / 5);
}
static inline u8 b43_freq_to_channel_bg(int freq)
static inline u8 b43_freq_to_channel_2ghz(int freq)
{
	u8 channel;

@@ -54,19 +54,13 @@ static inline u8 b43_freq_to_channel_bg(int freq)

	return channel;
}
static inline u8 b43_freq_to_channel(struct b43_wldev *dev, int freq)
{
	if (dev->phy.type == B43_PHYTYPE_A)
		return b43_freq_to_channel_a(freq);
	return b43_freq_to_channel_bg(freq);
}

/* Lightweight function to convert a channel number to a frequency (in Mhz). */
static inline int b43_channel_to_freq_a(u8 channel)
static inline int b43_channel_to_freq_5ghz(u8 channel)
{
	return (5000 + (5 * channel));
}
static inline int b43_channel_to_freq_bg(u8 channel)
static inline int b43_channel_to_freq_2ghz(u8 channel)
{
	int freq;

@@ -77,12 +71,6 @@ static inline int b43_channel_to_freq_bg(u8 channel)

	return freq;
}
static inline int b43_channel_to_freq(struct b43_wldev *dev, u8 channel)
{
	if (dev->phy.type == B43_PHYTYPE_A)
		return b43_channel_to_freq_a(channel);
	return b43_channel_to_freq_bg(channel);
}

static inline int b43_is_cck_rate(int rate)
{
+19 −8
Original line number Diff line number Diff line
@@ -531,21 +531,32 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
	switch (chanstat & B43_RX_CHAN_PHYTYPE) {
	case B43_PHYTYPE_A:
		status.phymode = MODE_IEEE80211A;
		status.freq = chanid;
		status.channel = b43_freq_to_channel_a(chanid);
		break;
	case B43_PHYTYPE_B:
		status.phymode = MODE_IEEE80211B;
		status.freq = chanid + 2400;
		status.channel = b43_freq_to_channel_bg(chanid + 2400);
		B43_WARN_ON(1);
		/* FIXME: We don't really know which value the "chanid" contains.
		 *        So the following assignment might be wrong. */
		status.channel = chanid;
		status.freq = b43_channel_to_freq_5ghz(status.channel);
		break;
	case B43_PHYTYPE_G:
		status.phymode = MODE_IEEE80211G;
		/* chanid is the radio channel cookie value as used
		 * to tune the radio. */
		status.freq = chanid + 2400;
		status.channel = b43_freq_to_channel_bg(chanid + 2400);
		status.channel = b43_freq_to_channel_2ghz(status.freq);
		break;
	case B43_PHYTYPE_N:
		status.phymode = 0xDEAD /*FIXME MODE_IEEE80211N*/;
		/* chanid is the SHM channel cookie. Which is the plain
		 * channel number in b43. */
		status.channel = chanid;
		if (chanstat & B43_RX_CHAN_5GHZ)
			status.freq = b43_freq_to_channel_5ghz(status.freq);
		else
			status.freq = b43_freq_to_channel_2ghz(status.freq);
		break;
	default:
		B43_WARN_ON(1);
		goto drop;
	}

	dev->stats.last_rx = jiffies;
+36 −29
Original line number Diff line number Diff line
@@ -170,7 +170,13 @@ struct b43_rxhdr_fw4 {
#define B43_RX_PHYST3_TRSTATE		0x0400 /* TR state */

/* MAC RX Status */
#define B43_RX_MAC_BEACONSENT	0x00008000	/* Beacon send flag */
#define B43_RX_MAC_RXST_VALID		0x01000000 /* PHY RXST valid */
#define B43_RX_MAC_TKIP_MICERR		0x00100000 /* TKIP MIC error */
#define B43_RX_MAC_TKIP_MICATT		0x00080000 /* TKIP MIC attempted */
#define B43_RX_MAC_AGGTYPE		0x00060000 /* Aggregation type */
#define B43_RX_MAC_AGGTYPE_SHIFT	17
#define B43_RX_MAC_AMSDU		0x00010000 /* A-MSDU mask */
#define B43_RX_MAC_BEACONSENT		0x00008000 /* Beacon sent flag */
#define B43_RX_MAC_KEYIDX		0x000007E0 /* Key index */
#define B43_RX_MAC_KEYIDX_SHIFT		5
#define B43_RX_MAC_DECERR		0x00000010 /* Decrypt error */
@@ -180,11 +186,12 @@ struct b43_rxhdr_fw4 {
#define B43_RX_MAC_FCSERR		0x00000001 /* FCS error */

/* RX channel */
#define B43_RX_CHAN_GAIN		0xFC00	/* Gain */
#define B43_RX_CHAN_GAIN_SHIFT	10
#define B43_RX_CHAN_ID		0x03FC	/* Channel ID */
#define B43_RX_CHAN_ID_SHIFT	2
#define B43_RX_CHAN_PHYTYPE		0x0003	/* PHY type */
#define B43_RX_CHAN_40MHZ		0x1000 /* 40 Mhz channel width */
#define B43_RX_CHAN_5GHZ		0x0800 /* 5 Ghz band */
#define B43_RX_CHAN_ID			0x07F8 /* Channel ID */
#define B43_RX_CHAN_ID_SHIFT		3
#define B43_RX_CHAN_PHYTYPE		0x0007 /* PHY type */


u8 b43_plcp_get_ratecode_cck(const u8 bitrate);
u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate);