Commit 6ecb2690 authored by Michael Buesch's avatar Michael Buesch Committed by John W. Linville

[PATCH] bcm43xx: set default attenuation values.

Signed-off-by: default avatarMichael Buesch <mbuesch@freenet.de>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 0ac59dae
...@@ -507,14 +507,23 @@ struct bcm43xx_radioinfo { ...@@ -507,14 +507,23 @@ struct bcm43xx_radioinfo {
u16 version; u16 version;
u8 revision; u8 revision;
/* 0: baseband attenuation,
* 1: radio attenuation,
* 2: tx_CTL1
* 3: tx_CTL2
*/
u16 txpower[4];
/* Desired TX power in dBm Q5.2 */ /* Desired TX power in dBm Q5.2 */
u16 txpower_desired; u16 txpower_desired;
/* TX Power control values. */
union {
/* B/G PHY */
struct {
u16 baseband_atten;
u16 radio_atten;
u16 txctl1;
u16 txctl2;
};
/* A PHY */
struct {
u16 txpwr_offset;
};
};
/* Current Interference Mitigation mode */ /* Current Interference Mitigation mode */
int interfmode; int interfmode;
/* Stack of saved values from the Interference Mitigation code */ /* Stack of saved values from the Interference Mitigation code */
......
...@@ -560,12 +560,9 @@ static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm) ...@@ -560,12 +560,9 @@ static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
radio->revision = revision; radio->revision = revision;
/* Set default attenuation values. */ /* Set default attenuation values. */
radio->txpower[0] = 2; radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
radio->txpower[1] = 2; radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
if (revision == 1) radio->txctl1 = bcm43xx_default_txctl1(bcm);
radio->txpower[2] = 3;
else
radio->txpower[2] = 0;
if (phy->type == BCM43xx_PHYTYPE_A) if (phy->type == BCM43xx_PHYTYPE_A)
radio->txpower_desired = bcm->sprom.maxpower_aphy; radio->txpower_desired = bcm->sprom.maxpower_aphy;
else else
......
...@@ -220,9 +220,9 @@ static void bcm43xx_phy_init_pctl(struct bcm43xx_private *bcm) ...@@ -220,9 +220,9 @@ static void bcm43xx_phy_init_pctl(struct bcm43xx_private *bcm)
bcm43xx_radio_write16(bcm, 0x0076, bcm43xx_radio_write16(bcm, 0x0076,
bcm43xx_radio_read16(bcm, 0x0076) | 0x0084); bcm43xx_radio_read16(bcm, 0x0076) | 0x0084);
} else { } else {
saved_batt = radio->txpower[0]; saved_batt = radio->baseband_atten;
saved_ratt = radio->txpower[1]; saved_ratt = radio->radio_atten;
saved_txctl1 = radio->txpower[2]; saved_txctl1 = radio->txctl1;
if ((radio->revision >= 6) && (radio->revision <= 8) if ((radio->revision >= 6) && (radio->revision <= 8)
&& /*FIXME: incomplete specs for 5 < revision < 9 */ 0) && /*FIXME: incomplete specs for 5 < revision < 9 */ 0)
bcm43xx_radio_set_txpower_bg(bcm, 0xB, 0x1F, 0); bcm43xx_radio_set_txpower_bg(bcm, 0xB, 0x1F, 0);
...@@ -1039,7 +1039,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm) ...@@ -1039,7 +1039,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
bcm43xx_radio_write16(bcm, 0x0078, radio->initval); bcm43xx_radio_write16(bcm, 0x0078, radio->initval);
bcm43xx_radio_write16(bcm, 0x0052, bcm43xx_radio_write16(bcm, 0x0052,
(bcm43xx_radio_read16(bcm, 0x0052) & 0xFFF0) (bcm43xx_radio_read16(bcm, 0x0052) & 0xFFF0)
| radio->txpower[3]); | radio->txctl2);
} }
if (phy->connected) { if (phy->connected) {
...@@ -1259,7 +1259,6 @@ struct bcm43xx_lopair * bcm43xx_find_lopair(struct bcm43xx_private *bcm, ...@@ -1259,7 +1259,6 @@ struct bcm43xx_lopair * bcm43xx_find_lopair(struct bcm43xx_private *bcm,
if (baseband_attenuation > 6) if (baseband_attenuation > 6)
baseband_attenuation = 6; baseband_attenuation = 6;
assert(radio_attenuation < 10); assert(radio_attenuation < 10);
assert(tx == 0 || tx == 3);
if (tx == 3) { if (tx == 3) {
return bcm43xx_get_lopair(phy, return bcm43xx_get_lopair(phy,
...@@ -1275,9 +1274,9 @@ struct bcm43xx_lopair * bcm43xx_current_lopair(struct bcm43xx_private *bcm) ...@@ -1275,9 +1274,9 @@ struct bcm43xx_lopair * bcm43xx_current_lopair(struct bcm43xx_private *bcm)
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
return bcm43xx_find_lopair(bcm, return bcm43xx_find_lopair(bcm,
radio->txpower[0], radio->baseband_atten,
radio->txpower[1], radio->radio_atten,
radio->txpower[2]); radio->txctl1);
} }
/* Adjust B/G LO */ /* Adjust B/G LO */
...@@ -1311,7 +1310,7 @@ static void bcm43xx_phy_lo_g_measure_txctl2(struct bcm43xx_private *bcm) ...@@ -1311,7 +1310,7 @@ static void bcm43xx_phy_lo_g_measure_txctl2(struct bcm43xx_private *bcm)
txctl2 = i; txctl2 = i;
} }
} }
radio->txpower[3] = txctl2; radio->txctl2 = txctl2;
} }
static static
...@@ -1530,8 +1529,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm) ...@@ -1530,8 +1529,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
r31 = 0; r31 = 0;
} }
bcm43xx_radio_write16(bcm, 0x43, i); bcm43xx_radio_write16(bcm, 0x43, i);
bcm43xx_radio_write16(bcm, 0x52, bcm43xx_radio_write16(bcm, 0x52, radio->txctl2);
radio->txpower[3]);
udelay(10); udelay(10);
bcm43xx_phy_set_baseband_attenuation(bcm, j * 2); bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
...@@ -1573,7 +1571,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm) ...@@ -1573,7 +1571,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
} }
bcm43xx_radio_write16(bcm, 0x43, i - 9); bcm43xx_radio_write16(bcm, 0x43, i - 9);
bcm43xx_radio_write16(bcm, 0x52, bcm43xx_radio_write16(bcm, 0x52,
radio->txpower[3] radio->txctl2
| (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above? | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above?
udelay(10); udelay(10);
...@@ -1780,9 +1778,9 @@ void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm) ...@@ -1780,9 +1778,9 @@ void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm)
} }
/* Calculate the new attenuation values. */ /* Calculate the new attenuation values. */
baseband_attenuation = radio->txpower[0]; baseband_attenuation = radio->baseband_atten;
baseband_attenuation += baseband_att_delta; baseband_attenuation += baseband_att_delta;
radio_attenuation = radio->txpower[1]; radio_attenuation = radio->radio_atten;
radio_attenuation += radio_att_delta; radio_attenuation += radio_att_delta;
/* Get baseband and radio attenuation values into their permitted ranges. /* Get baseband and radio attenuation values into their permitted ranges.
...@@ -1807,7 +1805,7 @@ void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm) ...@@ -1807,7 +1805,7 @@ void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm)
} }
baseband_attenuation = limit_value(baseband_attenuation, 0, 11); baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
txpower = radio->txpower[2]; txpower = radio->txctl1;
if ((radio->version == 0x2050) && (radio->revision == 2)) { if ((radio->version == 0x2050) && (radio->revision == 2)) {
if (radio_attenuation <= 1) { if (radio_attenuation <= 1) {
if (txpower == 0) { if (txpower == 0) {
...@@ -1829,7 +1827,7 @@ void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm) ...@@ -1829,7 +1827,7 @@ void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm)
} }
} }
} }
radio->txpower[2] = txpower; radio->txctl1 = txpower;
baseband_attenuation = limit_value(baseband_attenuation, 0, 11); baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
radio_attenuation = limit_value(radio_attenuation, 0, 9); radio_attenuation = limit_value(radio_attenuation, 0, 9);
......
...@@ -1652,7 +1652,7 @@ void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower) ...@@ -1652,7 +1652,7 @@ void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower)
bcm43xx_ilt_write(bcm, 0x3001, dac); bcm43xx_ilt_write(bcm, 0x3001, dac);
radio->txpower[0] = txpower; radio->txpwr_offset = txpower;
TODO(); TODO();
//TODO: FuncPlaceholder (Adjust BB loft cancel) //TODO: FuncPlaceholder (Adjust BB loft cancel)
...@@ -1666,17 +1666,14 @@ void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm, ...@@ -1666,17 +1666,14 @@ void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm,
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
if (baseband_attenuation == 0xFFFF) if (baseband_attenuation == 0xFFFF)
baseband_attenuation = radio->txpower[0]; baseband_attenuation = radio->baseband_atten;
else
radio->txpower[0] = baseband_attenuation;
if (radio_attenuation == 0xFFFF) if (radio_attenuation == 0xFFFF)
radio_attenuation = radio->txpower[1]; radio_attenuation = radio->radio_atten;
else
radio->txpower[1] = radio_attenuation;
if (txpower == 0xFFFF) if (txpower == 0xFFFF)
txpower = radio->txpower[2]; txpower = radio->txctl1;
else radio->baseband_atten = baseband_attenuation;
radio->txpower[2] = txpower; radio->radio_atten = radio_attenuation;
radio->txctl1 = txpower;
assert(/*baseband_attenuation >= 0 &&*/ baseband_attenuation <= 11); assert(/*baseband_attenuation >= 0 &&*/ baseband_attenuation <= 11);
if (radio->revision < 6) if (radio->revision < 6)
...@@ -1693,10 +1690,124 @@ void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm, ...@@ -1693,10 +1690,124 @@ void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm,
(bcm43xx_radio_read16(bcm, 0x0052) & ~0x0070) (bcm43xx_radio_read16(bcm, 0x0052) & ~0x0070)
| ((txpower << 4) & 0x0070)); | ((txpower << 4) & 0x0070));
} }
//FIXME: The spec is very weird and unclear here.
if (phy->type == BCM43xx_PHYTYPE_G) if (phy->type == BCM43xx_PHYTYPE_G)
bcm43xx_phy_lo_adjust(bcm, 0); bcm43xx_phy_lo_adjust(bcm, 0);
} }
u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm)
{
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
if (radio->version == 0x2050 && radio->revision < 6)
return 0;
return 2;
}
u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm)
{
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
u16 att = 0xFFFF;
if (phy->type == BCM43xx_PHYTYPE_A)
return 0x60;
switch (radio->version) {
case 0x2053:
switch (radio->revision) {
case 1:
att = 6;
break;
}
break;
case 0x2050:
switch (radio->revision) {
case 0:
att = 5;
break;
case 1:
if (phy->type == BCM43xx_PHYTYPE_G) {
if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
bcm->board_type == 0x421 &&
bcm->board_revision >= 30)
att = 3;
else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
bcm->board_type == 0x416)
att = 3;
else
att = 1;
} else {
if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
bcm->board_type == 0x421 &&
bcm->board_revision >= 30)
att = 7;
else
att = 6;
}
break;
case 2:
if (phy->type == BCM43xx_PHYTYPE_G) {
if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
bcm->board_type == 0x421 &&
bcm->board_revision >= 30)
att = 3;
else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
bcm->board_type == 0x416)
att = 5;
else if (bcm->chip_id == 0x4320)
att = 4;
else
att = 3;
} else
att = 6;
break;
case 3:
att = 5;
break;
case 4:
case 5:
att = 1;
break;
case 6:
case 7:
att = 5;
break;
case 8:
att = 0x1A;
break;
case 9:
default:
att = 5;
}
}
if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
bcm->board_type == 0x421) {
if (bcm->board_revision < 0x43)
att = 2;
else if (bcm->board_revision < 0x51)
att = 3;
}
if (att == 0xFFFF)
att = 5;
return att;
}
u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm)
{
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
if (radio->version != 0x2050)
return 0;
if (radio->revision == 1)
return 3;
if (radio->revision < 6)
return 2;
if (radio->revision == 8)
return 1;
return 0;
}
void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm) void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm)
{ {
......
...@@ -72,6 +72,11 @@ void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower); ...@@ -72,6 +72,11 @@ void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower);
void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm, void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm,
u16 baseband_attenuation, u16 attenuation, u16 baseband_attenuation, u16 attenuation,
u16 txpower); u16 txpower);
u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm);
u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm);
u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm);
void bcm43xx_radio_set_txantenna(struct bcm43xx_private *bcm, u32 val); void bcm43xx_radio_set_txantenna(struct bcm43xx_private *bcm, u32 val);
void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm); void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment