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

Commit 3311abbb authored by Rafał Miłecki's avatar Rafał Miłecki Committed by John W. Linville
Browse files

b43: fill PHY ctl word1 in TX header for N-PHY



This patch fixes tramissing on OFDM rates for PHYs 1 and 2. There is
still something wrong with PHYs 3+. Tests has shown decreasing of
performance on CCK rates by 1-2%, we have to live with that.
Additionaly this noticeably reduces amount of PHY errors. They were
mostly produced by auto-switching to higher rate for better
performanced, which resulted in no transmit at all and PHY errors.

Signed-off-by: default avatarRafał Miłecki <zajec5@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 850bedcc
Loading
Loading
Loading
Loading
+73 −0
Original line number Original line Diff line number Diff line
@@ -32,6 +32,36 @@
#include "dma.h"
#include "dma.h"
#include "pio.h"
#include "pio.h"


static const struct b43_tx_legacy_rate_phy_ctl_entry b43_tx_legacy_rate_phy_ctl[] = {
	{ B43_CCK_RATE_1MB,	0x0,			0x0 },
	{ B43_CCK_RATE_2MB,	0x0,			0x1 },
	{ B43_CCK_RATE_5MB,	0x0,			0x2 },
	{ B43_CCK_RATE_11MB,	0x0,			0x3 },
	{ B43_OFDM_RATE_6MB,	B43_TXH_PHY1_CRATE_1_2,	B43_TXH_PHY1_MODUL_BPSK },
	{ B43_OFDM_RATE_9MB,	B43_TXH_PHY1_CRATE_3_4,	B43_TXH_PHY1_MODUL_BPSK },
	{ B43_OFDM_RATE_12MB,	B43_TXH_PHY1_CRATE_1_2,	B43_TXH_PHY1_MODUL_QPSK },
	{ B43_OFDM_RATE_18MB,	B43_TXH_PHY1_CRATE_3_4,	B43_TXH_PHY1_MODUL_QPSK },
	{ B43_OFDM_RATE_24MB,	B43_TXH_PHY1_CRATE_1_2,	B43_TXH_PHY1_MODUL_QAM16 },
	{ B43_OFDM_RATE_36MB,	B43_TXH_PHY1_CRATE_3_4,	B43_TXH_PHY1_MODUL_QAM16 },
	{ B43_OFDM_RATE_48MB,	B43_TXH_PHY1_CRATE_2_3,	B43_TXH_PHY1_MODUL_QAM64 },
	{ B43_OFDM_RATE_54MB,	B43_TXH_PHY1_CRATE_3_4,	B43_TXH_PHY1_MODUL_QAM64 },
};

static const struct b43_tx_legacy_rate_phy_ctl_entry *
b43_tx_legacy_rate_phy_ctl_ent(u8 bitrate)
{
	const struct b43_tx_legacy_rate_phy_ctl_entry *e;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(b43_tx_legacy_rate_phy_ctl); i++) {
		e = &(b43_tx_legacy_rate_phy_ctl[i]);
		if (e->bitrate == bitrate)
			return e;
	}

	B43_WARN_ON(1);
	return NULL;
}


/* Extract the bitrate index out of a CCK PLCP header. */
/* Extract the bitrate index out of a CCK PLCP header. */
static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
@@ -145,6 +175,34 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
	}
	}
}
}


static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
{
	const struct b43_phy *phy = &dev->phy;
	const struct b43_tx_legacy_rate_phy_ctl_entry *e;
	u16 control = 0;
	u16 bw;

	if (phy->type == B43_PHYTYPE_LP)
		bw = B43_TXH_PHY1_BW_20;
	else /* FIXME */
		bw = B43_TXH_PHY1_BW_20;

	if (0) { /* FIXME: MIMO */
	} else if (b43_is_cck_rate(bitrate) && phy->type != B43_PHYTYPE_LP) {
		control = bw;
	} else {
		control = bw;
		e = b43_tx_legacy_rate_phy_ctl_ent(bitrate);
		if (e) {
			control |= e->coding_rate;
			control |= e->modulation;
		}
		control |= B43_TXH_PHY1_MODE_SISO;
	}

	return control;
}

static u8 b43_calc_fallback_rate(u8 bitrate)
static u8 b43_calc_fallback_rate(u8 bitrate)
{
{
	switch (bitrate) {
	switch (bitrate) {
@@ -437,6 +495,14 @@ int b43_generate_txhdr(struct b43_wldev *dev,
			extra_ft |= B43_TXH_EFT_RTSFB_OFDM;
			extra_ft |= B43_TXH_EFT_RTSFB_OFDM;
		else
		else
			extra_ft |= B43_TXH_EFT_RTSFB_CCK;
			extra_ft |= B43_TXH_EFT_RTSFB_CCK;

		if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS &&
		    phy->type == B43_PHYTYPE_N) {
			txhdr->phy_ctl1_rts = cpu_to_le16(
				b43_generate_tx_phy_ctl1(dev, rts_rate));
			txhdr->phy_ctl1_rts_fb = cpu_to_le16(
				b43_generate_tx_phy_ctl1(dev, rts_rate_fb));
		}
	}
	}


	/* Magic cookie */
	/* Magic cookie */
@@ -445,6 +511,13 @@ int b43_generate_txhdr(struct b43_wldev *dev,
	else
	else
		txhdr->new_format.cookie = cpu_to_le16(cookie);
		txhdr->new_format.cookie = cpu_to_le16(cookie);


	if (phy->type == B43_PHYTYPE_N) {
		txhdr->phy_ctl1 =
			cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));
		txhdr->phy_ctl1_fb =
			cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate_fb));
	}

	/* Apply the bitfields */
	/* Apply the bitfields */
	txhdr->mac_ctl = cpu_to_le32(mac_ctl);
	txhdr->mac_ctl = cpu_to_le32(mac_ctl);
	txhdr->phy_ctl = cpu_to_le16(phy_ctl);
	txhdr->phy_ctl = cpu_to_le16(phy_ctl);
+6 −0
Original line number Original line Diff line number Diff line
@@ -73,6 +73,12 @@ struct b43_txhdr {
	} __packed;
	} __packed;
} __packed;
} __packed;


struct b43_tx_legacy_rate_phy_ctl_entry {
	u8 bitrate;
	u16 coding_rate;
	u16 modulation;
};

/* MAC TX control */
/* MAC TX control */
#define B43_TXH_MAC_USEFBR		0x10000000 /* Use fallback rate for this AMPDU */
#define B43_TXH_MAC_USEFBR		0x10000000 /* Use fallback rate for this AMPDU */
#define B43_TXH_MAC_KEYIDX		0x0FF00000 /* Security key index */
#define B43_TXH_MAC_KEYIDX		0x0FF00000 /* Security key index */