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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.