2007-12-02 22:11:13

by Michael Wu

[permalink] [raw]
Subject: [PATCH 1/8] rtl8187: fix tx power reading

From: Andrea Merello <[email protected]>

CCK and OFDM power levels are stored in adjacent bytes, not nibbles.

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

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

diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c
index efc4120..eade81f 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl8187_rtl8225.c
@@ -283,8 +283,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
u32 reg;
int i;

- cck_power = priv->channels[channel - 1].val & 0xF;
- ofdm_power = priv->channels[channel - 1].val >> 4;
+ cck_power = priv->channels[channel - 1].val & 0xFF;
+ ofdm_power = priv->channels[channel - 1].val >> 8;

cck_power = min(cck_power, (u8)11);
ofdm_power = min(ofdm_power, (u8)35);
@@ -500,8 +500,8 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
u32 reg;
int i;

- cck_power = priv->channels[channel - 1].val & 0xF;
- ofdm_power = priv->channels[channel - 1].val >> 4;
+ cck_power = priv->channels[channel - 1].val & 0xFF;
+ ofdm_power = priv->channels[channel - 1].val >> 8;

cck_power = min(cck_power, (u8)15);
cck_power += priv->txpwr_base & 0xF;




2007-12-02 22:11:15

by Michael Wu

[permalink] [raw]
Subject: [PATCH 6/8] rtl8180: Add support for sa2400 radio

From: Andrea Merello <[email protected]>

This adds support for rtl8180+sa2400.

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

drivers/net/wireless/Makefile | 2
drivers/net/wireless/rtl8180_dev.c | 11 ++
drivers/net/wireless/rtl8180_sa2400.c | 193 +++++++++++++++++++++++++++++++++
drivers/net/wireless/rtl8180_sa2400.h | 38 ++++++
4 files changed, 243 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 65a5b7f..e295d1e 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -50,7 +50,7 @@ obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
obj-$(CONFIG_USB_ZD1201) += zd1201.o
obj-$(CONFIG_LIBERTAS) += libertas/

-rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o
+rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o
rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o

obj-$(CONFIG_RTL8180) += rtl8180.o
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index 7508eee..e1ea198 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -24,6 +24,7 @@

#include "rtl8180.h"
#include "rtl8180_rtl8225.h"
+#include "rtl8180_sa2400.h"

MODULE_AUTHOR("Michael Wu <[email protected]>");
MODULE_AUTHOR("Andrea Merello <[email protected]>");
@@ -31,7 +32,14 @@ MODULE_DESCRIPTION("RTL8180 / RTL8185 PCI wireless driver");
MODULE_LICENSE("GPL");

static struct pci_device_id rtl8180_table[] __devinitdata = {
+ /* rtl8185 */
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) },
+
+ /* rtl8180 */
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8180) },
+ { PCI_DEVICE(0x1799, 0x6001) },
+ { PCI_DEVICE(0x1799, 0x6020) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) },
{ }
};

