From: Hin-Tak Leung <htl10@users.sourceforge.net>
To: Herton Ronaldo Krzesinski <herton@mandriva.com.br>,
Larry Finger <Larry.Finger@lwfinger.net>
Cc: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>,
linux-wireless@vger.kernel.org,
John W Linville <linville@tuxdriver.com>,
seno <senada@t-online.de>
Subject: Re: [PATCH 9/9] rtl8187: restore anaparam registers after reset with 8187B
Date: Sun, 7 Nov 2010 13:51:10 +0000 (GMT) [thread overview]
Message-ID: <780743.69807.qm@web29503.mail.ird.yahoo.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 670 bytes --]
--- On Sun, 7/11/10, Larry Finger <Larry.Finger@lwfinger.net> wrote:
> > Do you have any pointer to it? (I can't find in the
> archives in April
> > 9 2009). Never saw it, if was posted in the mailing
> list certainly
> > missed it (and probably I was not in CC).
>
> There is a reference to it at
> http://www.spinics.net/lists/linux-wireless/msg31345.html.
> The patches were
> never done quite right, and I do not remember testing. As I
> have only 1 antenna
> (I think), it likely would not have affected the results.
>
> Larry
Yes, that's the one. Here is the patch from my stash anyway, it looks like it is exactly that.
Hin-Tak
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: rtl8187_antenna_diversity.patch --]
[-- Type: text/x-patch; name="rtl8187_antenna_diversity.patch", Size: 11464 bytes --]
diff -urN compat-wireless-2.6-old.orig/drivers/net/wireless/Makefile compat-wireless-2.6-old/drivers/net/wireless/Makefile
--- compat-wireless-2.6-old.orig/drivers/net/wireless/Makefile 2008-12-17 19:03:17.000000000 +0200
+++ compat-wireless-2.6-old/drivers/net/wireless/Makefile 2009-04-07 20:15:28.000000000 +0300
@@ -1,6 +1,7 @@
#
# Makefile for the Linux Wireless network device drivers.
#
+EXTRA_CFLAGS += -DSW_ANTENNA_DIVERSITY
obj-$(CONFIG_IPW2100) += ipw2100.o
diff -urN compat-wireless-2.6-old.orig/drivers/net/wireless/rtl8187_dev.c compat-wireless-2.6-old/drivers/net/wireless/rtl8187_dev.c
--- compat-wireless-2.6-old.orig/drivers/net/wireless/rtl8187_dev.c 2008-09-15 19:57:24.000000000 +0300
+++ compat-wireless-2.6-old/drivers/net/wireless/rtl8187_dev.c 2009-04-08 15:18:09.000000000 +0300
@@ -21,6 +21,8 @@
#include <linux/etherdevice.h>
#include <linux/eeprom_93cx6.h>
#include <net/mac80211.h>
+#include <linux/proc_fs.h> // for use the proc fs
+
#include "rtl8187.h"
#include "rtl8187_rtl8225.h"
@@ -45,6 +47,8 @@
{USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
/* Sitecom */
{USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
+ {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187},
+
{}
};
@@ -257,6 +261,7 @@
usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
buf, skb->len, rtl8187_tx_cb, skb);
+ urb->transfer_flags |= URB_ZERO_PACKET;
rc = usb_submit_urb(urb, GFP_ATOMIC);
if (rc < 0) {
usb_free_urb(urb);
@@ -266,6 +271,15 @@
return 0;
}
+#ifdef SW_ANTENNA_DIVERSITY
+inline void add_to_average_array(struct rtl8187_priv * priv, u8 val)
+{
+ priv->ant_diversity.agc_array[ priv->ant_diversity.count++ ] = val;
+ if (priv->ant_diversity.count >= VAL_ARRAY_SIZE)
+ priv->ant_diversity.count = 0;
+}
+#endif /* SW_ANTENNA_DIVERSITY */
+
static void rtl8187_rx_cb(struct urb *urb)
{
struct sk_buff *skb = (struct sk_buff *)urb->context;
@@ -320,6 +334,9 @@
}
rx_status.signal = signal;
priv->signal = signal;
+#ifdef SW_ANTENNA_DIVERSITY
+ add_to_average_array(priv, hdr->agc);
+#endif /* SW_ANTENNA_DIVERSITY */
} else {
struct rtl8187b_rx_hdr *hdr =
(typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
@@ -555,6 +572,13 @@
rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60);
rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+#ifdef SW_ANTENNA_DIVERSITY
+ INIT_DELAYED_WORK(&priv->antenna_work, SwAntennaWorkItemCallback);
+
+ priv->ant_diversity.switch_to = 0;
+ SwitchAntenna(priv);
+#endif /* SW_ANTENNA_DIVERSITY */
+
return 0;
}
@@ -721,6 +745,8 @@
static int rtl8187_start(struct ieee80211_hw *dev)
{
struct rtl8187_priv *priv = dev->priv;
+
+ priv->hw = dev;
u32 reg;
int ret;
@@ -836,6 +862,10 @@
struct rtl8187_priv *priv = dev->priv;
int i;
+#ifdef SW_ANTENNA_DIVERSITY
+ sw_antenna_diversity_timer_callback(priv);
+#endif /* SW_ANTENNA_DIVERSITY */
+
if (priv->mode != NL80211_IFTYPE_MONITOR)
return -EOPNOTSUPP;
@@ -867,6 +897,12 @@
mutex_lock(&priv->conf_mutex);
priv->mode = NL80211_IFTYPE_MONITOR;
priv->vif = NULL;
+
+#ifdef SW_ANTENNA_DIVERSITY
+ del_timer_sync(&priv->sw_antenna_diversity_timer);
+ cancel_delayed_work(&priv->antenna_work);
+#endif /* SW_ANTENNA_DIVERSITY */
+
mutex_unlock(&priv->conf_mutex);
}
@@ -970,6 +1006,127 @@
rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf);
}
+#ifdef SW_ANTENNA_DIVERSITY
+#define ANTENNA_DIVERSITY_TIMER_PERIOD 2000 // 1000 m
+#define ANTENNA_SWITCH_TIMER_PERIOD 300 // 300 m
+void sw_antenna_diversity_timer_callback(struct rtl8187_priv *priv)
+{
+ static int tick_without_switch = 0;
+ static int old_value = 0;
+ int average = 0;
+ int i;
+ for ( i = 0; i < VAL_ARRAY_SIZE; ++i)
+ {
+ average += priv->ant_diversity.agc_array[i];
+ }
+ average /= VAL_ARRAY_SIZE;
+ average /= 10; // cut 1 chipher
+ printk("%d->%d\n", old_value, average);
+
+ int sub = average - old_value;
+ if (sub < 0)
+ sub *= -1;
+ if (average > old_value)
+ {
+ priv->ant_diversity.switch_to ^= 1;
+ queue_delayed_work(priv->hw->workqueue, &priv->antenna_work,
+ msecs_to_jiffies(ANTENNA_SWITCH_TIMER_PERIOD));
+ }
+ old_value = average;
+
+ priv->sw_antenna_diversity_timer.expires = jiffies + msecs_to_jiffies(ANTENNA_DIVERSITY_TIMER_PERIOD);
+ add_timer(&priv->sw_antenna_diversity_timer);
+
+}
+
+/*
+ * Change Antenna Switch.
+ */
+bool SwitchAntenna(struct rtl8187_priv *priv)
+{
+ u8 u1bAntennaIndex = priv->ant_diversity.switch_to;
+
+ bool bAntennaSwitched = false;
+ switch(u1bAntennaIndex)
+ {
+ case 0:
+ /* main antenna */
+ // Rx CCK.
+ /* original code from realtek driver */
+ write_nic_byte(priv, 0x7f, ((0x01009b90 & 0xff000000) >> 24));
+ write_nic_byte(priv, 0x7e, ((0x01009b90 & 0x00ff0000) >> 16));
+ write_nic_byte(priv, 0x7d, ((0x01009b90 & 0x0000ff00) >> 8));
+ write_nic_byte(priv, 0x7c, ((0x01009b90 & 0x000000ff) >> 0));
+
+ // Rx OFDM.
+ /* original code from realtek driver */
+ write_nic_byte(priv, 0x7f, ((0x000090a6 & 0xff000000) >> 24));
+ write_nic_byte(priv, 0x7e, ((0x000090a6 & 0x00ff0000) >> 16));
+ write_nic_byte(priv, 0x7d, ((0x000090a6 & 0x0000ff00) >> 8));
+ write_nic_byte(priv, 0x7c, ((0x000090a6 & 0x000000ff) >> 0));
+
+ // Tx Antenna.
+ /* original code from realtek driver */
+ write_nic_byte(priv, ANTSEL, 0x03); // Config TX antenna.
+
+ bAntennaSwitched = true;
+ printk("switch to ANT1 antenna\n");
+ break;
+ case 1: /* switch(u1bAntennaIndex) */
+ // Rx CCK.
+ /* original code from realtek driver */
+ write_nic_byte(priv, 0x7f, ((0x0100db90 & 0xff000000) >> 24));
+ write_nic_byte(priv, 0x7e, ((0x0100db90 & 0x00ff0000) >> 16));
+ write_nic_byte(priv, 0x7d, ((0x0100db90 & 0x0000ff00) >> 8));
+ write_nic_byte(priv, 0x7c, ((0x0100db90 & 0x000000ff) >> 0));
+
+ // Rx OFDM.
+ /* original code from realtek driver */
+ write_nic_byte(priv, 0x7f, ((0x000010a6 & 0xff000000) >> 24));
+ write_nic_byte(priv, 0x7e, ((0x000010a6 & 0x00ff0000) >> 16));
+ write_nic_byte(priv, 0x7d, ((0x000010a6 & 0x0000ff00) >> 8));
+ write_nic_byte(priv, 0x7c, ((0x000010a6 & 0x000000ff) >> 0));
+
+ // Tx Antenna.
+ /* original code from realtek driver */
+ write_nic_byte(priv, ANTSEL, 0x00); // Config TX antenna.
+
+ bAntennaSwitched = true;
+ printk("switch to AUX antenna\n");
+ break;
+ default:
+ printk("[%s] unkown u1bAntennaIndex(%d)\n", __FUNCTION__, u1bAntennaIndex);
+ break;
+ } /* switch(u1bAntennaIndex) */
+
+ if(bAntennaSwitched)
+ {
+ priv->ant_diversity.curr_ant_index = u1bAntennaIndex;
+ }
+
+ return bAntennaSwitched;
+}
+
+
+
+void write_nic_byte(struct rtl8187_priv *priv, int indx, u8 data)
+{
+ struct usb_device *udev = priv->udev;
+
+ usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
+ indx|0xff00, 0, &data, 1, HZ / 2);
+}
+
+void SwAntennaWorkItemCallback(struct work_struct *work)
+{
+ struct rtl8187_priv * priv = container_of(work, struct rtl8187_priv, antenna_work.work);
+ SwitchAntenna(priv);
+}
+
+
+#endif /* SW_ANTENNA_DIVERSITY */
+
static const struct ieee80211_ops rtl8187_ops = {
.tx = rtl8187_tx,
.start = rtl8187_start,
@@ -981,6 +1138,52 @@
.configure_filter = rtl8187_configure_filter,
};
+#ifdef SW_ANTENNA_DIVERSITY
+
+#define procfs_name_in "antenna_diversity"
+int procfile_write(struct file *file, const char *buffer, unsigned long count, void* data)
+{
+ struct rtl8187_priv *priv = (struct rtl8187_priv *)data;
+ if (strncmp(buffer, "ANT1", 4) == 0)
+ {
+ priv->ant_diversity.switch_to = 0;
+ queue_delayed_work(priv->hw->workqueue, &priv->antenna_work,
+ msecs_to_jiffies(ANTENNA_SWITCH_TIMER_PERIOD));
+ }
+ else if (strncmp(buffer, "AUX", 3) == 0)
+ {
+ priv->ant_diversity.switch_to = 1;
+ queue_delayed_work(priv->hw->workqueue, &priv->antenna_work,
+ msecs_to_jiffies(ANTENNA_SWITCH_TIMER_PERIOD));
+ }
+ return count;
+}
+
+int init_module_proc(struct rtl8187_priv *priv)
+{
+ struct proc_dir_entry *proc_file;
+
+ proc_file = create_proc_entry(procfs_name_in, 0644, NULL);
+
+ if (proc_file == NULL)
+ {
+ printk(KERN_ALERT "Error: Could not initialize /proc/%s\n", procfs_name_in);
+ return -ENOMEM;
+ }
+
+ proc_file->write_proc = procfile_write;
+ proc_file->owner = THIS_MODULE;
+ proc_file->mode = S_IFREG | S_IRUGO;
+ proc_file->uid = 0;
+ proc_file->gid = 0;
+ proc_file->size = 0;
+ proc_file->data = priv;
+ printk(KERN_INFO "/proc/%s created\n", procfs_name_in);
+ return 0;
+}
+
+#endif //SW_ANTENNA_DIVERSITY
+
static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
{
struct ieee80211_hw *dev = eeprom->data;
@@ -1209,6 +1412,13 @@
printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n",
wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
chip_name, priv->asic_rev, priv->rf->name);
+#ifdef SW_ANTENNA_DIVERSITY
+ #warning ANTENNA DIVERSITY enabled
+ init_module_proc(priv);
+ init_timer(&priv->sw_antenna_diversity_timer);
+ priv->sw_antenna_diversity_timer.data = (unsigned long)priv;
+ priv->sw_antenna_diversity_timer.function = (void *)sw_antenna_diversity_timer_callback;
+#endif /* SW_ANTENNA_DIVERSITY */
return 0;
diff -urN compat-wireless-2.6-old.orig/drivers/net/wireless/rtl8187.h compat-wireless-2.6-old/drivers/net/wireless/rtl8187.h
--- compat-wireless-2.6-old.orig/drivers/net/wireless/rtl8187.h 2008-09-04 00:04:20.000000000 +0300
+++ compat-wireless-2.6-old/drivers/net/wireless/rtl8187.h 2009-04-07 19:53:37.000000000 +0300
@@ -82,11 +82,28 @@
DEVICE_RTL8187B
};
+#ifdef SW_ANTENNA_DIVERSITY
+
+#define VAL_ARRAY_SIZE 10
+
+#define ANTSEL 0x9F
+
+struct rtl8187_ant_diversity {
+ int count;
+ u8 agc_array[VAL_ARRAY_SIZE];
+
+ u8 switch_to;
+ u8 curr_ant_index;
+} __attribute__ ((packed));
+
+#endif /* SW_ANTENNA_DIVERSITY */
+
struct rtl8187_priv {
/* common between rtl818x drivers */
struct rtl818x_csr *map;
const struct rtl818x_rf_ops *rf;
struct ieee80211_vif *vif;
+ struct ieee80211_hw *hw;
int mode;
/* The mutex protects the TX loopback state.
* Any attempt to set channels concurrently locks the device.
@@ -112,6 +129,13 @@
u8 signal;
u8 quality;
u8 noise;
+
+#ifdef SW_ANTENNA_DIVERSITY
+ struct timer_list sw_antenna_diversity_timer;
+ struct rtl8187_ant_diversity ant_diversity;
+ struct delayed_work antenna_work;
+#endif /* SW_ANTENNA_DIVERSITY */
+
};
void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
@@ -218,4 +242,20 @@
rtl818x_iowrite32_idx(priv, addr, val, 0);
}
+void rtl8187_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes);
+#ifdef SW_ANTENNA_DIVERSITY
+
+void sw_antenna_diversity_timer_callback(struct rtl8187_priv *dev);
+
+bool SwitchAntenna(struct rtl8187_priv *priv);
+
+void write_nic_byte(struct rtl8187_priv *priv, int indx, u8 data);
+
+void SwAntennaWorkItemCallback(struct work_struct *work);
+
+#endif /* SW_ANTENNA_DIVERSITY */
+
#endif /* RTL8187_H */
next reply other threads:[~2010-11-07 13:51 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-07 13:51 Hin-Tak Leung [this message]
-- strict thread matches above, loose matches on Subject: below --
2010-11-02 0:59 [PATCH 0/9] rtl8187: start cleanup/revisiting code Herton Ronaldo Krzesinski
2010-11-02 0:59 ` [PATCH 9/9] rtl8187: restore anaparam registers after reset with 8187B Herton Ronaldo Krzesinski
2010-11-04 15:30 ` Thadeu Lima de Souza Cascardo
2010-11-04 15:50 ` Herton Ronaldo Krzesinski
2010-11-05 19:45 ` Thadeu Lima de Souza Cascardo
2010-11-07 1:07 ` Herton Ronaldo Krzesinski
2010-11-07 1:29 ` Hin-Tak Leung
2010-11-07 3:28 ` Herton Ronaldo Krzesinski
2010-11-07 3:45 ` Larry Finger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=780743.69807.qm@web29503.mail.ird.yahoo.com \
--to=htl10@users.sourceforge.net \
--cc=Larry.Finger@lwfinger.net \
--cc=cascardo@holoscopio.com \
--cc=herton@mandriva.com.br \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=senada@t-online.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).