2007-12-19 06:17:16

by Michael Wu

[permalink] [raw]
Subject: [PATCH 1/6] rtl8180: Initialize RF 3-wire registers before trying to identify RF version

From: Andrea Merello <[email protected]>

The RF version can be identified by writing and reading some RF chip
registers.
However 3-wire registers are initialized in the RF initialization
function, that is different for radio V1 and V2.
This caused write to RF chip with unitialized 3-wire bus, causing
sometimes malfunctions in following RF initialization code.
This patch add 3-wire bus registers initialization in the RF
identification function.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/rtl8180_rtl8225.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/rtl8180_rtl8225.c b/drivers/net/wireless/rtl8180_rtl8225.c
index 3bcdb9e..1c4fd33 100644
--- a/drivers/net/wireless/rtl8180_rtl8225.c
+++ b/drivers/net/wireless/rtl8180_rtl8225.c
@@ -305,10 +305,16 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)

int rtl8225_is_z2(struct ieee80211_hw *dev)
{
+ struct rtl8180_priv *priv = dev->priv;
int z2 = 0;

+ rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
+ rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
+ rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+ rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+ msleep(100);
+
rtl8225_write(dev, 0, 0x1B7);
- rtl8225_read(dev, 0);

if (rtl8225_read(dev, 8) == 0x588 && rtl8225_read(dev, 9) == 0x700)
z2 = 1;




2007-12-19 06:17:16

by Michael Wu

[permalink] [raw]
Subject: [PATCH 2/6] rtl8180: Power off VCO when stopping interface

From: Andrea Merello <[email protected]>

This should save power and reduce heat when the NIC is not used and the
interface is stopped.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/rtl8180_dev.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index cb884bd..91c1d9b 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -602,6 +602,11 @@ static void rtl8180_stop(struct ieee80211_hw *dev)

priv->rf_stop(dev);

+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+ reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
free_irq(priv->pdev->irq, dev);

rtl8180_free_rx_ring(dev);



2007-12-19 06:17:16

by Michael Wu

[permalink] [raw]
Subject: [PATCH 6/6] rtl8180: don't corrupt BRSR register on rtl8180 cards

From: Andrea Merello <[email protected]>

BRSR register is set to the (different) right value for both rtl8180 and
rtl8185. However rtl8225 rf init corrupts that register and we incorrectly
write it again after radio init with rtl8185 value.
As rf init for rtl8180's radios does not corrupt BRSR, we fix the problem by
simply avoiding the write for rtl8180 cards.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/rtl8180_dev.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index 3ab4922..c36c420 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -375,7 +375,8 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
}

priv->rf_init(dev);
- rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
+ if (priv->r8185)
+ rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
return 0;
}




2007-12-19 06:17:16

by Michael Wu

[permalink] [raw]
Subject: [PATCH 5/6] rtl8180: reduce lock during TX

From: Andrea Merello <[email protected]>

There is no need to hold lock during rts duration and plcp length calculation.
Also fix missing endianness conversion for plcp length.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/rtl8180_dev.c | 24 ++++++++++++++----------
1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index 058f30f..3ab4922 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -210,6 +210,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
unsigned int idx, prio;
dma_addr_t mapping;
u32 tx_flags;
+ u16 plcp_len = 0;
+ __le16 rts_duration = 0;

prio = control->queue;
ring = &priv->tx_ring[prio];
@@ -233,24 +235,26 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
*((struct ieee80211_tx_control **) skb->cb) =
kmemdup(control, sizeof(*control), GFP_ATOMIC);

- spin_lock_irqsave(&priv->lock, flags);
- idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
- entry = &ring->desc[idx];
-
if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
- entry->rts_duration =
- ieee80211_rts_duration(dev, priv->if_id, skb->len, control);
+ rts_duration = ieee80211_rts_duration(dev, priv->if_id, skb->len, control);