@@ -882,6 +890,9 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
break;
case 3:
rf_name = "Philips";
+ priv->rf_init = sa2400_rf_init;
+ priv->rf_stop = sa2400_rf_stop;
+ priv->rf_set_chan = sa2400_rf_set_channel;
break;
case 4:
rf_name = "Maxim";
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c
new file mode 100644
index 0000000..dea7e5a
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_sa2400.c
@@ -0,0 +1,193 @@
+
+/*
+ * Radio tuning for Philips SA2400 on RTL8180
+ *
+ * Copyright 2007 Andrea Merello <[email protected]>
+ *
+ * Code from the BSD driver and the rtl8181 project have been
+ * very useful to understand certain things
+ *
+ * I want to thanks the Authors of such projects and the Ndiswrapper
+ * project Authors.
+ *
+ * A special Big Thanks also is for all people who donated me cards,
+ * making possible the creation of the original rtl8180 driver
+ * from which this code is derived!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <net/mac80211.h>
+
+#include "rtl8180.h"
+#include "rtl8180_sa2400.h"
+
+static const u32 sa2400_chan[] = {
+ 0x00096c, /* ch1 */
+ 0x080970,
+ 0x100974,
+ 0x180978,
+ 0x000980,
+ 0x080984,
+ 0x100988,
+ 0x18098c,
+ 0x000994,
+ 0x080998,
+ 0x10099c,
+ 0x1809a0,
+ 0x0009a8,
+ 0x0009b4, /* ch 14 */
+};
+
+static void write_sa2400(struct ieee80211_hw *dev, u8 addr, u32 data)
+{
+ struct rtl8180_priv *priv = dev->priv;
+ u32 phy_config;
+
+ /* MAC will bang bits to the sa2400. sw 3-wire is NOT used */
+ phy_config = 0xb0000000;
+
+ phy_config |= ((u32)(addr & 0xf)) << 24;
+ phy_config |= data & 0xffffff;
+
+ rtl818x_iowrite32(priv,
+ (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
+
+ msleep(3);
+}
+
+static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan)
+{
+ struct rtl8180_priv *priv = dev->priv;
+ u8 ant = SA2400_ANTENNA;
+
+ if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
+ ant |= BB_ANTENNA_B;
+
+ if (chan == 14)
+ ant |= BB_ANTATTEN_CHAN14;
+
+ rtl8180_write_phy(dev, 0x10, ant);
+
+}
+
+void sa2400_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+{
+ struct rtl8180_priv *priv = dev->priv;
+ u32 txpw = priv->channels[conf->channel - 1].val & 0xFF;
+ u32 chan = sa2400_chan[conf->channel - 1];
+
+ write_sa2400(dev, 7, txpw);
+
+ sa2400_write_phy_antenna(dev, chan);
+
+ write_sa2400(dev, 0, chan);
+ write_sa2400(dev, 1, 0xbb50);
+ write_sa2400(dev, 2, 0x80);
+ write_sa2400(dev, 3, 0);
+}
+
+void sa2400_rf_stop(struct ieee80211_hw *dev)
+{
+ write_sa2400(dev, 4, 0);
+}
+
+void sa2400_rf_init(struct ieee80211_hw *dev)
+{
+ struct rtl8180_priv *priv = dev->priv;
+ u32 anaparam, txconf;
+ u8 firdac;
+ int analogphy = priv->rfparam & RF_PARAM_ANALOGPHY;
+
+ anaparam = priv->anaparam;
+ anaparam &= ~(1 << ANAPARAM_TXDACOFF_SHIFT);
+ anaparam &= ~ANAPARAM_PWR1_MASK;
+ anaparam &= ~ANAPARAM_PWR0_MASK;
+
+ if (analogphy) {
+ anaparam |= SA2400_ANA_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT;
+ firdac = 0;
+ } else {
+ anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT);
+ anaparam |= (SA2400_ANAPARAM_PWR0_ON << ANAPARAM_PWR0_SHIFT);
+ firdac = 1 << SA2400_REG4_FIRDAC_SHIFT;
+ }
+
+ rtl8180_set_anaparam(priv, anaparam);
+
+ write_sa2400(dev, 0, sa2400_chan[0]);
+ write_sa2400(dev, 1, 0xbb50);
+ write_sa2400(dev, 2, 0x80);
+ write_sa2400(dev, 3, 0);
+ write_sa2400(dev, 4, 0x19340 | firdac);
+ write_sa2400(dev, 5, 0x1dfb | (SA2400_MAX_SENS - 54) << 15);
+ write_sa2400(dev, 4, 0x19348 | firdac); /* calibrate VCO */
+
+ if (!analogphy)
+ write_sa2400(dev, 4, 0x1938c); /*???*/
+
+ write_sa2400(dev, 4, 0x19340 | firdac);
+
+ write_sa2400(dev, 0, sa2400_chan[0]);
+ write_sa2400(dev, 1, 0xbb50);
+ write_sa2400(dev, 2, 0x80);
+ write_sa2400(dev, 3, 0);
+ write_sa2400(dev, 4, 0x19344 | firdac); /* calibrate filter */
+
+ /* new from rtl8180 embedded driver (rtl8181 project) */
+ write_sa2400(dev, 6, 0x13ff | (1 << 23)); /* MANRX */
+ write_sa2400(dev, 8, 0); /* VCO */
+
+ if (analogphy) {
+ rtl8180_set_anaparam(priv, anaparam |
+ (1 << ANAPARAM_TXDACOFF_SHIFT));
+
+ txconf = rtl818x_ioread32(priv, &priv->map->TX_CONF);
+ rtl818x_iowrite32(priv, &priv->map->TX_CONF,
+ txconf | RTL818X_TX_CONF_LOOPBACK_CONT);
+
+ write_sa2400(dev, 4, 0x19341); /* calibrates DC */
+
+ /* a 5us sleep is required here,
+ * we rely on the 3ms delay introduced in write_sa2400 */
+ write_sa2400(dev, 4, 0x19345);
+
+ /* a 20us sleep is required here,
+ * we rely on the 3ms delay introduced in write_sa2400 */
+
+ rtl818x_iowrite32(priv, &priv->map->TX_CONF, txconf);
+
+ rtl8180_set_anaparam(priv, anaparam);
+ }
+ /* end new code */
+
+ write_sa2400(dev, 4, 0x19341 | firdac); /* RTX MODE */
+
+ /* baseband configuration */
+ rtl8180_write_phy(dev, 0, 0x98);
+ rtl8180_write_phy(dev, 3, 0x38);
+ rtl8180_write_phy(dev, 4, 0xe0);
+ rtl8180_write_phy(dev, 5, 0x90);
+ rtl8180_write_phy(dev, 6, 0x1a);
+ rtl8180_write_phy(dev, 7, 0x64);
+
+ sa2400_write_phy_antenna(dev, 1);
+
+ rtl8180_write_phy(dev, 0x11, 0x80);
+
+ if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
+ RTL818X_CONFIG2_ANTENNA_DIV)
+ rtl8180_write_phy(dev, 0x12, 0xc7); /* enable ant diversity */
+ else
+ rtl8180_write_phy(dev, 0x12, 0x47); /* disable ant diversity */
+
+ rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
+
+ rtl8180_write_phy(dev, 0x19, 0x0);
+ rtl8180_write_phy(dev, 0x1a, 0xa0);
+}
diff --git a/drivers/net/wireless/rtl8180_sa2400.h b/drivers/net/wireless/rtl8180_sa2400.h
new file mode 100644
index 0000000..018bb92
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_sa2400.h
@@ -0,0 +1,38 @@
+#ifndef RTL8180_SA2400_H
+#define RTL8180_SA2400_H
+
+/*
+ * Radio tuning for Philips SA2400 on RTL8180
+ *
+ * Copyright 2007 Andrea Merello <[email protected]>
+ *
+ * Code from the BSD driver and the rtl8181 project have been
+ * very useful to understand certain things
+ *
+ * I want to thanks the Authors of such projects and the Ndiswrapper
+ * project Authors.
+ *
+ * A special Big Thanks also is for all people who donated me cards,
+ * making possible the creation of the original rtl8180 driver
+ * from which this code is derived!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define SA2400_ANTENNA 0x91
+#define SA2400_DIG_ANAPARAM_PWR1_ON 0x8
+#define SA2400_ANA_ANAPARAM_PWR1_ON 0x28
+#define SA2400_ANAPARAM_PWR0_ON 0x3
+
+/* RX sensitivity in dbm */
+#define SA2400_MAX_SENS 85
+
+#define SA2400_REG4_FIRDAC_SHIFT 7
+
+void sa2400_rf_init(struct ieee80211_hw *);
+void sa2400_rf_stop(struct ieee80211_hw *);
+void sa2400_rf_set_channel(struct ieee80211_hw *, struct ieee80211_conf *);
+
+#endif /* RTL8180_SA2400_H */



