Search Linux Wireless

[PATCH] rtl818x: Use RF ops tables

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Unfortunately, merging the usb and pci rtl8225 rf code is currently
more pain than gain. Switch to RF ops tables to avoid symbol conflicts
when building in the rtl818x drivers.

Signed-off-by: Michael Wu <flamingice@xxxxxxxxxxxx>
---

 drivers/net/wireless/rtl8180.h         |    4 --
 drivers/net/wireless/rtl8180_dev.c     |   47 +++++----------------
 drivers/net/wireless/rtl8180_grf5101.c |   15 +++++--
 drivers/net/wireless/rtl8180_grf5101.h |    4 --
 drivers/net/wireless/rtl8180_max2820.c |   16 +++++--
 drivers/net/wireless/rtl8180_max2820.h |    4 --
 drivers/net/wireless/rtl8180_rtl8225.c |   71 ++++++++++++++++++++------------
 drivers/net/wireless/rtl8180_rtl8225.h |    7 ---
 drivers/net/wireless/rtl8180_sa2400.c  |   14 +++++-
 drivers/net/wireless/rtl8180_sa2400.h  |    4 --
 drivers/net/wireless/rtl8187.h         |    2 -
 drivers/net/wireless/rtl8187_dev.c     |   48 ++++++++--------------
 drivers/net/wireless/rtl8187_rtl8225.c |   52 +++++++++++++++++++----
 drivers/net/wireless/rtl8187_rtl8225.h |    9 ----
 drivers/net/wireless/rtl818x.h         |    7 +++
 15 files changed, 163 insertions(+), 141 deletions(-)

diff --git a/drivers/net/wireless/rtl8180.h b/drivers/net/wireless/rtl8180.h
index 41b64cb..2cbfe3c 100644
--- a/drivers/net/wireless/rtl8180.h
+++ b/drivers/net/wireless/rtl8180.h
@@ -89,9 +89,7 @@ struct rtl8180_tx_ring {
 struct rtl8180_priv {
 	/* common between rtl818x drivers */
 	struct rtl818x_csr __iomem *map;
-	void (*rf_init)(struct ieee80211_hw *);
-	void (*rf_stop)(struct ieee80211_hw *);
-	void (*rf_set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
+	const struct rtl818x_rf_ops *rf;
 	struct ieee80211_vif *vif;
 	int mode;
 
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index c8e24a1..07f37b0 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -375,7 +375,7 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
 		rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C);
 	}
 
-	priv->rf_init(dev);
+	priv->rf->init(dev);
 	if (priv->r8185)
 		rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
 	return 0;
@@ -609,7 +609,7 @@ static void rtl8180_stop(struct ieee80211_hw *dev)
 	reg &= ~RTL818X_CMD_RX_ENABLE;
 	rtl818x_iowrite8(priv, &priv->map->CMD, reg);
 
-	priv->rf_stop(dev);
+	priv->rf->stop(dev);
 
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
 	reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
@@ -663,7 +663,7 @@ static int rtl8180_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
 {
 	struct rtl8180_priv *priv = dev->priv;
 
-	priv->rf_set_chan(dev, conf);
+	priv->rf->set_chan(dev, conf);
 
 	return 0;
 }
@@ -770,7 +770,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
 	unsigned int io_addr, io_len;
 	int err, i;
 	struct eeprom_93cx6 eeprom;
-	const char *chip_name, *rf_name;
+	const char *chip_name, *rf_name = NULL;
 	u32 reg;
 	u16 eeprom_val;
 	DECLARE_MAC_BUF(mac);
@@ -900,40 +900,17 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
 	eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val);
 	eeprom_val &= 0xFF;
 	switch (eeprom_val) {
-	case 1:
-		rf_name = "Intersil";
+	case 1:	rf_name = "Intersil";
 		break;
-	case 2:
-		rf_name = "RFMD";
+	case 2:	rf_name = "RFMD";
 		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;
+	case 3:	priv->rf = &sa2400_rf_ops;
 		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;
+	case 4:	priv->rf = &max2820_rf_ops;
 		break;
-	case 5:
-		rf_name = "GCT";
-		priv->rf_init = grf5101_rf_init;
-		priv->rf_stop = grf5101_rf_stop;
-		priv->rf_set_chan = grf5101_rf_set_channel;
+	case 5:	priv->rf = &grf5101_rf_ops;
 		break;
-	case 9:
-		if (rtl8225_is_z2(dev)) {
-			rf_name = "RTL8225z2";
-			priv->rf_init = rtl8225z2_rf_init;
-		} else {
-			rf_name = "RTL8225";
-			priv->rf_init = rtl8225_rf_init;
-		}
-		priv->rf_stop = rtl8225_rf_stop;
-		priv->rf_set_chan = rtl8225_rf_set_channel;
+	case 9:	priv->rf = rtl8180_detect_rf(dev);
 		break;
 	case 10:
 		rf_name = "RTL8255";
@@ -944,7 +921,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
 		goto err_iounmap;
 	}
 
-	if (eeprom_val < 3) {
+	if (!priv->rf) {
 		printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n",
 		       pci_name(pdev), rf_name);
 		goto err_iounmap;
@@ -997,7 +974,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
 
 	printk(KERN_INFO "%s: hwaddr %s, %s + %s\n",
 	       wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
-	       chip_name, rf_name);
+	       chip_name, priv->rf->name);
 
 	return 0;
 
diff --git a/drivers/net/wireless/rtl8180_grf5101.c b/drivers/net/wireless/rtl8180_grf5101.c
index 11e80ab..8293e19 100644
--- a/drivers/net/wireless/rtl8180_grf5101.c
+++ b/drivers/net/wireless/rtl8180_grf5101.c
@@ -69,8 +69,8 @@ static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan)
 	rtl8180_write_phy(dev, 0x10, ant);
 }
 
-void grf5101_rf_set_channel(struct ieee80211_hw *dev,
-			    struct ieee80211_conf *conf)
+static void grf5101_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;
@@ -90,7 +90,7 @@ void grf5101_rf_set_channel(struct ieee80211_hw *dev,
 	grf5101_write_phy_antenna(dev, chan);
 }
 
-void grf5101_rf_stop(struct ieee80211_hw *dev)
+static void grf5101_rf_stop(struct ieee80211_hw *dev)
 {
 	struct rtl8180_priv *priv = dev->priv;
 	u32 anaparam;
@@ -106,7 +106,7 @@ void grf5101_rf_stop(struct ieee80211_hw *dev)
 	write_grf5101(dev, 0x00, 0x8e4);
 }
 
-void grf5101_rf_init(struct ieee80211_hw *dev)
+static void grf5101_rf_init(struct ieee80211_hw *dev)
 {
 	struct rtl8180_priv *priv = dev->priv;
 
@@ -170,3 +170,10 @@ void grf5101_rf_init(struct ieee80211_hw *dev)
 	rtl8180_write_phy(dev, 0x1a, 0xa0);
 	rtl8180_write_phy(dev, 0x1b, 0x44);
 }
+
+const struct rtl818x_rf_ops grf5101_rf_ops = {
+	.name		= "GCT",
+	.init		= grf5101_rf_init,
+	.stop		= grf5101_rf_stop,
+	.set_chan	= grf5101_rf_set_channel
+};
diff --git a/drivers/net/wireless/rtl8180_grf5101.h b/drivers/net/wireless/rtl8180_grf5101.h
index 5b4a171..7664711 100644
--- a/drivers/net/wireless/rtl8180_grf5101.h
+++ b/drivers/net/wireless/rtl8180_grf5101.h
@@ -23,8 +23,6 @@
 
 #define GRF5101_ANTENNA 0xA3
 
-void grf5101_rf_init(struct ieee80211_hw *);
-void grf5101_rf_stop(struct ieee80211_hw *);
-void grf5101_rf_set_channel(struct ieee80211_hw *, struct ieee80211_conf *);
+extern const struct rtl818x_rf_ops grf5101_rf_ops;
 
 #endif /* RTL8180_GRF5101_H */
diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl8180_max2820.c
index c3e125f..98fe9fd 100644
--- a/drivers/net/wireless/rtl8180_max2820.c
+++ b/drivers/net/wireless/rtl8180_max2820.c
@@ -26,7 +26,7 @@
 #include "rtl8180.h"
 #include "rtl8180_max2820.h"
 
-u32 max2820_chan[] = {
+static const u32 max2820_chan[] = {
 	12, /* CH 1 */
 	17,
 	22,
@@ -74,7 +74,8 @@ static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan)
 	rtl8180_write_phy(dev, 0x10, ant);
 }
 
-void max2820_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+static 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;
@@ -89,14 +90,14 @@ void max2820_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *con
 	write_max2820(dev, 3, chan);
 }
 
-void max2820_rf_stop(struct ieee80211_hw *dev)
+static 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)
+static void max2820_rf_init(struct ieee80211_hw *dev)
 {
 	struct rtl8180_priv *priv = dev->priv;
 
@@ -140,3 +141,10 @@ void max2820_rf_init(struct ieee80211_hw *dev)
 
 	max2820_rf_set_channel(dev, NULL);
 }
+
+const struct rtl818x_rf_ops max2820_rf_ops = {
+	.name		= "Maxim",
+	.init		= max2820_rf_init,
+	.stop		= max2820_rf_stop,
+	.set_chan	= max2820_rf_set_channel
+};
diff --git a/drivers/net/wireless/rtl8180_max2820.h b/drivers/net/wireless/rtl8180_max2820.h
index 8e27292..61cf6d1 100644
--- a/drivers/net/wireless/rtl8180_max2820.h
+++ b/drivers/net/wireless/rtl8180_max2820.h
@@ -23,8 +23,6 @@
 
 #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 *);
+extern const struct rtl818x_rf_ops max2820_rf_ops;
 
 #endif /* RTL8180_MAX2820_H */
diff --git a/drivers/net/wireless/rtl8180_rtl8225.c b/drivers/net/wireless/rtl8180_rtl8225.c
index 09a54fd..37ac402 100644
--- a/drivers/net/wireless/rtl8180_rtl8225.c
+++ b/drivers/net/wireless/rtl8180_rtl8225.c
@@ -299,28 +299,7 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
 	msleep(1);
 }
 
-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);
-
-	if (rtl8225_read(dev, 8) == 0x588 && rtl8225_read(dev, 9) == 0x700)
-		z2 = 1;
-
-	rtl8225_write(dev, 0, 0x0B7);
-
-	return z2;
-}
-
-void rtl8225_rf_init(struct ieee80211_hw *dev)
+static void rtl8225_rf_init(struct ieee80211_hw *dev)
 {
 	struct rtl8180_priv *priv = dev->priv;
 	int i;
@@ -549,7 +528,7 @@ static const u16 rtl8225z2_rxgain[] = {
 	0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
 };
 
-void rtl8225z2_rf_init(struct ieee80211_hw *dev)
+static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
 {
 	struct rtl8180_priv *priv = dev->priv;
 	int i;
@@ -718,7 +697,7 @@ void rtl8225z2_rf_init(struct ieee80211_hw *dev)
 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
 }
 
-void rtl8225_rf_stop(struct ieee80211_hw *dev)
+static void rtl8225_rf_stop(struct ieee80211_hw *dev)
 {
 	struct rtl8180_priv *priv = dev->priv;
 	u8 reg;
@@ -734,12 +713,12 @@ void rtl8225_rf_stop(struct ieee80211_hw *dev)
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 }
 
-void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
-			    struct ieee80211_conf *conf)
+static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
+				   struct ieee80211_conf *conf)
 {
 	struct rtl8180_priv *priv = dev->priv;
 
-	if (priv->rf_init == rtl8225_rf_init)
+	if (priv->rf->init == rtl8225_rf_init)
 		rtl8225_rf_set_tx_power(dev, conf->channel);
 	else
 		rtl8225z2_rf_set_tx_power(dev, conf->channel);
@@ -761,3 +740,41 @@ void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
 		rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
 	}
 }