if (!priv->r8185) {
unsigned int remainder;

- entry->plcp_len =
- DIV_ROUND_UP(16 * (skb->len + 4), (control->rate->rate * 2) / 10);
- remainder = (16 * (skb->len + 4)) % ((control->rate->rate * 2) / 10);
+ plcp_len = DIV_ROUND_UP(16 * (skb->len + 4),
+ (control->rate->rate * 2) / 10);
+ remainder = (16 * (skb->len + 4)) %
+ ((control->rate->rate * 2) / 10);
if (remainder > 0 && remainder <= 6)
- entry->plcp_len |= 1 << 15;
+ plcp_len |= 1 << 15;
}

+ spin_lock_irqsave(&priv->lock, flags);
+ idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
+ entry = &ring->desc[idx];
+
+ entry->rts_duration = rts_duration;
+ entry->plcp_len = cpu_to_le16(plcp_len);
entry->tx_buf = cpu_to_le32(mapping);
entry->frame_len = cpu_to_le32(skb->len);
entry->flags2 = control->alt_retry_rate != -1 ?



2007-12-19 06:17:16

by Michael Wu

[permalink] [raw]
Subject: [PATCH 4/6] rtl8180: update BB registers for rtl8225 V1 radio

From: Andrea Merello <[email protected]>

This should give performance improvement in OFDM when signal is poor.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/rtl8180_rtl8225.c | 28 ++++++++++------------------
1 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/rtl8180_rtl8225.c b/drivers/net/wireless/rtl8180_rtl8225.c
index 1c4fd33..30c7e5d 100644
--- a/drivers/net/wireless/rtl8180_rtl8225.c
+++ b/drivers/net/wireless/rtl8180_rtl8225.c
@@ -288,10 +288,6 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);

- rtl8225_write_phy_ofdm(dev, 2, 0x42);
- rtl8225_write_phy_ofdm(dev, 6, 0x00);
- rtl8225_write_phy_ofdm(dev, 8, 0x00);
-
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1);

@@ -395,9 +391,9 @@ void rtl8225_rf_init(struct ieee80211_hw *dev)
rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
- rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
+ rtl8225_write_phy_ofdm(dev, 0x06, 0x00); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
- rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
+ rtl8225_write_phy_ofdm(dev, 0x08, 0x00); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
@@ -405,7 +401,7 @@ void rtl8225_rf_init(struct ieee80211_hw *dev)
rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
- rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1);
+ rtl8225_write_phy_ofdm(dev, 0x11, 0x03); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
@@ -427,11 +423,6 @@ void rtl8225_rf_init(struct ieee80211_hw *dev)
rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);

- rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[1 * 4]);
- rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[1 * 4 + 2]);
- rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[1 * 4 + 3]);
- rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[1 * 4 + 1]);
-
rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
@@ -473,13 +464,14 @@ void rtl8225_rf_init(struct ieee80211_hw *dev)
rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002);
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);

- /* set sensitivity */
rtl8225_write(dev, 0x0c, 0x50);
- rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[1 * 4]);
- rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[1 * 4 + 2]);
- rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[1 * 4 + 3]);
- rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[1 * 4 + 1]);
- rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]);
+ /* set OFDM initial gain */
+ rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]);
+ rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]);
+ rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]);
+ rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]);
+ /* set CCK threshold */
+ rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]);
}

static const u8 rtl8225z2_tx_power_cck_ch14[] = {



2007-12-19 06:17:16

by Michael Wu

[permalink] [raw]
Subject: [PATCH 3/6] rtl8180: Set CRC failed flag

From: Andrea Merello <[email protected]>

Frames that fail CRC need RX_FLAG_FAILED_FCS_CRC set.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/rtl8180_dev.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index 91c1d9b..058f30f 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -104,6 +104,9 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
rx_status.phymode = dev->conf.phymode;
rx_status.mactime = le64_to_cpu(entry->tsft);
rx_status.flag |= RX_FLAG_TSFT;
+ if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR)
+ rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
+
ieee80211_rx_irqsafe(dev, skb, &rx_status);

skb = new_skb;