2007-12-02 22:11:14

by Michael Wu

[permalink] [raw]
Subject: [PATCH 7/8] rtl8180: Add support for max2820 radio

From: Andrea Merello <[email protected]>

This adds support for rtl8180+max2820.

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

drivers/net/wireless/Makefile | 2
drivers/net/wireless/rtl8180_dev.c | 4 +
drivers/net/wireless/rtl8180_max2820.c | 142 ++++++++++++++++++++++++++++++++
drivers/net/wireless/rtl8180_max2820.h | 30 +++++++
4 files changed, 177 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index e295d1e..75f8262 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -50,7 +50,7 @@ obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
obj-$(CONFIG_USB_ZD1201) += zd1201.o
obj-$(CONFIG_LIBERTAS) += libertas/

-rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o
+rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o
rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o

obj-$(CONFIG_RTL8180) += rtl8180.o
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index e1ea198..db70604 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -25,6 +25,7 @@
#include "rtl8180.h"
#include "rtl8180_rtl8225.h"
#include "rtl8180_sa2400.h"
+#include "rtl8180_max2820.h"

MODULE_AUTHOR("Michael Wu <[email protected]>");
MODULE_AUTHOR("Andrea Merello <[email protected]>");
@@ -896,6 +897,9 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
break;
case 4:
rf_name = "Maxim";
+ priv->rf_init = max2820_rf_init;
+ priv->rf_stop = max2820_rf_stop;
+ priv->rf_set_chan = max2820_rf_set_channel;
break;
case 5:
rf_name = "GCT";
diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl8180_max2820.c
new file mode 100644
index 0000000..c3e125f
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_max2820.c
@@ -0,0 +1,142 @@
+/*
+ * Radio tuning for Maxim max2820 on RTL8180
+ *
+ * Copyright 2007 Andrea Merello <[email protected]>
+ *
+ * Code from the BSD driver and the rtl8181 project have been
+ * very useful to understand certain things
+ *
+ * I want to thanks the Authors of such projects and the Ndiswrapper
+ * project Authors.
+ *
+ * A special Big Thanks also is for all people who donated me cards,
+ * making possible the creation of the original rtl8180 driver
+ * from which this code is derived!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <net/mac80211.h>
+
+#include "rtl8180.h"
+#include "rtl8180_max2820.h"
+
+u32 max2820_chan[] = {
+ 12, /* CH 1 */
+ 17,
+ 22,
+ 27,
+ 32,
+ 37,
+ 42,
+ 47,
+ 52,
+ 57,
+ 62,
+ 67,
+ 72,
+ 84, /* CH 14 */
+};
+
+static void write_max2820(struct ieee80211_hw *dev, u8 addr, u32 data)
+{
+ struct rtl8180_priv *priv = dev->priv;
+ u32 phy_config;
+
+ phy_config = 0x90 + (data & 0xf);
+ phy_config <<= 16;
+ phy_config += addr;
+ phy_config <<= 8;
+ phy_config += (data >> 4) & 0xff;
+
+ rtl818x_iowrite32(priv,
+ (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
+
+ msleep(1);
+}
+
+static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan)
+{
+ struct rtl8180_priv *priv = dev->priv;
+ u8 ant;
+
+ ant = MAXIM_ANTENNA;
+ if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
+ ant |= BB_ANTENNA_B;
+ if (chan == 14)
+ ant |= BB_ANTATTEN_CHAN14;
+
+ rtl8180_write_phy(dev, 0x10, ant);
+}
+
+void max2820_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+{
+ struct rtl8180_priv *priv = dev->priv;
+ unsigned int chan_idx = conf ? conf->channel - 1 : 0;
+ u32 txpw = priv->channels[chan_idx].val & 0xFF;
+ u32 chan = max2820_chan[chan_idx];
+
+ /* While philips SA2400 drive the PA bias from
+ * sa2400, for MAXIM we do this directly from BB */
+ rtl8180_write_phy(dev, 3, txpw);
+
+ max2820_write_phy_antenna(dev, chan);
+ write_max2820(dev, 3, chan);
+}
+
+void max2820_rf_stop(struct ieee80211_hw *dev)
+{
+ rtl8180_write_phy(dev, 3, 0x8);
+ write_max2820(dev, 1, 0);
+}
+
+
+void max2820_rf_init(struct ieee80211_hw *dev)
+{
+ struct rtl8180_priv *priv = dev->priv;
+
+ /* MAXIM from netbsd driver */
+ write_max2820(dev, 0, 0x007); /* test mode as indicated in datasheet */
+ write_max2820(dev, 1, 0x01e); /* enable register */
+ write_max2820(dev, 2, 0x001); /* synt register */
+
+ max2820_rf_set_channel(dev, NULL);
+
+ write_max2820(dev, 4, 0x313); /* rx register */
+
+ /* PA is driven directly by the BB, we keep the MAXIM bias
+ * at the highest value in case that setting it to lower
+ * values may introduce some further attenuation somewhere..
+ */
+ write_max2820(dev, 5, 0x00f);
+
+ /* baseband configuration */
+ rtl8180_write_phy(dev, 0, 0x88); /* sys1 */
+ rtl8180_write_phy(dev, 3, 0x08); /* txagc */
+ rtl8180_write_phy(dev, 4, 0xf8); /* lnadet */
+ rtl8180_write_phy(dev, 5, 0x90); /* ifagcinit */
+ rtl8180_write_phy(dev, 6, 0x1a); /* ifagclimit */
+ rtl8180_write_phy(dev, 7, 0x64); /* ifagcdet */
+
+ max2820_write_phy_antenna(dev, 1);
+
+ rtl8180_write_phy(dev, 0x11, 0x88); /* trl */
+
+ if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
+ RTL818X_CONFIG2_ANTENNA_DIV)
+ rtl8180_write_phy(dev, 0x12, 0xc7);
+ else
+ rtl8180_write_phy(dev, 0x12, 0x47);
+
+ rtl8180_write_phy(dev, 0x13, 0x9b);
+
+ rtl8180_write_phy(dev, 0x19, 0x0); /* CHESTLIM */
+ rtl8180_write_phy(dev, 0x1a, 0x9f); /* CHSQLIM */
+
+ max2820_rf_set_channel(dev, NULL);
+}
diff --git a/drivers/net/wireless/rtl8180_max2820.h b/drivers/net/wireless/rtl8180_max2820.h
new file mode 100644
index 0000000..8e27292
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_max2820.h
@@ -0,0 +1,30 @@
+#ifndef RTL8180_MAX2820_H
+#define RTL8180_MAX2820_H
+
+/*
+ * Radio tuning for Maxim max2820 on RTL8180
+ *
+ * Copyright 2007 Andrea Merello <[email protected]>
+ *
+ * Code from the BSD driver and the rtl8181 project have been
+ * very useful to understand certain things
+ *
+ * I want to thanks the Authors of such projects and the Ndiswrapper
+ * project Authors.
+ *
+ * A special Big Thanks also is for all people who donated me cards,
+ * making possible the creation of the original rtl8180 driver
+ * from which this code is derived!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define MAXIM_ANTENNA 0xb3
+
+void max2820_rf_init(struct ieee80211_hw *);
+void max2820_rf_stop(struct ieee80211_hw *);
+void max2820_rf_set_channel(struct ieee80211_hw *, struct ieee80211_conf *);
+
+#endif /* RTL8180_MAX2820_H */



2007-12-02 22:11:14

by Michael Wu

[permalink] [raw]
Subject: [PATCH 4/8] rtl8180: Add rtl8180_set_anaparam

From: Andrea Merello <[email protected]>

This piece of code is used everywhere, so pull it into a function.

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

drivers/net/wireless/rtl8180.h | 1 +
drivers/net/wireless/rtl8180_dev.c | 26 ++++++++++++++++----------
drivers/net/wireless/rtl8180_rtl8225.c | 16 ++--------------
3 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/rtl8180.h b/drivers/net/wireless/rtl8180.h
index 4a5b44b..28431ac 100644
--- a/drivers/net/wireless/rtl8180.h
+++ b/drivers/net/wireless/rtl8180.h
@@ -101,6 +101,7 @@ struct rtl8180_priv {
};

void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
+void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam);

static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr)
{
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index a2a6791..54f9c31 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -243,6 +243,20 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
return 0;
}

+void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam)
+{
+ u8 reg;
+
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+ reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3,
+ reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3,
+ reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+}
+
static int rtl8180_init_hw(struct ieee80211_hw *dev)
{
struct rtl8180_priv *priv = dev->priv;
@@ -285,16 +299,8 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)

rtl818x_iowrite8(priv, &priv->map->MSR, 0);

- if (!priv->r8185) {
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3,
- reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM, priv->anaparam);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3,
- reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
- }
+ if (!priv->r8185)
+ rtl8180_set_anaparam(priv, priv->anaparam);

rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma);
rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma);
diff --git a/drivers/net/wireless/rtl8180_rtl8225.c b/drivers/net/wireless/rtl8180_rtl8225.c
index 6fb0659..3bcdb9e 100644
--- a/drivers/net/wireless/rtl8180_rtl8225.c
+++ b/drivers/net/wireless/rtl8180_rtl8225.c
@@ -322,14 +322,8 @@ void rtl8225_rf_init(struct ieee80211_hw *dev)
{
struct rtl8180_priv *priv = dev->priv;
int i;
- u8 reg;

- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+ rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);

/* host_pci_init */
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
@@ -561,14 +555,8 @@ void rtl8225z2_rf_init(struct ieee80211_hw *dev)
{
struct rtl8180_priv *priv = dev->priv;
int i;
- u8 reg;

- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+ rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);

/* host_pci_init */
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);



2007-12-02 22:11:13

by Michael Wu

[permalink] [raw]
Subject: [PATCH 2/8] rtl8180: fix tx power reading

From: Andrea Merello <[email protected]>

CCK and OFDM power levels are stored in adjacent bytes, not nibbles.

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

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

diff --git a/drivers/net/wireless/rtl8180_rtl8225.c b/drivers/net/wireless/rtl8180_rtl8225.c
index 96b9b7f..6fb0659 100644
--- a/drivers/net/wireless/rtl8180_rtl8225.c
+++ b/drivers/net/wireless/rtl8180_rtl8225.c
@@ -261,8 +261,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
u32 reg;
int i;