+
+static const struct rtl818x_rf_ops rtl8225_ops = {
+	.name		= "rtl8225",
+	.init		= rtl8225_rf_init,
+	.stop		= rtl8225_rf_stop,
+	.set_chan	= rtl8225_rf_set_channel
+};
+
+static const struct rtl818x_rf_ops rtl8225z2_ops = {
+	.name		= "rtl8225z2",
+	.init		= rtl8225z2_rf_init,
+	.stop		= rtl8225_rf_stop,
+	.set_chan	= rtl8225_rf_set_channel
+};
+
+const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
+{
+	struct rtl8180_priv *priv = dev->priv;
+	u16 reg8, reg9;
+
+	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);
+
+	reg8 = rtl8225_read(dev, 8);
+	reg9 = rtl8225_read(dev, 9);
+
+	rtl8225_write(dev, 0, 0x0B7);
+
+	if (reg8 != 0x588 || reg9 != 0x700)
+		return &rtl8225_ops;
+
+	return &rtl8225z2_ops;
+}
diff --git a/drivers/net/wireless/rtl8180_rtl8225.h b/drivers/net/wireless/rtl8180_rtl8225.h
index e142795..92d2b17 100644
--- a/drivers/net/wireless/rtl8180_rtl8225.h
+++ b/drivers/net/wireless/rtl8180_rtl8225.h
@@ -6,12 +6,7 @@
 #define RTL8225_ANAPARAM_OFF	0xa00beb59
 #define RTL8225_ANAPARAM2_OFF	0x840dec11
 
-int rtl8225_is_z2(struct ieee80211_hw *dev);
-
-void rtl8225_rf_init(struct ieee80211_hw *);
-void rtl8225z2_rf_init(struct ieee80211_hw *);
-void rtl8225_rf_stop(struct ieee80211_hw *);
-void rtl8225_rf_set_channel(struct ieee80211_hw *, struct ieee80211_conf *);
+const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *);
 
 static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev,
 					  u8 addr, u8 data)
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c
index dea7e5a..e08ace7 100644
--- a/drivers/net/wireless/rtl8180_sa2400.c
+++ b/drivers/net/wireless/rtl8180_sa2400.c
@@ -76,7 +76,8 @@ static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan)
 
 }
 
-void sa2400_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+static 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;
@@ -92,12 +93,12 @@ void sa2400_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf
 	write_sa2400(dev, 3, 0);
 }
 
-void sa2400_rf_stop(struct ieee80211_hw *dev)
+static void sa2400_rf_stop(struct ieee80211_hw *dev)
 {
 	write_sa2400(dev, 4, 0);
 }
 
-void sa2400_rf_init(struct ieee80211_hw *dev)
+static void sa2400_rf_init(struct ieee80211_hw *dev)
 {
 	struct rtl8180_priv *priv = dev->priv;
 	u32 anaparam, txconf;
@@ -191,3 +192,10 @@ void sa2400_rf_init(struct ieee80211_hw *dev)
 	rtl8180_write_phy(dev, 0x19, 0x0);
 	rtl8180_write_phy(dev, 0x1a, 0xa0);
 }
+
+const struct rtl818x_rf_ops sa2400_rf_ops = {
+	.name		= "Philips",
+	.init		= sa2400_rf_init,
+	.stop		= sa2400_rf_stop,
+	.set_chan	= sa2400_rf_set_channel
+};
diff --git a/drivers/net/wireless/rtl8180_sa2400.h b/drivers/net/wireless/rtl8180_sa2400.h
index 018bb92..a4aaa0d 100644
--- a/drivers/net/wireless/rtl8180_sa2400.h
+++ b/drivers/net/wireless/rtl8180_sa2400.h
@@ -31,8 +31,6 @@
 
 #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 *);
+extern const struct rtl818x_rf_ops sa2400_rf_ops;
 
 #endif /* RTL8180_SA2400_H */
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h
index a934a46..8680a0b 100644
--- a/drivers/net/wireless/rtl8187.h
+++ b/drivers/net/wireless/rtl8187.h
@@ -64,7 +64,7 @@ struct rtl8187_tx_hdr {
 struct rtl8187_priv {
 	/* common between rtl818x drivers */
 	struct rtl818x_csr *map;
-	void (*rf_init)(struct ieee80211_hw *);
+	const struct rtl818x_rf_ops *rf;
 	struct ieee80211_vif *vif;
 	int mode;
 
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 13399de..0d71716 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -394,7 +394,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7);
 	msleep(100);
 
-	priv->rf_init(dev);
+	priv->rf->init(dev);
 
 	rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
 	reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1;
@@ -407,24 +407,6 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
 	return 0;
 }
 
-static void rtl8187_set_channel(struct ieee80211_hw *dev, int channel)
-{
-	u32 reg;
-	struct rtl8187_priv *priv = dev->priv;
-
-	reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
-	/* Enable TX loopback on MAC level to avoid TX during channel
-	 * changes, as this has be seen to causes problems and the
-	 * card will stop work until next reset
-	 */
-	rtl818x_iowrite32(priv, &priv->map->TX_CONF,
-			  reg | RTL818X_TX_CONF_LOOPBACK_MAC);
-	msleep(10);
-	rtl8225_rf_set_channel(dev, channel);
-	msleep(10);
-	rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
-}
-
 static int rtl8187_start(struct ieee80211_hw *dev)
 {
 	struct rtl8187_priv *priv = dev->priv;
@@ -493,7 +475,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
 	reg &= ~RTL818X_CMD_RX_ENABLE;
 	rtl818x_iowrite8(priv, &priv->map->CMD, reg);
 
-	rtl8225_rf_stop(dev);
+	priv->rf->stop(dev);
 
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
 	reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
@@ -544,7 +526,19 @@ static void rtl8187_remove_interface(struct ieee80211_hw *dev,
 static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
 {
 	struct rtl8187_priv *priv = dev->priv;
-	rtl8187_set_channel(dev, conf->channel);
+	u32 reg;
+
+	reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
+	/* Enable TX loopback on MAC level to avoid TX during channel
+	 * changes, as this has be seen to causes problems and the
+	 * card will stop work until next reset
+	 */
+	rtl818x_iowrite32(priv, &priv->map->TX_CONF,
+			  reg | RTL818X_TX_CONF_LOOPBACK_MAC);
+	msleep(10);
+	priv->rf->set_chan(dev, conf);
+	msleep(10);
+	rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
 
 	rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
 
@@ -762,14 +756,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
 	rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
-	rtl8225_write(dev, 0, 0x1B7);
-
-	if (rtl8225_read(dev, 8) != 0x588 || rtl8225_read(dev, 9) != 0x700)
-		priv->rf_init = rtl8225_rf_init;
-	else
-		priv->rf_init = rtl8225z2_rf_init;
-
-	rtl8225_write(dev, 0, 0x0B7);
+	priv->rf = rtl8187_detect_rf(dev);
 
 	err = ieee80211_register_hw(dev);
 	if (err) {
@@ -779,8 +766,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
 
 	printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n",
 	       wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
-	       priv->asic_rev, priv->rf_init == rtl8225_rf_init ?
-	       "rtl8225" : "rtl8225z2");
+	       priv->asic_rev, priv->rf->name);
 
 	return 0;
 
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c
index eade81f..c04ad34 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl8187_rtl8225.c
@@ -101,7 +101,7 @@ static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data)
 	msleep(2);
 }
 
-void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
+static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
 {
 	struct rtl8187_priv *priv = dev->priv;
 
@@ -111,7 +111,7 @@ void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
 		rtl8225_write_bitbang(dev, addr, data);
 }
 
-u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
+static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
 {
 	struct rtl8187_priv *priv = dev->priv;
 	u16 reg80, reg82, reg84, out;
@@ -325,7 +325,7 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
 	msleep(1);
 }
 