- cck_power = priv->channels[channel - 1].val & 0xF;
- ofdm_power = priv->channels[channel - 1].val >> 4;
+ cck_power = priv->channels[channel - 1].val & 0xFF;
+ ofdm_power = priv->channels[channel - 1].val >> 8;

cck_power = min(cck_power, (u8)35);
ofdm_power = min(ofdm_power, (u8)35);
@@ -505,8 +505,8 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
const u8 *tmp;
int i;

- cck_power = priv->channels[channel - 1].val & 0xF;
- ofdm_power = priv->channels[channel - 1].val >> 4;
+ cck_power = priv->channels[channel - 1].val & 0xFF;
+ ofdm_power = priv->channels[channel - 1].val >> 8;

if (channel == 14)
tmp = rtl8225z2_tx_power_cck_ch14;



2007-12-02 22:11:15

by Michael Wu

[permalink] [raw]
Subject: [PATCH 8/8] rtl8187: Add USB ID for Sitecom WL-168 v1 001

From: Matthias Mueller <[email protected]>

Thanks to Matthias Mueller for reporting this device.

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

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

diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 859235f..db2e0e0 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -38,6 +38,8 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
{USB_DEVICE(0x0846, 0x6a00)},
/* HP */
{USB_DEVICE(0x03f0, 0xca02)},
+ /* Sitecom */
+ {USB_DEVICE(0x0df6, 0x000d)},
{}
};




2007-12-26 00:56:12

by Michael Wu

[permalink] [raw]
Subject: Re: [PATCH 1/8] rtl8187: fix tx power reading

On Sunday 02 December 2007 17:17:51 Michael Wu wrote:
> CCK and OFDM power levels are stored in adjacent bytes, not nibbles.
>
This turns out to be true only for rtl8180. On rtl8187, power levels are
indeed stored in nibbles, so this patch is wrong. Please revert this patch.

Thanks,
-Michael Wu


Attachments:
(No filename) (298.00 B)
signature.asc (194.00 B)
This is a digitally signed message part.
Download all attachments

2007-12-02 22:11:14

by Michael Wu

[permalink] [raw]
Subject: [PATCH 5/8] rtl8180: Add full support for rtl8180

From: Andrea Merello <[email protected]>

This patch makes the driver fully support the rtl8180 mac. However, no
radio tuning is added so this won't work without patches adding support
for specific radios.

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

drivers/net/wireless/rtl8180.h | 16 +++++++++++++++-
drivers/net/wireless/rtl8180_dev.c | 26 ++++++++++++++++++++------
2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/rtl8180.h b/drivers/net/wireless/rtl8180.h
index 28431ac..8051054 100644
--- a/drivers/net/wireless/rtl8180.h
+++ b/drivers/net/wireless/rtl8180.h
@@ -5,11 +5,25 @@

#define MAX_RX_SIZE IEEE80211_MAX_RTS_THRESHOLD

-#define RF_PARAM_DIGPHY (1 << 0)
+#define RF_PARAM_ANALOGPHY (1 << 0)
#define RF_PARAM_ANTBDEFAULT (1 << 1)
#define RF_PARAM_CARRIERSENSE1 (1 << 2)
#define RF_PARAM_CARRIERSENSE2 (1 << 3)

+#define BB_ANTATTEN_CHAN14 0x0C
+#define BB_ANTENNA_B 0x40
+
+#define BB_HOST_BANG (1 << 30)
+#define BB_HOST_BANG_EN (1 << 2)
+#define BB_HOST_BANG_CLK (1 << 1)
+#define BB_HOST_BANG_DATA 1
+
+#define ANAPARAM_TXDACOFF_SHIFT 27
+#define ANAPARAM_PWR0_SHIFT 28
+#define ANAPARAM_PWR0_MASK (0x07 << ANAPARAM_PWR0_SHIFT)
+#define ANAPARAM_PWR1_SHIFT 20
+#define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT)
+
enum rtl8180_tx_desc_flags {
RTL8180_TX_DESC_FLAG_NO_ENC = (1 << 15),
RTL8180_TX_DESC_FLAG_TX_OK = (1 << 15),
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index 54f9c31..7508eee 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -223,10 +223,21 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
spin_lock_irqsave(&priv->lock, flags);
idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
entry = &ring->desc[idx];
- /* TODO: calculate PLCP length - needed for rtl8180 */
+
if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
entry->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);
+ if (remainder > 0 && remainder <= 6)
+ entry->plcp_len |= 1 << 15;
+ }
+
entry->tx_buf = cpu_to_le32(mapping);
entry->frame_len = cpu_to_le32(skb->len);
entry->flags2 = control->alt_retry_rate != -1 ?
@@ -328,12 +339,9 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
- }

- /* TODO: fix for rtl8180 */
- rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
+ rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);

- if (priv->r8185) {
/* TODO: set ClkRun enable? necessary? */
reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE);
rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6));
@@ -341,6 +349,12 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2));
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+ } else {
+ rtl818x_iowrite16(priv, &priv->map->BRSR, 0x1);
+ rtl818x_iowrite8(priv, &priv->map->SECURITY, 0);
+
+ rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6);
+ rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C);
}

priv->rf_init(dev);
@@ -901,13 +915,13 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
goto err_iounmap;
}

- eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam);
eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val);
priv->csthreshold = eeprom_val >> 8;
if (!priv->r8185) {
__le32 anaparam;
eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2);
priv->anaparam = le32_to_cpu(anaparam);
+ eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam);
}

eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)dev->wiphy->perm_addr, 3);



2007-12-02 22:11:13

by Michael Wu

[permalink] [raw]
Subject: [PATCH 3/8] rtl818x: update register struct

From: Andrea Merello <[email protected]>

Add the SECURITY and CARRIER_SENSE_COUNTER registers.
Change PGSELECT length from 16 to 8 bits.

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

drivers/net/wireless/rtl8187_dev.c | 12 ++++++------
drivers/net/wireless/rtl818x.h | 6 ++++--
2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index e454ae8..859235f 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -393,12 +393,12 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
priv->rf_init(dev);

rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
- reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & 0xfffe;
- rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 0x1);
+ reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1;
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10);
rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80);
rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60);
- rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);

return 0;
}
@@ -750,13 +750,13 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE,
&priv->txpwr_base);

- reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & ~1;
- rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 1);
+ reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1;
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
/* 0 means asic B-cut, we should use SW 3 wire
* bit-by-bit banging for radio. 1 means we can use
* USB specific request to write radio registers */
priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3;
- rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);

rtl8225_write(dev, 0, 0x1B7);
diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x.h
index 99b8b1b..1322f6a 100644
--- a/drivers/net/wireless/rtl818x.h
+++ b/drivers/net/wireless/rtl818x.h
@@ -113,14 +113,16 @@ struct rtl818x_csr {
#define RTL818X_CONFIG4_VCOOFF (1 << 7)
u8 TESTR;
u8 reserved_9[2];
- __le16 PGSELECT;
+ u8 PGSELECT;
+ u8 SECURITY;
__le32 ANAPARAM2;
u8 reserved_10[12];
__le16 BEACON_INTERVAL;
__le16 ATIM_WND;
__le16 BEACON_INTERVAL_TIME;
__le16 ATIMTR_INTERVAL;
- __le16 PHY_DELAY;
+ u8 PHY_DELAY;
+ u8 CARRIER_SENSE_COUNTER;
u8 reserved_11[2];
u8 PHY[4];
__le16 RFPinsOutput;