-void rtl8225_rf_init(struct ieee80211_hw *dev)
+static void rtl8225_rf_init(struct ieee80211_hw *dev)
 {
 	struct rtl8187_priv *priv = dev->priv;
 	int i;
@@ -567,7 +567,7 @@ static const u8 rtl8225z2_gain_bg[] = {
 	0x63, 0x15, 0xc5  /* -66dBm */
 };
 
-void rtl8225z2_rf_init(struct ieee80211_hw *dev)
+static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
 {
 	struct rtl8187_priv *priv = dev->priv;
 	int i;
@@ -715,7 +715,7 @@ void rtl8225z2_rf_init(struct ieee80211_hw *dev)
 	rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
 }
 
-void rtl8225_rf_stop(struct ieee80211_hw *dev)
+static void rtl8225_rf_stop(struct ieee80211_hw *dev)
 {
 	u8 reg;
 	struct rtl8187_priv *priv = dev->priv;
@@ -731,15 +731,47 @@ void rtl8225_rf_stop(struct ieee80211_hw *dev)
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 }
 
-void rtl8225_rf_set_channel(struct ieee80211_hw *dev, int channel)
+static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
+				   struct ieee80211_conf *conf)
 {
 	struct rtl8187_priv *priv = dev->priv;
 
-	if (priv->rf_init == rtl8225_rf_init)
-		rtl8225_rf_set_tx_power(dev, channel);
+	if (priv->rf->init == rtl8225_rf_init)
+		rtl8225_rf_set_tx_power(dev, conf->channel);
 	else
-		rtl8225z2_rf_set_tx_power(dev, channel);
+		rtl8225z2_rf_set_tx_power(dev, conf->channel);
 
-	rtl8225_write(dev, 0x7, rtl8225_chan[channel - 1]);
+	rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]);
 	msleep(10);
 }
+
+static const struct rtl818x_rf_ops rtl8225_ops = {
+	.name		= "rtl8225",
+	.init		= rtl8225_rf_init,
+	.stop		= rtl8225_rf_stop,
+	.set_chan	= rtl8225_rf_set_channel
+};
+
+static const struct rtl818x_rf_ops rtl8225z2_ops = {
+	.name		= "rtl8225z2",
+	.init		= rtl8225z2_rf_init,
+	.stop		= rtl8225_rf_stop,
+	.set_chan	= rtl8225_rf_set_channel
+};
+
+const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev)
+{
+	u16 reg8, reg9;
+
+	rtl8225_write(dev, 0, 0x1B7);
+
+	reg8 = rtl8225_read(dev, 8);
+	reg9 = rtl8225_read(dev, 9);
+
+	rtl8225_write(dev, 0, 0x0B7);
+
+	if (reg8 != 0x588 || reg9 != 0x700)
+		return &rtl8225_ops;
+
+	return &rtl8225z2_ops;
+}
diff --git a/drivers/net/wireless/rtl8187_rtl8225.h b/drivers/net/wireless/rtl8187_rtl8225.h
index 798ba4a..d39ed02 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.h
+++ b/drivers/net/wireless/rtl8187_rtl8225.h
@@ -20,14 +20,7 @@
 #define RTL8225_ANAPARAM_OFF	0xa00beb59
 #define RTL8225_ANAPARAM2_OFF	0x840dec11
 
-void rtl8225_write(struct ieee80211_hw *, u8 addr, u16 data);
-u16  rtl8225_read(struct ieee80211_hw *, u8 addr);
-
-void rtl8225_rf_init(struct ieee80211_hw *);
-void rtl8225z2_rf_init(struct ieee80211_hw *);
-void rtl8225_rf_stop(struct ieee80211_hw *);
-void rtl8225_rf_set_channel(struct ieee80211_hw *, int);
-
+const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *);
 
 static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev,
 					  u8 addr, u32 data)
diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x.h
index 1322f6a..1e7d6f8 100644
--- a/drivers/net/wireless/rtl818x.h
+++ b/drivers/net/wireless/rtl818x.h
@@ -168,6 +168,13 @@ struct rtl818x_csr {
 	u8	TALLY_SEL;
 } __attribute__((packed));
 
+struct rtl818x_rf_ops {
+	char *name;
+	void (*init)(struct ieee80211_hw *);
+	void (*stop)(struct ieee80211_hw *);
+	void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
+};
+
 static const struct ieee80211_rate rtl818x_rates[] = {
 	{ .rate = 10,
 	  .val = 0,


-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux