linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
@ 2008-06-15  0:59 Hin-Tak Leung
  2008-06-18 22:31 ` Uwe Hermann
  2008-06-25 14:08 ` John W. Linville
  0 siblings, 2 replies; 18+ messages in thread
From: Hin-Tak Leung @ 2008-06-15  0:59 UTC (permalink / raw)
  To: herton, linux-wireless, flamingice, andreamrl, linville

[-- Attachment #1: Type: text/plain, Size: 1641 bytes --]

(I am not on linux-wireless so please CC: me if replying)

This is a patch against compat-wireless-2008-06-14 to work with 2.6.25.6-55.fc9.x86_64 kernel headers. I am using it right now so it works for me, YMMV.

It is mostly a patch from Herton a few months ago to add support for
Realtek 8187B. Herton's patch was missing a little quirk change for usb endpoint 12 for management frame; and I ported it forward to current fedora 9 kernel headers. 

The rest of the story is at:
https://bugzilla.redhat.com/show_bug.cgi?id=432280

I have a few questions during the porting:

- control->queue, which the herton's change used, for switching between 4 tramission queue at end point 6,7,5,4, has disappeared. I hard-coded 6 in this version, (see commemt #37 for background), but what's the correct
way to do this in current wireless-2.6 code?

- compat-wireless seems to use a small inlined routine 
from http://article.gmane.org/gmane.linux.kernel.wireless.general/15830,
which isn't in the redhat header yet. so I have added an ifndef at
the top of rtl8187_dev.c . so the patch needs to have that part removed
if commited to compat-wireless.

- obviously it is getting a bit painful to forward-port the patch every time something else changes or something else changes in the header... 
what can I do to make this go into wireless-2.6 ?

I think I have forward-port the patch mostly correctly, but I'd like to hear about comments, etc and how to make it better...
 



      __________________________________________________________
Sent from Yahoo! Mail.
A Smarter Email http://uk.docs.yahoo.com/nowyoucan.html

[-- Attachment #2: compat-wireless-2008-06-14_rtl8187b.diff.working-version --]
[-- Type: application/octet-stream, Size: 41124 bytes --]

diff -ruBb ../orig/compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_dev.c compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_dev.c
--- ../orig/compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_dev.c	2008-06-14 05:10:53.000000000 +0100
+++ compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_dev.c	2008-06-15 00:19:07.000000000 +0100
@@ -20,26 +20,35 @@
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/proc_fs.h>
 #include <net/mac80211.h>
+#ifndef ieee80211_has_morefrags
+static inline int ieee80211_has_morefrags(__le16 fc)
+{
+  return !!(fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS));
+}
+#endif
 
 #include "rtl8187.h"
 #include "rtl8187_rtl8225.h"
 
 MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
 MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
-MODULE_DESCRIPTION("RTL8187 USB wireless driver");
+MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
 MODULE_LICENSE("GPL");
 
 static struct usb_device_id rtl8187_table[] __devinitdata = {
 	/* Realtek */
-	{USB_DEVICE(0x0bda, 0x8187)},
+	{USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
+	{USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
+	{USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
 	/* Netgear */
-	{USB_DEVICE(0x0846, 0x6100)},
-	{USB_DEVICE(0x0846, 0x6a00)},
+	{USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
+	{USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
 	/* HP */
-	{USB_DEVICE(0x03f0, 0xca02)},
+	{USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
 	/* Sitecom */
-	{USB_DEVICE(0x0df6, 0x000d)},
+	{USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
 	{}
 };
 
@@ -153,23 +162,58 @@
 	struct sk_buff *skb = (struct sk_buff *)urb->context;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_hw *hw = info->driver_data[0];
+        struct rtl8187_priv *priv = hw->priv;
 
 	usb_free_urb(info->driver_data[1]);
-	skb_pull(skb, sizeof(struct rtl8187_tx_hdr));
+        skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) :
+                 sizeof(struct rtl8187_tx_hdr));
 	memset(&info->status, 0, sizeof(info->status));
 	info->flags |= IEEE80211_TX_STAT_ACK;
 	ieee80211_tx_status_irqsafe(hw, skb);
 }
 
+static void *rtl8187_tx_buf(struct sk_buff *skb, __le32 flags, __le16 rts_dur,    
+                            __le32 retry)    
+{    
+  struct rtl8187_tx_hdr *hdr;    
+    
+  hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));    
+  hdr->flags = flags;    
+  hdr->len = 0;    
+  hdr->rts_duration = rts_dur;    
+  hdr->retry = retry;    
+    
+  return hdr;    
+}    
+    
+static void *rtl8187b_tx_buf(struct sk_buff *skb, __le32 flags,    
+                             __le16 rts_dur, __le32 retry,    
+                             __le16 tx_dur)    
+{    
+  struct rtl8187b_tx_hdr *hdr;    
+    
+  hdr = (struct rtl8187b_tx_hdr *)skb_push(skb, sizeof(*hdr));    
+  memset(hdr, 0, sizeof(*hdr));    
+  hdr->flags = flags;    
+  hdr->rts_duration = rts_dur;    
+  hdr->retry = retry;    
+  hdr->tx_duration = tx_dur;    
+    
+  return hdr;    
+}    
+
 static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
 	struct rtl8187_priv *priv = dev->priv;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct rtl8187_tx_hdr *hdr;
+	void *buf;
 	struct urb *urb;
 	__le16 rts_dur = 0;
 	u32 flags;
 	int rc;
+        unsigned int ep[4] = { 6, 7, 5, 4 };
+        u16 frame_control = le16_to_cpu(((struct ieee80211_hdr *)(skb->data))->frame_control);
+        u8 is_mgmt = ((frame_control & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT);
 
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb) {
@@ -193,16 +237,24 @@
 		flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
 	}
 
-	hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
-	hdr->flags = cpu_to_le32(flags);
-	hdr->len = 0;
-	hdr->rts_duration = rts_dur;
-	hdr->retry = cpu_to_le32(info->control.retry_limit << 8);
+        if (!priv->is_rtl8187b)   
+          buf = rtl8187_tx_buf(skb, cpu_to_le32(flags), rts_dur,   
+                               cpu_to_le32(info->control.retry_limit << 8));
+        else   
+          buf = rtl8187b_tx_buf(skb, cpu_to_le32(flags), rts_dur,   
+                                cpu_to_le32(info->control.retry_limit << 8),   
+                                ieee80211_generic_frame_duration(   
+                                                                 dev,   
+                                                                 priv->vif,   
+                                                                 skb->len,   
+                                                                 ieee80211_get_tx_rate(dev, info)));
 
 	info->driver_data[0] = dev;
 	info->driver_data[1] = urb;
-	usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2),
-			  hdr, skb->len, rtl8187_tx_cb, skb);
+        usb_fill_bulk_urb(urb, priv->udev,   
+                          usb_sndbulkpipe(priv->udev,   
+                                          priv->is_rtl8187b ? (is_mgmt ? 12 : 6) : 2), /* fix this */  
+                          buf, skb->len, rtl8187_tx_cb, skb);   
 	rc = usb_submit_urb(urb, GFP_ATOMIC);
 	if (rc < 0) {
 		usb_free_urb(urb);
@@ -219,6 +271,7 @@
 	struct ieee80211_hw *dev = info->dev;
 	struct rtl8187_priv *priv = dev->priv;
 	struct rtl8187_rx_hdr *hdr;
+	struct rtl8187b_rx_hdr *hdr_b;
 	struct ieee80211_rx_status rx_status = { 0 };
 	int rate, signal;
 	u32 flags;
@@ -239,11 +292,32 @@
 	}
 
 	skb_put(skb, urb->actual_length);
-	hdr = (struct rtl8187_rx_hdr *)(skb_tail_pointer(skb) - sizeof(*hdr));
+	if (!priv->is_rtl8187b) {
+		hdr = (struct rtl8187_rx_hdr *)
+			(skb_tail_pointer(skb) - sizeof(*hdr));
 	flags = le32_to_cpu(hdr->flags);
-	skb_trim(skb, flags & 0x0FFF);
-
 	signal = hdr->agc >> 1;
+		rx_status.antenna = (hdr->signal >> 7) & 1;
+		rx_status.signal = 64 - min(hdr->noise, (u8)64);
+		rx_status.mactime = le64_to_cpu(hdr->mac_time);
+		priv->signal = hdr->signal;
+		priv->quality = hdr->agc >> 1;
+		priv->noise = hdr->noise;
+	} else {
+		hdr_b = (struct rtl8187b_rx_hdr *)
+			(skb_tail_pointer(skb) - sizeof(*hdr_b));
+		flags = le32_to_cpu(hdr_b->flags);
+		signal = hdr_b->agc >> 1;
+		rx_status.antenna = (hdr_b->signal >> 7) & 1;
+		rx_status.signal = 64 - min(hdr_b->noise, (u8)64);
+		rx_status.noise = hdr_b->noise;
+		rx_status.mactime = le64_to_cpu(hdr_b->mac_time);
+		priv->signal = hdr_b->signal;
+		priv->quality = hdr_b->agc >> 1;
+		priv->noise = hdr_b->noise;
+	}
+
+	skb_trim(skb, flags & 0x0FFF);
 	rate = (flags >> 20) & 0xF;
 	if (rate > 3) {	/* OFDM rate */
 		if (signal > 90)
@@ -259,13 +333,10 @@
 		signal = 95 - signal;
 	}
 
-	rx_status.antenna = (hdr->signal >> 7) & 1;
-	rx_status.qual = 64 - min(hdr->noise, (u8)64);
 	rx_status.signal = signal;
 	rx_status.rate_idx = rate;
 	rx_status.freq = dev->conf.channel->center_freq;
 	rx_status.band = dev->conf.channel->band;
-	rx_status.mactime = le64_to_cpu(hdr->mac_time);
 	rx_status.flag |= RX_FLAG_TSFT;
 	if (flags & (1 << 13))
 		rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
@@ -305,7 +376,8 @@
 			break;
 		}
 		usb_fill_bulk_urb(entry, priv->udev,
-				  usb_rcvbulkpipe(priv->udev, 1),
+				  usb_rcvbulkpipe(priv->udev,
+				  priv->is_rtl8187b ? 3 : 1),
 				  skb_tail_pointer(skb),
 				  RTL8187_MAX_RX, rtl8187_rx_cb, skb);
 		info = (struct rtl8187_rx_info *)skb->cb;
@@ -318,29 +390,12 @@
 	return 0;
 }
 
-static int rtl8187_init_hw(struct ieee80211_hw *dev)
+static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
 {
 	struct rtl8187_priv *priv = dev->priv;
 	u8 reg;
 	int i;
 
-	/* reset */
-	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_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
-	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
-	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
-
-	rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
-
-	msleep(200);
-	rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10);
-	rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11);
-	rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00);
-	msleep(200);
-
 	reg = rtl818x_ioread8(priv, &priv->map->CMD);
 	reg &= (1 << 1);
 	reg |= RTL818X_CMD_RESET;
@@ -376,6 +431,36 @@
 		return -ETIMEDOUT;
 	}
 
+	return 0;
+}
+
+static int rtl8187_init_hw(struct ieee80211_hw *dev)
+{
+	struct rtl8187_priv *priv = dev->priv;
+	u8 reg;
+	int res;
+
+	/* reset */
+	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_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
+	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+	rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
+
+	msleep(200);
+	rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10);
+	rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11);
+	rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00);
+	msleep(200);
+
+	res = rtl8187_cmd_reset(dev);
+	if (res)
+		return res;
+
 	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);
@@ -445,16 +530,192 @@
 	return 0;
 }
 
+static const u8 rtl8187b_reg_table[][3] = {
+	{0xF0, 0x32, 0}, {0xF1, 0x32, 0}, {0xF2, 0x00, 0}, {0xF3, 0x00, 0},
+	{0xF4, 0x32, 0}, {0xF5, 0x43, 0}, {0xF6, 0x00, 0}, {0xF7, 0x00, 0},
+	{0xF8, 0x46, 0}, {0xF9, 0xA4, 0}, {0xFA, 0x00, 0}, {0xFB, 0x00, 0},
+	{0xFC, 0x96, 0}, {0xFD, 0xA4, 0}, {0xFE, 0x00, 0}, {0xFF, 0x00, 0},
+
+	{0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1},
+	{0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1},
+	{0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xE0, 0xFF, 1}, {0xE1, 0x0F, 1},
+	{0xE2, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, {0xF2, 0x02, 1},
+	{0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, {0xF6, 0x06, 1},
+	{0xF7, 0x07, 1}, {0xF8, 0x08, 1},
+
+	{0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2},
+	{0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2},
+	{0x27, 0x8D, 2}, {0x4D, 0x08, 2}, {0x50, 0x05, 2}, {0x51, 0xF5, 2},
+	{0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2},
+	{0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2},
+	{0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2},
+	{0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, {0x72, 0x56, 2},
+	{0x73, 0x9A, 2},
+
+	{0x34, 0xF0, 0}, {0x35, 0x0F, 0}, {0x5B, 0x40, 0}, {0x84, 0x88, 0},
+	{0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0},
+	{0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0},
+	{0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0},
+	{0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x91, 0x03, 0},
+
+	{0x4C, 0x00, 2}, {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0},
+	{0x8E, 0x08, 0}, {0x8F, 0x00, 0}
+};
+
+static int rtl8187b_init_hw(struct ieee80211_hw *dev)
+{
+	struct rtl8187_priv *priv = dev->priv;
+	int res, i;
+	u8 reg;
+
+	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+
+	reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+	reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT;
+	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
+	rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, 0x727f3f52);
+	rtl818x_iowrite32(priv, &priv->map->ANAPARAM, 0x45090658);
+	rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, 0);
+
+	rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10);
+	reg = rtl818x_ioread8(priv, (u8 *)0xFF62);
+	rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5));
+	rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5));
+
+	reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+	reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
+	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
+
+	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+	res = rtl8187_cmd_reset(dev);
+	if (res)
+		return res;
+
+	rtl818x_iowrite16(priv, (__le16 *)0xFF2D, 0x0FFF);
+	reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
+	reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
+	rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
+	reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
+	reg |= RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT |
+	       RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
+	rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
+
+	rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
+	reg = rtl818x_ioread8(priv, &priv->map->RATE_FALLBACK);
+	reg |= RTL818X_RATE_FALLBACK_ENABLE;
+	rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, reg);
+
+	rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
+	rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
+	rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1);
+
+	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+	reg = rtl818x_ioread8(priv, &priv->map->CONFIG1);
+	rtl818x_iowrite8(priv, &priv->map->CONFIG1, (reg & 0x3F) | 0x80);
+	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+	rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
+	for (i = 0; i < ARRAY_SIZE(rtl8187b_reg_table); i++) {
+		rtl818x_iowrite8_idx(priv,
+				     (u8 *)(uintptr_t)
+				     (rtl8187b_reg_table[i][0] | 0xFF00),
+				     rtl8187b_reg_table[i][1],
+				     rtl8187b_reg_table[i][2]);
+	}
+
+	rtl818x_iowrite16(priv, &priv->map->TID_AC_MAP, 0xFA50);
+	rtl818x_iowrite16(priv, &priv->map->INT_MIG, 0);
+
+	rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF0, 0, 1);
+	rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF4, 0, 1);
+	rtl818x_iowrite8_idx(priv, (u8 *)0xFFF8, 0, 1);
+
+	rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001);
+
+	rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2);
+
+	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+	reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+	reg |= RTL818X_CONFIG3_ANAPARAM_WRITE;
+	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
+	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
+	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488);
+	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+	msleep(1100);
+
+	priv->rf->init(dev);
+
+	reg = RTL818X_CMD_TX_ENABLE | RTL818X_CMD_RX_ENABLE;
+	rtl818x_iowrite8(priv, &priv->map->CMD, reg);
+	rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
+
+	rtl818x_iowrite8(priv, (u8 *)0xFE41, 0xF4);
+	rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x00);
+	rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00);
+	rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01);
+	rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x0F);
+	rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00);
+	rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01);
+
+	reg = rtl818x_ioread8(priv, (u8 *)0xFFDB);
+	rtl818x_iowrite8(priv, (u8 *)0xFFDB, reg | (1 << 2));
+	rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x59FA, 3);
+	rtl818x_iowrite16_idx(priv, (__le16 *)0xFF74, 0x59D2, 3);
+	rtl818x_iowrite16_idx(priv, (__le16 *)0xFF76, 0x59D2, 3);
+	rtl818x_iowrite16_idx(priv, (__le16 *)0xFF78, 0x19FA, 3);
+	rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7A, 0x19FA, 3);
+	rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7C, 0x00D0, 3);
+	rtl818x_iowrite8(priv, (u8 *)0xFF61, 0);
+	rtl818x_iowrite8_idx(priv, (u8 *)0xFF80, 0x0F, 1);
+	rtl818x_iowrite8_idx(priv, (u8 *)0xFF83, 0x03, 1);
+	rtl818x_iowrite8(priv, (u8 *)0xFFDA, 0x10);
+	rtl818x_iowrite8_idx(priv, (u8 *)0xFF4D, 0x08, 2);
+
+	rtl818x_iowrite32(priv, &priv->map->HSSI_PARA, 0x0600321B);
+
+	rtl818x_iowrite16_idx(priv, (__le16 *)0xFFEC, 0x0800, 1);
+
+	return 0;
+}
+
 static int rtl8187_start(struct ieee80211_hw *dev)
 {
 	struct rtl8187_priv *priv = dev->priv;
 	u32 reg;
 	int ret;
 
-	ret = rtl8187_init_hw(dev);
+	ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) :
+				     rtl8187b_init_hw(dev);
 	if (ret)
 		return ret;
 
+	if (priv->is_rtl8187b) {
+		reg = RTL818X_RX_CONF_MGMT |
+		      RTL818X_RX_CONF_DATA |
+		      RTL818X_RX_CONF_BROADCAST |
+		      RTL818X_RX_CONF_NICMAC |
+		      RTL818X_RX_CONF_BSSID |
+		      (7 << 13 /* RX FIFO threshold NONE */) |
+		      (7 << 10 /* MAX RX DMA */) |
+		      RTL818X_RX_CONF_RX_AUTORESETPHY |
+		      RTL818X_RX_CONF_ONLYERLPKT |
+		      RTL818X_RX_CONF_MULTICAST;
+		priv->rx_conf = reg;
+		rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
+
+		rtl818x_iowrite32(priv, &priv->map->TX_CONF,
+				  RTL818X_TX_CONF_HW_SEQNUM |
+				  RTL818X_TX_CONF_DISREQQSIZE |
+				  (7 << 8  /* short retry limit */) |
+				  (7 << 0  /* long retry limit */) |
+				  (7 << 21 /* MAX TX DMA */));
+		rtl8187_init_urbs(dev);
+		return 0;
+	}
+
 	rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
 
 	rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
@@ -581,6 +842,7 @@
 	msleep(10);
 	rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
 
+	if (!priv->is_rtl8187b) {
 	rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
 
 	if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
@@ -594,6 +856,7 @@
 		rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24);
 		rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
 	}
+	}
 
 	rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
 	rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
@@ -608,14 +871,20 @@
 {
 	struct rtl8187_priv *priv = dev->priv;
 	int i;
+	u8 reg;
 
 	for (i = 0; i < ETH_ALEN; i++)
 		rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
 
-	if (is_valid_ether_addr(conf->bssid))
-		rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA);
-	else
-		rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK);
+	if (is_valid_ether_addr(conf->bssid)) {
+		reg = RTL818X_MSR_INFRA;
+		if (priv->is_rtl8187b)
+			reg |= RTL818X_MSR_ENEDCA;
+		rtl818x_iowrite8(priv, &priv->map->MSR, reg);
+	} else {
+		reg = RTL818X_MSR_NO_LINK;
+		rtl818x_iowrite8(priv, &priv->map->MSR, reg);
+	}
 
 	return 0;
 }
@@ -694,6 +963,49 @@
 	udelay(10);
 }
 
+static struct proc_dir_entry *rtl8187_proc = NULL;
+
+static int rtl8187_get_radio_status(char *page, char **start, off_t offset,
+				    int count, int *eof, void *data)
+{
+	struct ieee80211_hw *dev = data;
+	struct rtl8187_priv *priv = dev->priv;
+	int res;
+
+	res = snprintf(page, count, "Signal: %u\nQuality: %u\nNoise: %u\n",
+		       priv->signal, priv->quality, priv->noise);
+	*eof = 1;
+	return res;
+}
+
+static void rtl8187_create_proc_entries(struct ieee80211_hw *dev)
+{
+	rtl8187_proc = create_proc_entry(KBUILD_MODNAME, S_IFDIR,
+					 init_net.proc_net);
+	if (!rtl8187_proc) {
+		printk(KERN_WARNING "rtl8187: cannot create rtl8187 "
+				    "/proc entry\n");
+		return;
+	}
+
+	create_proc_read_entry("radio_status", S_IFREG | S_IRUGO,
+				rtl8187_proc, rtl8187_get_radio_status,
+				dev);
+	create_proc_read_entry("radio_registers", S_IFREG | S_IRUGO,
+				rtl8187_proc, rtl8187_get_radio_registers,
+				dev);
+}
+
+static void rtl8187_remove_proc_entries(void)
+{
+	if (!rtl8187_proc)
+		return;
+	remove_proc_entry("radio_registers", rtl8187_proc);
+	remove_proc_entry("radio_status", rtl8187_proc);
+	remove_proc_entry(KBUILD_MODNAME, init_net.proc_net);
+	rtl8187_proc = NULL;
+}
+
 static int __devinit rtl8187_probe(struct usb_interface *intf,
 				   const struct usb_device_id *id)
 {
@@ -702,6 +1014,7 @@
 	struct rtl8187_priv *priv;
 	struct eeprom_93cx6 eeprom;
 	struct ieee80211_channel *channel;
+	const char *chip_name;
 	u16 txpwr, reg;
 	int err, i;
 	DECLARE_MAC_BUF(mac);
@@ -713,6 +1026,8 @@
 	}
 
 	priv = dev->priv;
+	priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B) ||
+			    !memcmp(udev->product, "RTL8187B", 8);
 
 	SET_IEEE80211_DEV(dev, &intf->dev);
 	usb_set_intfdata(intf, dev);
@@ -741,8 +1056,13 @@
 	dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
 		     IEEE80211_HW_RX_INCLUDES_FCS |
 		     IEEE80211_HW_SIGNAL_UNSPEC;
-	dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr);
+        dev->extra_tx_headroom = (!priv->is_rtl8187b) ?
+          sizeof(struct rtl8187_tx_hdr) :
+          sizeof(struct rtl8187b_tx_hdr);
+        if (!priv->is_rtl8187b)
 	dev->queues = 1;
+        else
+          dev->queues = 4;
 	dev->max_signal = 65;
 
 	eeprom.data = dev;
@@ -777,12 +1097,26 @@
 		(*channel++).hw_value = txpwr & 0xFF;
 		(*channel++).hw_value = txpwr >> 8;
 	}
+	if (!priv->is_rtl8187b) {
 	for (i = 0; i < 2; i++) {
-		eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i,
+			eeprom_93cx6_read(&eeprom,
+					  RTL8187_EEPROM_TXPWR_CHAN_6 + i,
 				  &txpwr);
 		(*channel++).hw_value = txpwr & 0xFF;
 		(*channel++).hw_value = txpwr >> 8;
 	}
+	} else {
+		eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6,
+				  &txpwr);
+		(*channel++).hw_value = txpwr & 0xFF;
+
+		eeprom_93cx6_read(&eeprom, 0x0A, &txpwr);
+		(*channel++).hw_value = txpwr & 0xFF;
+
+		eeprom_93cx6_read(&eeprom, 0x1C, &txpwr);
+		(*channel++).hw_value = txpwr & 0xFF;
+		(*channel++).hw_value = txpwr >> 8;
+	}
 
 	eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE,
 			  &priv->txpwr_base);
@@ -796,6 +1130,50 @@
 	rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
+	if (!priv->is_rtl8187b) {
+		u32 reg32;
+		reg32 = rtl818x_ioread32(priv, &priv->map->TX_CONF);
+		reg32 &= RTL818X_TX_CONF_HWVER_MASK;
+		switch (reg32) {
+		case RTL818X_TX_CONF_R8187vD_1:
+		case RTL818X_TX_CONF_R8187vD_2:
+			chip_name = "RTL8187vD";
+			break;
+		default:
+			chip_name = "RTL8187vB (default)";
+		}
+       } else {
+		printk(KERN_WARNING "rtl8187: 8187B chip detected. Support "
+			"is EXPERIMENTAL, and could damage your\n"
+			"         hardware, use at your own risk\n");
+		/* 
+		 * Force USB request to write radio registers for 8187B, Realtek
+		 * only uses it in their sources
+		 */
+		/*if (priv->asic_rev == 0) {
+			printk(KERN_WARNING "rtl8187: Forcing use of USB "
+			       "requests to write to radio registers\n");
+			priv->asic_rev = 1;
+		}*/
+		switch (rtl818x_ioread8(priv, (u8 *)0xFFE1)) {
+		case RTL818X_R8187B_B:
+			chip_name = "RTL8187BvB";
+			priv->hw_rev = RTL8187BvB;
+			break;
+		case RTL818X_R8187B_D:
+			chip_name = "RTL8187BvD";
+			priv->hw_rev = RTL8187BvD;
+			break;
+		case RTL818X_R8187B_E:
+			chip_name = "RTL8187BvE";
+			priv->hw_rev = RTL8187BvE;
+			break;
+		default:
+			chip_name = "RTL8187BvB (default)";
+			priv->hw_rev = RTL8187BvB;
+		}
+	}
+
 	priv->rf = rtl8187_detect_rf(dev);
 
 	err = ieee80211_register_hw(dev);
@@ -804,9 +1182,11 @@
 		goto err_free_dev;
 	}
 
-	printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n",
+	rtl8187_create_proc_entries(dev);
+
+	printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n",
 	       wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
-	       priv->asic_rev, priv->rf->name);
+	       chip_name, priv->asic_rev, priv->rf->name);
 
 	return 0;
 
@@ -827,6 +1207,8 @@
 
 	ieee80211_unregister_hw(dev);
 
+	rtl8187_remove_proc_entries();
+
 	priv = dev->priv;
 	usb_put_dev(interface_to_usbdev(intf));
 	ieee80211_free_hw(dev);
diff -ruBb ../orig/compat-wireless-2008-06-14/drivers/net/wireless/rtl8187.h compat-wireless-2008-06-14/drivers/net/wireless/rtl8187.h
--- ../orig/compat-wireless-2008-06-14/drivers/net/wireless/rtl8187.h	2008-06-14 05:10:53.000000000 +0100
+++ compat-wireless-2008-06-14/drivers/net/wireless/rtl8187.h	2008-06-14 23:47:49.000000000 +0100
@@ -44,8 +44,19 @@
 	__le64 mac_time;
 } __attribute__((packed));
 
+struct rtl8187b_rx_hdr {  
+  __le32 flags;  
+  __le64 mac_time;  
+  u8 noise;  
+  u8 signal;  
+  u8 agc;  
+  u8 reserved;  
+  __le32 unused;  
+} __attribute__((packed));
+
 struct rtl8187_tx_hdr {
 	__le32 flags;
+/* Tx flags are common between rtl8187 and rtl8187b */
 #define RTL8187_TX_FLAG_NO_ENCRYPT	(1 << 15)
 #define RTL8187_TX_FLAG_MORE_FRAG	(1 << 17)
 #define RTL8187_TX_FLAG_CTS		(1 << 18)
@@ -55,6 +66,21 @@
 	__le32 retry;
 } __attribute__((packed));
 
+struct rtl8187b_tx_hdr {
+  __le32 flags;
+  __le16 rts_duration;
+  __le16 len;
+  __le32 unused_1;
+  __le16 unused_2;
+  __le16 tx_duration;
+  __le32 unused_3;
+  __le32 retry;
+  __le32 unused_4[2];
+} __attribute__((packed));
+
+#define DEVICE_RTL8187  0
+#define DEVICE_RTL8187B 1
+
 struct rtl8187_priv {
 	/* common between rtl818x drivers */
 	struct rtl818x_csr *map;
@@ -70,70 +96,120 @@
 	u32 rx_conf;
 	u16 txpwr_base;
 	u8 asic_rev;
+	u8 is_rtl8187b;
+	enum {
+		RTL8187BvB,
+		RTL8187BvD,
+		RTL8187BvE
+	} hw_rev;
 	struct sk_buff_head rx_queue;
+	u8 signal;
+	u8 quality;
+	u8 noise;
 };
 
 void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
 
-static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr)
+static inline u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv,
+				     u8 *addr, u8 idx)
 {
 	u8 val;
 
 	usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
 			RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
-			(unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+			(unsigned long)addr, idx & 0x03, &val,
+			sizeof(val), HZ / 2);
 
 	return val;
 }
 
-static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr)
+static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr)
+{
+	return rtl818x_ioread8_idx(priv, addr, 0);
+}
+
+static inline u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv,
+				       __le16 *addr, u8 idx)
 {
 	__le16 val;
 
 	usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
 			RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
-			(unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+			(unsigned long)addr, idx & 0x03, &val,
+			sizeof(val), HZ / 2);
 
 	return le16_to_cpu(val);
 }
 
-static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr)
+static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr)
+{
+	return rtl818x_ioread16_idx(priv, addr, 0);
+}
+
+static inline u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv,
+				       __le32 *addr, u8 idx)
 {
 	__le32 val;
 
 	usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
 			RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
-			(unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+			(unsigned long)addr, idx & 0x03, &val,
+			sizeof(val), HZ / 2);
 
 	return le32_to_cpu(val);
 }
 
-static inline void rtl818x_iowrite8(struct rtl8187_priv *priv,
-				    u8 *addr, u8 val)
+static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr)
+{
+	return rtl818x_ioread32_idx(priv, addr, 0);
+}
+
+static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv,
+					u8 *addr, u8 val, u8 idx)
 {
 	usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
 			RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
-			(unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+			(unsigned long)addr, idx & 0x03, &val,
+			sizeof(val), HZ / 2);
 }
 
-static inline void rtl818x_iowrite16(struct rtl8187_priv *priv,
-				     __le16 *addr, u16 val)
+static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val)
+{
+	rtl818x_iowrite8_idx(priv, addr, val, 0);
+}
+
+static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv,
+					 __le16 *addr, u16 val, u8 idx)
 {
 	__le16 buf = cpu_to_le16(val);
 
 	usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
 			RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
-			(unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2);
+			(unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
+			HZ / 2);
+}
+
+static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr,
+				     u16 val)
+{
+	rtl818x_iowrite16_idx(priv, addr, val, 0);
 }
 
-static inline void rtl818x_iowrite32(struct rtl8187_priv *priv,
-				     __le32 *addr, u32 val)
+static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv,
+					 __le32 *addr, u32 val, u8 idx)
 {
 	__le32 buf = cpu_to_le32(val);
 
 	usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
 			RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
-			(unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2);
+			(unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
+			HZ / 2);
+}
+
+static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr,
+				     u32 val)
+{
+	rtl818x_iowrite32_idx(priv, addr, val, 0);
 }
 
 #endif /* RTL8187_H */
diff -ruBb ../orig/compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_rtl8225.c compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_rtl8225.c
--- ../orig/compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_rtl8225.c	2008-06-14 05:10:53.000000000 +0100
+++ compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_rtl8225.c	2008-06-14 23:03:16.000000000 +0100
@@ -471,12 +471,42 @@
 	rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]);
 }
 
+static const u8 rtl8225z2_agc[] = {
+	0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51, 0x4f,
+	0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
+	0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f,
+	0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
+	0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
+	0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28,
+	0x28, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
+	0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30,
+	0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
+	0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
+};
+static const u8 rtl8225z2_ofdm[] = {
+	0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
+	0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
+	0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
+	0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
+	0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
+	0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
+	0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
+	0x6d, 0x3c, 0xfb, 0x07
+};
+
 static const u8 rtl8225z2_tx_power_cck_ch14[] = {
-	0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
+	0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
+	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
+	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
+	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
 };
 
 static const u8 rtl8225z2_tx_power_cck[] = {
-	0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
+	0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
+	0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
+	0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
+	0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
 };
 
 static const u8 rtl8225z2_tx_power_ofdm[] = {
@@ -542,6 +572,85 @@
 	msleep(1);
 }
 
+static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
+{
+	struct rtl8187_priv *priv = dev->priv;
+	u8 cck_power, ofdm_power;
+	const u8 *tmp;
+	int i;
+
+	cck_power = priv->channels[channel - 1].hw_value & 0xF;
+	ofdm_power = priv->channels[channel - 1].hw_value >> 4;
+
+	if (cck_power > 15)
+		cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22;
+	else
+		cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7;
+	cck_power += priv->txpwr_base & 0xF;
+	cck_power = min(cck_power, (u8)35);
+
+	if (ofdm_power > 15)
+		ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25;
+	else
+		ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10;
+	ofdm_power += (priv->txpwr_base >> 4) & 0xF;
+	ofdm_power = min(ofdm_power, (u8)35);
+
+	if (channel == 14)
+		tmp = rtl8225z2_tx_power_cck_ch14;
+	else
+		tmp = rtl8225z2_tx_power_cck;
+
+	if (priv->hw_rev == RTL8187BvB) {
+		if (cck_power <= 6)
+			; /* do nothing */
+		else if (cck_power <= 11)
+			tmp += 8;
+		else
+			tmp += 16;
+	} else {
+		if (cck_power <= 5)
+			; /* do nothing */
+		else if (cck_power <= 11)
+			tmp += 8;
+		else if (cck_power <= 17)
+			tmp += 16;
+		else
+			tmp += 24;
+	}
+
+	for (i = 0; i < 8; i++)
+		rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
+
+	rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
+			 rtl8225z2_tx_gain_cck_ofdm[cck_power]);
+	msleep(1);
+
+	rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
+			 rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1);
+	if (priv->hw_rev == RTL8187BvB) {
+		if (ofdm_power <= 11) {
+			rtl8225_write_phy_ofdm(dev, 0x87, 0x60);
+			rtl8225_write_phy_ofdm(dev, 0x89, 0x60);
+		} else {
+			rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
+			rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
+		}
+	} else {
+		if (ofdm_power <= 11) {
+			rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
+			rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
+		} else if (ofdm_power <= 17) {
+			rtl8225_write_phy_ofdm(dev, 0x87, 0x54);
+			rtl8225_write_phy_ofdm(dev, 0x89, 0x54);
+		} else {
+			rtl8225_write_phy_ofdm(dev, 0x87, 0x50);
+			rtl8225_write_phy_ofdm(dev, 0x89, 0x50);
+		}
+	}
+	msleep(1);
+}
+
 static const u16 rtl8225z2_rxgain[] = {
 	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
 	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
@@ -715,6 +824,81 @@
 	rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
 }
 
+static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
+{
+	struct rtl8187_priv *priv = dev->priv;
+	int i;
+
+	rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
+	rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
+	rtl8225_write(dev, 0x2, 0x44D); msleep(1);
+	rtl8225_write(dev, 0x3, 0x441); msleep(1);
+	rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
+	rtl8225_write(dev, 0x5, 0xC72); msleep(1);
+	rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
+	rtl8225_write(dev, 0x7, 0x82A); msleep(1);
+	rtl8225_write(dev, 0x8, 0x03F); msleep(1);
+	rtl8225_write(dev, 0x9, 0x335); msleep(1);
+	rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
+	rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
+	rtl8225_write(dev, 0xc, 0x850); msleep(1);
+	rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
+	rtl8225_write(dev, 0xe, 0x02B); msleep(1);
+	rtl8225_write(dev, 0xf, 0x114); msleep(1);
+
+	rtl8225_write(dev, 0x0, 0x1B7); msleep(1);
+
+	for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
+		rtl8225_write(dev, 0x1, i + 1); msleep(1);
+		rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); msleep(1);
+	}
+
+	rtl8225_write(dev, 0x3, 0x080); msleep(1);
+	rtl8225_write(dev, 0x5, 0x004); msleep(1);
+	rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
+	msleep(3000);
+
+	rtl8225_write(dev, 0x2, 0xC4D); msleep(1);
+	msleep(2000);
+
+	rtl8225_write(dev, 0x2, 0x44D); msleep(1);
+	rtl8225_write(dev, 0x0, 0x2BF); msleep(1);
+
+	rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03);
+	rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07);
+	rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
+
+	rtl8225_write_phy_ofdm(dev, 0x80, 0x12);
+	for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) {
+		rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]);
+		rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i);
+		rtl8225_write_phy_ofdm(dev, 0xE, 0);
+	}
+	rtl8225_write_phy_ofdm(dev, 0x80, 0x10);
+
+	for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++)
+		rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]);
+
+	rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
+	rtl818x_iowrite8(priv, &priv->map->SLOT, 9);
+	rtl818x_iowrite8(priv, (u8 *)0xFFF0, 28);
+	rtl818x_iowrite8(priv, (u8 *)0xFFF4, 28);
+	rtl818x_iowrite8(priv, (u8 *)0xFFF8, 28);
+	rtl818x_iowrite8(priv, (u8 *)0xFFFC, 28);
+	rtl818x_iowrite8(priv, (u8 *)0xFF2D, 0x5B);
+	rtl818x_iowrite8(priv, (u8 *)0xFF79, 0x5B);
+	rtl818x_iowrite32(priv, (__le32 *)0xFFF0, (7 << 12) | (3 << 8) | 28);
+	rtl818x_iowrite32(priv, (__le32 *)0xFFF4, (7 << 12) | (3 << 8) | 28);
+	rtl818x_iowrite32(priv, (__le32 *)0xFFF8, (7 << 12) | (3 << 8) | 28);
+	rtl818x_iowrite32(priv, (__le32 *)0xFFFC, (7 << 12) | (3 << 8) | 28);
+	rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
+
+	rtl8225_write_phy_ofdm(dev, 0x97, 0x46); msleep(1);
+	rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6); msleep(1);
+	rtl8225_write_phy_ofdm(dev, 0x85, 0xfc); msleep(1);
+	rtl8225_write_phy_cck(dev, 0xc1, 0x88); msleep(1);
+}
+
 static void rtl8225_rf_stop(struct ieee80211_hw *dev)
 {
 	u8 reg;
@@ -731,6 +915,28 @@
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 }
 
+int rtl8187_get_radio_registers(char *page, char **start, off_t offset,
+				int count, int *eof, void *data)
+{
+	struct ieee80211_hw *dev = data;
+	static unsigned int reg_pos;
+	int len = 0;
+
+	while (reg_pos <= 0xFF) {
+		if (len + 11 > count)
+			break;
+		len += snprintf(page + offset + len, count - len,
+				"0x%02x: %04x\n", reg_pos,
+				rtl8225_read(dev, (u8)reg_pos));
+		reg_pos++;
+	}
+	if (reg_pos > 0xFF) {
+		reg_pos = 0;
+		*eof = 1;
+	}
+	return len;
+}
+
 static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
 				   struct ieee80211_conf *conf)
 {
@@ -739,8 +945,10 @@
 
 	if (priv->rf->init == rtl8225_rf_init)
 		rtl8225_rf_set_tx_power(dev, chan);
-	else
+	else if (priv->rf->init == rtl8225z2_rf_init)
 		rtl8225z2_rf_set_tx_power(dev, chan);
+	else
+		rtl8225z2_b_rf_set_tx_power(dev, chan);
 
 	rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
 	msleep(10);
@@ -760,10 +968,19 @@
 	.set_chan	= rtl8225_rf_set_channel
 };
 
+static const struct rtl818x_rf_ops rtl8225z2_b_ops = {
+	.name		= "rtl8225z2",
+	.init		= rtl8225z2_b_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;
+	struct rtl8187_priv *priv = dev->priv;
 
+	if (!priv->is_rtl8187b) {
 	rtl8225_write(dev, 0, 0x1B7);
 
 	reg8 = rtl8225_read(dev, 8);
@@ -775,4 +992,6 @@
 		return &rtl8225_ops;
 
 	return &rtl8225z2_ops;
+	} else
+		return &rtl8225z2_b_ops;
 }
diff -ruBb ../orig/compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_rtl8225.h compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_rtl8225.h
--- ../orig/compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_rtl8225.h	2008-06-14 05:10:53.000000000 +0100
+++ compat-wireless-2008-06-14/drivers/net/wireless/rtl8187_rtl8225.h	2008-06-14 23:03:16.000000000 +0100
@@ -34,4 +34,7 @@
 	rtl8187_write_phy(dev, addr, data | 0x10000);
 }
 
+int rtl8187_get_radio_registers(char *page, char **start, off_t offset,
+				int count, int *eof, void *data);
+
 #endif /* RTL8187_RTL8225_H */
diff -ruBb ../orig/compat-wireless-2008-06-14/drivers/net/wireless/rtl818x.h compat-wireless-2008-06-14/drivers/net/wireless/rtl818x.h
--- ../orig/compat-wireless-2008-06-14/drivers/net/wireless/rtl818x.h	2008-06-14 05:10:53.000000000 +0100
+++ compat-wireless-2008-06-14/drivers/net/wireless/rtl818x.h	2008-06-14 23:03:16.000000000 +0100
@@ -66,7 +66,10 @@
 #define RTL818X_TX_CONF_R8180_F		(3 << 25)
 #define RTL818X_TX_CONF_R8185_ABC	(4 << 25)
 #define RTL818X_TX_CONF_R8185_D		(5 << 25)
+#define RTL818X_TX_CONF_R8187vD_1	(5 << 25)
+#define RTL818X_TX_CONF_R8187vD_2	(6 << 25)
 #define RTL818X_TX_CONF_HWVER_MASK	(7 << 25)
+#define RTL818X_TX_CONF_DISREQQSIZE	(1 << 28)
 #define RTL818X_TX_CONF_PROBE_DTS	(1 << 29)
 #define RTL818X_TX_CONF_HW_SEQNUM	(1 << 30)
 #define RTL818X_TX_CONF_CW_MIN		(1 << 31)
@@ -106,8 +109,11 @@
 #define RTL818X_MSR_NO_LINK		(0 << 2)
 #define RTL818X_MSR_ADHOC		(1 << 2)
 #define RTL818X_MSR_INFRA		(2 << 2)
+#define RTL818X_MSR_MASTER		(3 << 2)
+#define RTL818X_MSR_ENEDCA		(4 << 2)
 	u8	CONFIG3;
 #define RTL818X_CONFIG3_ANAPARAM_WRITE	(1 << 6)
+#define RTL818X_CONFIG3_GNT_SELECT	(1 << 7)
 	u8	CONFIG4;
 #define RTL818X_CONFIG4_POWEROFF	(1 << 6)
 #define RTL818X_CONFIG4_VCOOFF		(1 << 7)
@@ -133,7 +139,9 @@
 	__le32	RF_TIMING;
 	u8	GP_ENABLE;
 	u8	GPIO;
-	u8	reserved_12[10];
+	u8	reserved_12[2];
+	__le32	HSSI_PARA;
+	u8	reserved_13[4];
 	u8	TX_AGC_CTL;
 #define RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT		(1 << 0)
 #define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT	(1 << 1)
@@ -141,29 +149,38 @@
 	u8	TX_GAIN_CCK;
 	u8	TX_GAIN_OFDM;
 	u8	TX_ANTENNA;
-	u8	reserved_13[16];
+	u8	reserved_14[16];
 	u8	WPA_CONF;
-	u8	reserved_14[3];
+	u8	reserved_15[3];
 	u8	SIFS;
 	u8	DIFS;
 	u8	SLOT;
-	u8	reserved_15[5];
+	u8	reserved_16[5];
 	u8	CW_CONF;
 #define RTL818X_CW_CONF_PERPACKET_CW_SHIFT	(1 << 0)
 #define RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT	(1 << 1)
 	u8	CW_VAL;
 	u8	RATE_FALLBACK;
-	u8	reserved_16[25];
+#define RTL818X_RATE_FALLBACK_ENABLE	(1 << 7)
+	u8	ACM_CONTROL;
+	u8	reserved_17[24];
 	u8	CONFIG5;
 	u8	TX_DMA_POLLING;
-	u8	reserved_17[2];
+	u8	reserved_18[2];
 	__le16	CWR;
 	u8	RETRY_CTR;
-	u8	reserved_18[5];
+	u8	reserved_19[3];
+	__le16	INT_MIG;
+#define RTL818X_R8187B_B	0
+#define RTL818X_R8187B_D	1
+#define RTL818X_R8187B_E	2
 	__le32	RDSAR;
-	u8	reserved_19[12];
-	__le16	FEMR;
+	__le16	TID_AC_MAP;
 	u8	reserved_20[4];
+	u8	ANAPARAM3;
+	u8	reserved_21[5];
+	__le16	FEMR;
+	u8	reserved_22[4];
 	__le16	TALLY_CNT;
 	u8	TALLY_SEL;
 } __attribute__((packed));

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-15  0:59 [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189 Hin-Tak Leung
@ 2008-06-18 22:31 ` Uwe Hermann
  2008-06-19  0:17   ` Hin-Tak Leung
  2008-06-25 14:08 ` John W. Linville
  1 sibling, 1 reply; 18+ messages in thread
From: Uwe Hermann @ 2008-06-18 22:31 UTC (permalink / raw)
  To: Hin-Tak Leung; +Cc: herton, linux-wireless, flamingice, andreamrl, linville

On Sun, Jun 15, 2008 at 12:59:54AM +0000, Hin-Tak Leung wrote:
> (I am not on linux-wireless so please CC: me if replying)
> 
> This is a patch against compat-wireless-2008-06-14 to work with 2.6.25.6-55.fc9.x86_64 kernel headers. I am using it right now so it works for me, YMMV.
> 
> It is mostly a patch from Herton a few months ago to add support for
> Realtek 8187B. Herton's patch was missing a little quirk change for usb endpoint 12 for management frame; and I ported it forward to current fedora 9 kernel headers. 
> 
> The rest of the story is at:
> https://bugzilla.redhat.com/show_bug.cgi?id=432280
> 
> I have a few questions during the porting:
> 
> - control->queue, which the herton's change used, for switching between 4 tramission queue at end point 6,7,5,4, has disappeared. I hard-coded 6 in this version, (see commemt #37 for background), but what's the correct
> way to do this in current wireless-2.6 code?
> 
> - compat-wireless seems to use a small inlined routine 
> from http://article.gmane.org/gmane.linux.kernel.wireless.general/15830,
> which isn't in the redhat header yet. so I have added an ifndef at
> the top of rtl8187_dev.c . so the patch needs to have that part removed
> if commited to compat-wireless.
> 
> - obviously it is getting a bit painful to forward-port the patch every time something else changes or something else changes in the header... 
> what can I do to make this go into wireless-2.6 ?

ACK, same here. I'm an owner of a 'One A110' mini-laptop (see
http://a110wiki.de/wiki/Wireless) and the situation is really getting
uncontrollable with a gazillion of tarballs and patches for the R8187B
driver floating around, all of them with small differences...

(the ID on this laptop is 0bda:8189 btw)

I'm very interested to see something get merged upstream, and I'm also
willing to test whatever needs testing on my hardware.


Thanks, Uwe.
-- 
http://www.hermann-uwe.de  | http://www.holsham-traders.de
http://www.crazy-hacks.org | http://www.unmaintained-free-software.org

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-18 22:31 ` Uwe Hermann
@ 2008-06-19  0:17   ` Hin-Tak Leung
  0 siblings, 0 replies; 18+ messages in thread
From: Hin-Tak Leung @ 2008-06-19  0:17 UTC (permalink / raw)
  To: Uwe Hermann; +Cc: herton, linux-wireless, flamingice, andreamrl, linville

(I am not on linux-wireless so please CC: me if replying)
Uwe Hermann wrote:
> On Sun, Jun 15, 2008 at 12:59:54AM +0000, Hin-Tak Leung wrote:
<snipped>
>> The rest of the story is at:
>> https://bugzilla.redhat.com/show_bug.cgi?id=432280
<snipped>
> ACK, same here. I'm an owner of a 'One A110' mini-laptop (see
> http://a110wiki.de/wiki/Wireless) and the situation is really getting
> uncontrollable with a gazillion of tarballs and patches for the R8187B
> driver floating around, all of them with small differences...
> 
> (the ID on this laptop is 0bda:8189 btw)
> 
> I'm very interested to see something get merged upstream, and I'm also
> willing to test whatever needs testing on my hardware.

Yes, this is getting out of hand! Your page actually contains a few forked
code I don't know about... I think I can summarize the situation as this:

1) there are two main branches of drivers which work to various extent with 
various kernel versions, excluding ndiswrapper usage. One is a vendor driver
(I had 1024.0822.2007, but the 1031.0125.2008 on one's web site seems to be 
newer) based on the old pre-2.6.22 stack, and Herton's rewrite based on the new 
mac80211 stack.

2) the vendor driver (and the old stack) is considered dead-end by the 
linux-wireless people; also it suffers from "bit-rot" as it is largely
unmaintained (there is no identifiable person to contact, and this is the first 
time I heard of the one's web site newer version) and can't keep up with
progress in the rest of the kernel.

3) Herton's driver (I think he didn't have the actual hardware) was missing
a couple of lines about the management frames (details in the redhat bugzilla) 
so in its original form can scan but can't associate; it was considered at one
point to be included in the kernel a few months ago. It also suffers from some
extent of bit-rot in the last couple of months. I think I am the one currently
maintaining it, and various CC: in the redhat bugzilla has reported success with
current kernel.

So I propose these steps:
1) I think Herton wrote the new code based on 1024.0822 . We need to find out
    a) any useful difference between 1024.0822 and 1031.0125
    b) did herton have any doubts, etc while looking at 1024.0822?
2) anybody wants to review the difference of my update on herton's?
    The most important and necessary part is the management frames change, the
    rest is just to cope with bit-rot; I explained that I needed to add an inline
    (which should be taken out when added to wireless-testing),  and
    I don't know where the multi-queue data structure has gone, so I have
    hardcoded 6. I am willing to answer any questions or go over why I changed
    what I have changed to stop the bit rotting going any further.

Any patch would bit-rot if it doesn't go into the rest of the wireless stack,
so we should get this done.

Hin-Tak










^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-15  0:59 [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189 Hin-Tak Leung
  2008-06-18 22:31 ` Uwe Hermann
@ 2008-06-25 14:08 ` John W. Linville
  2008-06-25 14:59   ` Larry Finger
  1 sibling, 1 reply; 18+ messages in thread
From: John W. Linville @ 2008-06-25 14:08 UTC (permalink / raw)
  To: Hin-Tak Leung; +Cc: herton, linux-wireless, flamingice, andreamrl, linville

On Sun, Jun 15, 2008 at 12:59:54AM +0000, Hin-Tak Leung wrote:
> (I am not on linux-wireless so please CC: me if replying)
> 
> This is a patch against compat-wireless-2008-06-14 to work with 2.6.25.6-55.fc9.x86_64 kernel headers. I am using it right now so it works for me, YMMV.
> 
> It is mostly a patch from Herton a few months ago to add support for
> Realtek 8187B. Herton's patch was missing a little quirk change for usb endpoint 12 for management frame; and I ported it forward to current fedora 9 kernel headers. 
> 
> The rest of the story is at:
> https://bugzilla.redhat.com/show_bug.cgi?id=432280
> 
> I have a few questions during the porting:
> 
> - control->queue, which the herton's change used, for switching between 4 tramission queue at end point 6,7,5,4, has disappeared. I hard-coded 6 in this version, (see commemt #37 for background), but what's the correct
> way to do this in current wireless-2.6 code?
> 
> - compat-wireless seems to use a small inlined routine 
> from http://article.gmane.org/gmane.linux.kernel.wireless.general/15830,
> which isn't in the redhat header yet. so I have added an ifndef at
> the top of rtl8187_dev.c . so the patch needs to have that part removed
> if commited to compat-wireless.
> 
> - obviously it is getting a bit painful to forward-port the patch every time something else changes or something else changes in the header... 
> what can I do to make this go into wireless-2.6 ?
> 
> I think I have forward-port the patch mostly correctly, but I'd like to hear about comments, etc and how to make it better...

Thanks for your effort on this issue.  I am very proud of the way you
and others have participated in improving this patch as documented
in the bugzilla link above.

I apologize for having been slow to respond but I seem to constantly
be buried in patches...  That is even more true today since I have
recently been on vacation.  Still, this patch has been languishing
in my mailbox too long!

Please review the guidelines here:

   http://linux.yyz.us/patch-format.html

If possible, please wrap your changelog comment lines at 80 columns
or less.  Also you should probably include Signed-off-by lines from
Herton and Pavel.  And please include the patch inline if possible
for easier review -- use a mailer that preserves whitespace correctly.

I may have more specific comments about the patch itself later, but now
I really need to get caught-up on some other merging.  I just wanted to
ensure that you knew I was not (completely) ignoring your efforts! :-)

Thanks,

John
-- 
John W. Linville
linville@tuxdriver.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-25 14:08 ` John W. Linville
@ 2008-06-25 14:59   ` Larry Finger
  2008-06-25 15:44     ` Hin-Tak Leung
  2008-06-26  0:26     ` Matthew Garrett
  0 siblings, 2 replies; 18+ messages in thread
From: Larry Finger @ 2008-06-25 14:59 UTC (permalink / raw)
  To: Hin-Tak Leung
  Cc: John W. Linville, herton, linux-wireless, flamingice, andreamrl,
	linville

John W. Linville wrote:
> 
> Thanks for your effort on this issue.  I am very proud of the way you
> and others have participated in improving this patch as documented
> in the bugzilla link above.
> 
> I apologize for having been slow to respond but I seem to constantly
> be buried in patches...  That is even more true today since I have
> recently been on vacation.  Still, this patch has been languishing
> in my mailbox too long!
> 
> Please review the guidelines here:
> 
>    http://linux.yyz.us/patch-format.html
> 
> If possible, please wrap your changelog comment lines at 80 columns
> or less.  Also you should probably include Signed-off-by lines from
> Herton and Pavel.  And please include the patch inline if possible
> for easier review -- use a mailer that preserves whitespace correctly.
> 
> I may have more specific comments about the patch itself later, but now
> I really need to get caught-up on some other merging.  I just wanted to
> ensure that you knew I was not (completely) ignoring your efforts! :-)

I have been using this patch on my Level 1 WNC-0301USB device. There 
are still problems with the TX code as it can associate only about 1 
try in 10, but RX seems to be fine. I have been too busy to sort out 
the problems, but I have fixed the patch to get rid of checkpatch 
warnings and errors, which includes the "Signed-off-by" lines.

Would you like me to send the updated version to you, or should I send 
it to linux-wireless and John?

Larry

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-25 14:59   ` Larry Finger
@ 2008-06-25 15:44     ` Hin-Tak Leung
  2008-06-26  0:26     ` Matthew Garrett
  1 sibling, 0 replies; 18+ messages in thread
From: Hin-Tak Leung @ 2008-06-25 15:44 UTC (permalink / raw)
  To: Larry Finger, John W. Linville
  Cc: herton, linux-wireless, flamingice, andreamrl, linville

(am still not on linux-wireless, please cc: when replying...)
Larry Finger wrote:
> John W. Linville wrote:
<snipped>
>> I may have more specific comments about the patch itself later, but now
>> I really need to get caught-up on some other merging.  I just wanted to
>> ensure that you knew I was not (completely) ignoring your efforts! :-)

Great - I have checked out the whole git of wireless-testing a few days ago
and will try to find some time to track down how some of the recent changes
elsewhere broke, and do some of the stuff 'properly'.

> I have been using this patch on my Level 1 WNC-0301USB device. There are 
> still problems with the TX code as it can associate only about 1 try in 
> 10, but RX seems to be fine. I have been too busy to sort out the 
> problems, but I have fixed the patch to get rid of checkpatch warnings 
> and errors, which includes the "Signed-off-by" lines.
> 
> Would you like me to send the updated version to you, or should I send 
> it to linux-wireless and John?

Both and/or attaching to the redhat bugzilla :-). (have as many people
seeing/testing...) There is a newer vendor driver out from the one Herton based
on, so that might fix something; also the control queue switching I mentioned in
the my forward port effort may have something to do with that.

Cheers, and looking forward to moving this forward :-).
Hin-Tak


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-25 14:59   ` Larry Finger
  2008-06-25 15:44     ` Hin-Tak Leung
@ 2008-06-26  0:26     ` Matthew Garrett
  2008-06-26  0:44       ` Hin-Tak Leung
  1 sibling, 1 reply; 18+ messages in thread
From: Matthew Garrett @ 2008-06-26  0:26 UTC (permalink / raw)
  To: Larry Finger
  Cc: Hin-Tak Leung, John W. Linville, herton, linux-wireless,
	flamingice, andreamrl, linville

On Wed, Jun 25, 2008 at 09:59:05AM -0500, Larry Finger wrote:

> Would you like me to send the updated version to you, or should I send 
> it to linux-wireless and John?

One thing I noticed is that the 0x8187 USB ID seems to be used for both 
plain and b devices, so I suspect we're going to need some more 
intelligent probing than just basing it off USB ID. IIRC, the endpoint 
descriptions are different?

-- 
Matthew Garrett | mjg59@srcf.ucam.org

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-26  0:26     ` Matthew Garrett
@ 2008-06-26  0:44       ` Hin-Tak Leung
  2008-06-26  3:41         ` Larry Finger
  0 siblings, 1 reply; 18+ messages in thread
From: Hin-Tak Leung @ 2008-06-26  0:44 UTC (permalink / raw)
  To: Larry Finger, Matthew Garrett
  Cc: John W. Linville, herton, linux-wireless, flamingice, andreamrl,
	linville

--- On Thu, 26/6/08, Matthew Garrett <mjg@redhat.com> wrote:
<snipped>
> One thing I noticed is that the 0x8187 USB ID seems to be
> used for both 
> plain and b devices, so I suspect we're going to need
> some more 
> intelligent probing than just basing it off USB ID. IIRC,
> the endpoint 
> descriptions are different?

This is my /proc/bus/usb/devices entry- anybody who has a 0x8187 which 
behaves like a 8187b posting theirs? You remember correctly - 8187 
sends through endpoint 2, 8187b uses 4,5,6,7 and 12 (0x0c). 
----------
T:  Bus=01 Lev=01 Prnt=01 Port=05 Cnt=01 Dev#=  2 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=0bda ProdID=8197 Rev= 2.00
S:  Manufacturer=Manufacturer_Realtek
S:  Product=RTL8187B_WLAN_Adapter 
S:  SerialNumber=<masked>
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA
I:* If#= 0 Alt= 0 #EPs= 9 Cls=ff(vend.) Sub=ff Prot=ff Driver=rtl8187
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
------------


      __________________________________________________________
Sent from Yahoo! Mail.
A Smarter Email http://uk.docs.yahoo.com/nowyoucan.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-26  0:44       ` Hin-Tak Leung
@ 2008-06-26  3:41         ` Larry Finger
  2008-06-26 17:22           ` Hin-Tak Leung
  0 siblings, 1 reply; 18+ messages in thread
From: Larry Finger @ 2008-06-26  3:41 UTC (permalink / raw)
  To: Hin-Tak Leung
  Cc: Matthew Garrett, John W. Linville, herton, linux-wireless,
	flamingice, andreamrl, linville

Hin-Tak Leung wrote:
> --- On Thu, 26/6/08, Matthew Garrett <mjg@redhat.com> wrote:
> <snipped>
>> One thing I noticed is that the 0x8187 USB ID seems to be
>> used for both 
>> plain and b devices, so I suspect we're going to need
>> some more 
>> intelligent probing than just basing it off USB ID. IIRC,
>> the endpoint 
>> descriptions are different?
> 
> This is my /proc/bus/usb/devices entry- anybody who has a 0x8187 which 
> behaves like a 8187b posting theirs? You remember correctly - 8187 
> sends through endpoint 2, 8187b uses 4,5,6,7 and 12 (0x0c). 
> ----------
> T:  Bus=01 Lev=01 Prnt=01 Port=05 Cnt=01 Dev#=  2 Spd=480 MxCh= 0
> D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
> P:  Vendor=0bda ProdID=8197 Rev= 2.00
> S:  Manufacturer=Manufacturer_Realtek
> S:  Product=RTL8187B_WLAN_Adapter 
> S:  SerialNumber=<masked>
> C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA
> I:* If#= 0 Alt= 0 #EPs= 9 Cls=ff(vend.) Sub=ff Prot=ff Driver=rtl8187
> E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

My device doesn't show up in /proc, but 
/sys/bus/usb/devices/1-5/product shows it to have the same Product 
string as yours, with a ProdID of 8187.

Does anyone have an 8187b with an ProdID of 0x8187 and a Product 
string that does not say 8187B?

Larry

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-26  3:41         ` Larry Finger
@ 2008-06-26 17:22           ` Hin-Tak Leung
  2008-06-26 18:33             ` Larry Finger
  0 siblings, 1 reply; 18+ messages in thread
From: Hin-Tak Leung @ 2008-06-26 17:22 UTC (permalink / raw)
  To: Larry Finger
  Cc: Matthew Garrett, John W. Linville, herton, linux-wireless,
	flamingice, andreamrl, linville



Larry Finger wrote:
> Hin-Tak Leung wrote:
>> --- On Thu, 26/6/08, Matthew Garrett <mjg@redhat.com> wrote:
<snipped>
>> E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>> E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>> E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>> E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>> E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>> E:  Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>> E:  Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>> E:  Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>> E:  Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> 
> My device doesn't show up in /proc, but /sys/bus/usb/devices/1-5/product 
> shows it to have the same Product string as yours, with a ProdID of 8187.
<snipped>

Is your usbfs mounted? you should have an entry similiar to this in your
fstab:
----------
none            /proc/bus/usb    usbfs  auto         0 0
----------
and that gives you the /proc/bus/usb/devices entries. Most userland
usb device drivers (libusb - scanners, ptp digital cameras) need the
/proc/bus/usb hierachy to work.
The usb endpoint list is a functional difference between the 8187 and 8187b.
(it runs to 0c for the 8187b, and does not have a 02 entry which the 8187 uses).



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-26 17:22           ` Hin-Tak Leung
@ 2008-06-26 18:33             ` Larry Finger
  2008-06-26 18:44               ` Pavel Roskin
  0 siblings, 1 reply; 18+ messages in thread
From: Larry Finger @ 2008-06-26 18:33 UTC (permalink / raw)
  To: Hin-Tak Leung
  Cc: Matthew Garrett, John W. Linville, herton, linux-wireless,
	flamingice, andreamrl, linville

Hin-Tak Leung wrote:
> 
> 
> Larry Finger wrote:
>> Hin-Tak Leung wrote:
>>> --- On Thu, 26/6/08, Matthew Garrett <mjg@redhat.com> wrote:
> <snipped>
>>> E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>>> E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>>> E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>>> E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>>> E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>>> E:  Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>>> E:  Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>>> E:  Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>>> E:  Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
>>
>> My device doesn't show up in /proc, but 
>> /sys/bus/usb/devices/1-5/product shows it to have the same Product 
>> string as yours, with a ProdID of 8187.
> <snipped>
> 
> Is your usbfs mounted? you should have an entry similiar to this in your
> fstab:
> ----------
> none            /proc/bus/usb    usbfs  auto         0 0
> ----------
> and that gives you the /proc/bus/usb/devices entries. Most userland
> usb device drivers (libusb - scanners, ptp digital cameras) need the
> /proc/bus/usb hierachy to work.
> The usb endpoint list is a functional difference between the 8187 and 
> 8187b.
> (it runs to 0c for the 8187b, and does not have a 02 entry which the 
> 8187 uses).

My fstab entry was set "noauto". Once it was mounted, then it shows

T:  Bus=01 Lev=01 Prnt=01 Port=04 Cnt=02 Dev#=  3 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=0bda ProdID=8187 Rev= 2.00
S:  Manufacturer=Manufacturer_Realtek
S:  Product=RTL8187B_WLAN_Adapter
S:  SerialNumber=00e04c000001
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA
I:* If#= 0 Alt= 0 #EPs= 9 Cls=ff(vend.) Sub=ff Prot=ff Driver=rtl8187
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

Do I understand correctly that it might be better to check for the 
existence of endpoint 02 for an 8187 device? Or would it be better to 
look for endpoint 12 to set it as an 8187B?

Larry


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-26 18:33             ` Larry Finger
@ 2008-06-26 18:44               ` Pavel Roskin
  2008-06-26 19:45                 ` Hin-Tak Leung
  0 siblings, 1 reply; 18+ messages in thread
From: Pavel Roskin @ 2008-06-26 18:44 UTC (permalink / raw)
  To: Larry Finger
  Cc: Hin-Tak Leung, Matthew Garrett, John W. Linville, herton,
	linux-wireless, flamingice, andreamrl, linville

On Thu, 2008-06-26 at 13:33 -0500, Larry Finger wrote:

> Do I understand correctly that it might be better to check for the 
> existence of endpoint 02 for an 8187 device? Or would it be better to 
> look for endpoint 12 to set it as an 8187B?

It's probably OK either way, but I would look at some number that takes
more than just 2 values (true and false).  Say, the number of endpoints
would be such number.  This way, it there is some elusive 8187A or
8187C, it may have a different number and won't be mistaken for known
chipsets.

Of course, we cannot guarantee anything.  It's just a matter of general
sanity that may or may not help.  But sometimes it helps.

-- 
Regards,
Pavel Roskin

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-26 18:44               ` Pavel Roskin
@ 2008-06-26 19:45                 ` Hin-Tak Leung
  2008-06-26 20:40                   ` Herton Ronaldo Krzesinski
  2008-06-26 20:44                   ` Larry Finger
  0 siblings, 2 replies; 18+ messages in thread
From: Hin-Tak Leung @ 2008-06-26 19:45 UTC (permalink / raw)
  To: Pavel Roskin
  Cc: Larry Finger, Matthew Garrett, John W. Linville, herton,
	linux-wireless, flamingice, andreamrl, linville

Pavel Roskin wrote:
> On Thu, 2008-06-26 at 13:33 -0500, Larry Finger wrote:
> 
>> Do I understand correctly that it might be better to check for the 
>> existence of endpoint 02 for an 8187 device? Or would it be better to 
>> look for endpoint 12 to set it as an 8187B?
> 
> It's probably OK either way, but I would look at some number that takes
> more than just 2 values (true and false).  Say, the number of endpoints
> would be such number.  This way, it there is some elusive 8187A or
> 8187C, it may have a different number and won't be mistaken for known
> chipsets.
> 
> Of course, we cannot guarantee anything.  It's just a matter of general
> sanity that may or may not help.  But sometimes it helps.

Larry's 8187 indeed looks like a 8187B i.e. the OEM being naughty and needs
some serious lashing there... where does it come from - what brand and what
is it bundled with?

The 8187/8187b code actually *uses* the
endpoints to send management frames for association - that's a functional 
difference and it is not possible to drive a 8187 as if it is a 8187b or
vice versa. In the absence of
more authoritative answers like reading from a register or something, counting
the endpoints - I would actually go a bit further and demand the used endpoints
being there and in the right direction and propertes (int/bulk) - would seem
to be a good idea. As for what to do "if things don't add up", at least a 
warning through dmesg "give the OEM some lashing for calling a 8187b 0x8187".

I think Larry's question could be re-phrased as: if there is a preculiar device
with *both* end point 2 and endpoint 12, what to treat it as?

I would be inclined to treat it as the newer chip - but some big warning, or
even refusing to carry on, is probably in order.

Herton's code also seem to distinguish revC/revD/revE of different 8187B's -
I don't seem to have seen those distinctions in the original vendor code, but
maybe I haven't look hard enough :-).


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-26 19:45                 ` Hin-Tak Leung
@ 2008-06-26 20:40                   ` Herton Ronaldo Krzesinski
  2008-06-26 21:24                     ` Herton Ronaldo Krzesinski
  2008-06-26 20:44                   ` Larry Finger
  1 sibling, 1 reply; 18+ messages in thread
From: Herton Ronaldo Krzesinski @ 2008-06-26 20:40 UTC (permalink / raw)
  To: Hin-Tak Leung
  Cc: Pavel Roskin, Larry Finger, Matthew Garrett, John W. Linville,
	linux-wireless, flamingice, andreamrl, linville

Em Thursday 26 June 2008 16:45:34 Hin-Tak Leung escreveu:
> Pavel Roskin wrote:
> > On Thu, 2008-06-26 at 13:33 -0500, Larry Finger wrote:
> >> Do I understand correctly that it might be better to check for the
> >> existence of endpoint 02 for an 8187 device? Or would it be better to
> >> look for endpoint 12 to set it as an 8187B?
> >
> > It's probably OK either way, but I would look at some number that takes
> > more than just 2 values (true and false).  Say, the number of endpoints
> > would be such number.  This way, it there is some elusive 8187A or
> > 8187C, it may have a different number and won't be mistaken for known
> > chipsets.
> >
> > Of course, we cannot guarantee anything.  It's just a matter of general
> > sanity that may or may not help.  But sometimes it helps.
>
> Larry's 8187 indeed looks like a 8187B i.e. the OEM being naughty and needs
> some serious lashing there... where does it come from - what brand and what
> is it bundled with?
>
> The 8187/8187b code actually *uses* the
> endpoints to send management frames for association - that's a functional
> difference and it is not possible to drive a 8187 as if it is a 8187b or
> vice versa. In the absence of
> more authoritative answers like reading from a register or something,
> counting the endpoints - I would actually go a bit further and demand the
> used endpoints being there and in the right direction and propertes
> (int/bulk) - would seem to be a good idea. As for what to do "if things
> don't add up", at least a warning through dmesg "give the OEM some lashing
> for calling a 8187b 0x8187".
>
> I think Larry's question could be re-phrased as: if there is a preculiar
> device with *both* end point 2 and endpoint 12, what to treat it as?
>
> I would be inclined to treat it as the newer chip - but some big warning,
> or even refusing to carry on, is probably in order.
>
> Herton's code also seem to distinguish revC/revD/revE of different 8187B's
> - I don't seem to have seen those distinctions in the original vendor code,
> but maybe I haven't look hard enough :-).

The vendor driver I have here uses this revision information of 8187B inside 
rtl8225z2_SetTXPowerLevel function, for changing of radio registers. Do you 
have this too? It only checks if it's a 8187B of revB or not.

Also not using endpoint 12 for management frames was indeed a bug in original 
patch. As a curious thing, I tried too to debug the rtl8187b using the 
windows driver under ndiswrapper while analysing the traffic of commands with 
usbmon, I noted that the windows driver does a different setup, in fact the 
initialization is almost the same but later it starts to write data to index 
1304, ie:

c6d1eb80 286218884 S Co:1:003:0 s 40 04 0000 1304 0002 2 = 700b
c6d1eb80 286219207 C Co:1:003:0 0 2 >
c6d1eb80 286220241 S Co:1:003:0 s 40 04 0000 1304 0002 2 = 01ee
c6d1eb80 286220583 C Co:1:003:0 0 2 >
c6d1eb80 286221617 S Co:1:003:0 s 40 04 0000 1304 0002 2 = d244
c6d1eb80 286221957 C Co:1:003:0 0 2 >
c6d1eb80 286222990 S Co:1:003:0 s 40 04 0000 1304 0002 2 = 1344
c6d1eb80 286223330 C Co:1:003:0 0 2 >

The linux driver from realtek doesn't do this until where I could see. I tried 
to emulate the same behaviour but didn't got good results so I dropped it. 
Also when debugging this and checking registers I noticed other small errors 
in original patch too, the following is not a ready to apply patch (and not
diffed against latest wireless-testing), just to get the idea and I'll comment
the parts:

diff -p -up linux-2.6.24/drivers/net/wireless/rtl8187.h.orig linux-2.6.24/drivers/net/wireless/rtl8187.h
--- linux-2.6.24/drivers/net/wireless/rtl8187.h.orig	2008-06-25 13:22:17.000000000 -0400
+++ linux-2.6.24/drivers/net/wireless/rtl8187.h	2008-06-25 13:22:54.000000000 -0400
@@ -76,7 +76,7 @@ struct rtl8187_tx_hdr {
 struct rtl8187b_tx_hdr {
 	__le32 flags;
 	__le16 rts_duration;
-	__le16 len;
+	__le16 plcp_len;
 	__le32 unused_1;
 	__le16 unused_2;
 	__le16 tx_duration;
diff -p -up linux-2.6.24/drivers/net/wireless/rtl8187_dev.c.orig linux-2.6.24/drivers/net/wireless/rtl8187_dev.c
--- linux-2.6.24/drivers/net/wireless/rtl8187_dev.c.orig	2008-06-25 13:24:34.000000000 -0400
+++ linux-2.6.24/drivers/net/wireless/rtl8187_dev.c	2008-06-25 15:25:07.000000000 -0400
@@ -377,8 +377,8 @@ static int rtl8187_init_hw(struct ieee80
 	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_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
+	rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8187_RTL8225_ANAPARAM_ON);
+	rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8187_RTL8225_ANAPARAM2_ON);
 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
@@ -397,8 +397,8 @@ static int rtl8187_init_hw(struct ieee80
 	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_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
+	rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8187_RTL8225_ANAPARAM_ON);
+	rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8187_RTL8225_ANAPARAM2_ON);
 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
@@ -506,9 +506,9 @@ static int rtl8187b_init_hw(struct ieee8
 	reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
 	reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT;
 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
-	rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, 0x727f3f52);
-	rtl818x_iowrite32(priv, &priv->map->ANAPARAM, 0x45090658);
-	rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, 0);
+	rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8187B_RTL8225_ANAPARAM2_ON);
+	rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8187B_RTL8225_ANAPARAM_ON);
+	rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, RTL8187B_RTL8225_ANAPARAM3_ON);
 
 	rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10);
 	reg = rtl818x_ioread8(priv, (u8 *)0xFF62);
@@ -566,6 +566,8 @@ static int rtl8187b_init_hw(struct ieee8
 
 	rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001);
 
+	rtl818x_iowrite8_idx(priv, (u8 *)0xFF4E, 1, 2);
+
 	rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2);
 
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
diff -p -up linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.c.orig linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.c
--- linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.c.orig	2008-06-25 13:28:37.000000000 -0400
+++ linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.c	2008-06-25 15:29:33.000000000 -0400
@@ -306,7 +306,7 @@ void rtl8225_rf_set_tx_power(struct ieee
 	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->ANAPARAM2, RTL8225_ANAPARAM2_ON);
+	rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8187_RTL8225_ANAPARAM2_ON);
 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
@@ -489,10 +489,10 @@ static const u8 rtl8225z2_ofdm[] = {
 	0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
 	0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
 	0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
-	0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
+	0x0a, 0xe1, 0x2c, 0x4a, 0x86, 0x83, 0x34, 0x0f,
 	0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
 	0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
-	0x6d, 0x3c, 0xfb, 0x07
+	0x6d, 0x3c, 0xfb, 0xc7
 };
 
 static const u8 rtl8225z2_tx_power_cck_ch14[] = {
@@ -557,7 +557,7 @@ void rtl8225z2_8187_rf_set_tx_power(stru
 	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->ANAPARAM2, RTL8225_ANAPARAM2_ON);
+	rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8187_RTL8225_ANAPARAM2_ON);
 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
@@ -866,7 +866,7 @@ void rtl8225z2_8187b_rf_init(struct ieee
 
 	rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03);
 	rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07);
-	rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
+	rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); msleep(1);
 
 	rtl8225_write_phy_ofdm(dev, 0x80, 0x12);
 	for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) {
@@ -879,6 +879,10 @@ void rtl8225z2_8187b_rf_init(struct ieee
 	for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++) {
 		rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]);
 	}
+	rtl8225_write_phy_cck(dev, 0xc1, 0x88); msleep(1);
+	rtl8225_write_phy_ofdm(dev, 0x97, 0x46); msleep(1);
+	rtl8225_write_phy_ofdm(dev, 0xa4, 0x86); msleep(1);
+	rtl8225_write_phy_ofdm(dev, 0x85, 0xfb); msleep(1);
 
 	rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
 	rtl818x_iowrite8(priv, &priv->map->SLOT, 9);
@@ -889,15 +893,13 @@ void rtl8225z2_8187b_rf_init(struct ieee
 	rtl818x_iowrite8(priv, (u8 *)0xFF2D, 0x5B);
 	rtl818x_iowrite8(priv, (u8 *)0xFF79, 0x5B);
 	rtl818x_iowrite32(priv, (__le32 *)0xFFF0, (7 << 12) | (3 << 8) | 28);
+	rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
 	rtl818x_iowrite32(priv, (__le32 *)0xFFF4, (7 << 12) | (3 << 8) | 28);
+	rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
 	rtl818x_iowrite32(priv, (__le32 *)0xFFF8, (7 << 12) | (3 << 8) | 28);
+	rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
 	rtl818x_iowrite32(priv, (__le32 *)0xFFFC, (7 << 12) | (3 << 8) | 28);
 	rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
-
-	rtl8225_write_phy_ofdm(dev, 0x97, 0x46); msleep(1);
-	rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6); msleep(1);
-	rtl8225_write_phy_ofdm(dev, 0x85, 0xfc); msleep(1);
-	rtl8225_write_phy_cck(dev, 0xc1, 0x88); msleep(1);
 }
 
 void rtl8225_rf_stop(struct ieee80211_hw *dev)
@@ -910,8 +912,19 @@ void rtl8225_rf_stop(struct ieee80211_hw
 	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->ANAPARAM2, RTL8225_ANAPARAM2_OFF);
-	rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF);
+	if (!priv->is_rtl8187b) {
+		rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
+				  RTL8187_RTL8225_ANAPARAM2_OFF);
+		rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
+				  RTL8187_RTL8225_ANAPARAM_OFF);
+	} else {
+		rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
+				  RTL8187B_RTL8225_ANAPARAM2_OFF);
+		rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
+				  RTL8187B_RTL8225_ANAPARAM_OFF);
+		rtl818x_iowrite32(priv, &priv->map->ANAPARAM3,
+				  RTL8187B_RTL8225_ANAPARAM3_OFF);
+	}
 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 }
diff -p -up linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.h.orig linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.h
--- linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.h.orig	2008-06-25 15:13:28.000000000 -0400
+++ linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.h	2008-06-25 15:20:41.000000000 -0400
@@ -15,10 +15,17 @@
 #ifndef RTL8187_RTL8225_H
 #define RTL8187_RTL8225_H
 
-#define RTL8225_ANAPARAM_ON	0xa0000a59
-#define RTL8225_ANAPARAM2_ON	0x860c7312
-#define RTL8225_ANAPARAM_OFF	0xa00beb59
-#define RTL8225_ANAPARAM2_OFF	0x840dec11
+#define RTL8187_RTL8225_ANAPARAM_ON	0xa0000a59
+#define RTL8187_RTL8225_ANAPARAM2_ON	0x860c7312
+#define RTL8187_RTL8225_ANAPARAM_OFF	0xa00beb59
+#define RTL8187_RTL8225_ANAPARAM2_OFF	0x840dec11
+
+#define RTL8187B_RTL8225_ANAPARAM_ON	0x45090658
+#define RTL8187B_RTL8225_ANAPARAM2_ON	0x727f3f52
+#define RTL8187B_RTL8225_ANAPARAM3_ON	0x00
+#define RTL8187B_RTL8225_ANAPARAM_OFF	0x55480658
+#define RTL8187B_RTL8225_ANAPARAM2_OFF	0x72003f50
+#define RTL8187B_RTL8225_ANAPARAM3_OFF	0x00
 
 void rtl8225_write(struct ieee80211_hw *, u8 addr, u16 data);
 u16  rtl8225_read(struct ieee80211_hw *, u8 addr);


There are main 6 changes on the diff above:

- len is probably plcp_len field like on r818{0,5}, on vendor driver it was
specified as 'length'
- To turn ANAPARAM off we need especial value like when turning on, for
ANAPARAM*_OFF values I used the stock values from the hardware after
a cold boot
- The write to the address 0xFFF0 seems to need always a write to ACM_CONTROL
after this with value '0', the vendor driver both on win/linux does this, was
another mistake that I didn't see:
 	rtl818x_iowrite32(priv, (__le32 *)0xFFF0, (7 << 12) | (3 << 8) | 28);
+	rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);

- Win driver writes to 0xFF4E and , so I added the same thing:
+	rtl818x_iowrite8_idx(priv, (u8 *)0xFF4E, 1, 2);
and does things in another order, so I moved code:
+	rtl8225_write_phy_cck(dev, 0xc1, 0x88); msleep(1);
+	rtl8225_write_phy_ofdm(dev, 0x97, 0x46); msleep(1);
+	rtl8225_write_phy_ofdm(dev, 0xa4, 0x86); msleep(1);
+	rtl8225_write_phy_ofdm(dev, 0x85, 0xfb); msleep(1);

- I changed "static const u8 rtl8225z2_ofdm[]" because of when looking the usb
traffic with usbmon and ndiswrapper it was different in that values, the win
driver has the values.
- I placed msleep(1) after write TX_ANTENNA, as all already in kernel realtek
code need this why rtl8187b does not? Better to play safe.

As I don't have docs I have to appeal to this kind of things... sorry for the
everything in one patch, I wasn't available to look more into this, but better
post what I have found until now.

-- 
[]'s
Herton

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-26 19:45                 ` Hin-Tak Leung
  2008-06-26 20:40                   ` Herton Ronaldo Krzesinski
@ 2008-06-26 20:44                   ` Larry Finger
  2008-06-26 21:15                     ` Herton Ronaldo Krzesinski
  1 sibling, 1 reply; 18+ messages in thread
From: Larry Finger @ 2008-06-26 20:44 UTC (permalink / raw)
  To: Hin-Tak Leung
  Cc: Pavel Roskin, Matthew Garrett, John W. Linville, herton,
	linux-wireless, flamingice, andreamrl, linville

Hin-Tak Leung wrote:
> Pavel Roskin wrote:
>> On Thu, 2008-06-26 at 13:33 -0500, Larry Finger wrote:
>>
>>> Do I understand correctly that it might be better to check for the 
>>> existence of endpoint 02 for an 8187 device? Or would it be better to 
>>> look for endpoint 12 to set it as an 8187B?
>>
>> It's probably OK either way, but I would look at some number that takes
>> more than just 2 values (true and false).  Say, the number of endpoints
>> would be such number.  This way, it there is some elusive 8187A or
>> 8187C, it may have a different number and won't be mistaken for known
>> chipsets.
>>
>> Of course, we cannot guarantee anything.  It's just a matter of general
>> sanity that may or may not help.  But sometimes it helps.
> 
> Larry's 8187 indeed looks like a 8187B i.e. the OEM being naughty and needs
> some serious lashing there... where does it come from - what brand and what
> is it bundled with?

It is a Level One WNC-0301USB dongle. I bought it as an interim 
replacement when the PCIe interface in my laptop expired and I could 
not get it fixed at that time. I was quite put out when Linux couldn't 
drive it as I needed Linux for my E-mail and it had to be wireless. I 
tried ndiswrapper with it, but that didn't work either. I finally 
settled on running Windows XP with Linux as a virtual machine running 
under VirtualBox. It wasn't pretty, but it worked.

> The 8187/8187b code actually *uses* the
> endpoints to send management frames for association - that's a 
> functional difference and it is not possible to drive a 8187 as if it is 
> a 8187b or
> vice versa. In the absence of
> more authoritative answers like reading from a register or something, 
> counting
> the endpoints - I would actually go a bit further and demand the used 
> endpoints
> being there and in the right direction and propertes (int/bulk) - would 
> seem
> to be a good idea. As for what to do "if things don't add up", at least 
> a warning through dmesg "give the OEM some lashing for calling a 8187b 
> 0x8187".


Good idea. It probably won't change anything other than make us feel good.


> I think Larry's question could be re-phrased as: if there is a preculiar 
> device
> with *both* end point 2 and endpoint 12, what to treat it as?
> 
> I would be inclined to treat it as the newer chip - but some big 
> warning, or
> even refusing to carry on, is probably in order.


I will prepare a patch with these warnings.


> Herton's code also seem to distinguish revC/revD/revE of different 
> 8187B's -
> I don't seem to have seen those distinctions in the original vendor 
> code, but
> maybe I haven't look hard enough :-).

I have not found them either. FWIW, my device is reported as 
RTL8187BvE V0 + rtl8225z2. The decision comes from 
rtl818x_ioread8(priv, (u8 *)0xFFE1), but I don't know what is at that 
address.

Larry

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-26 20:44                   ` Larry Finger
@ 2008-06-26 21:15                     ` Herton Ronaldo Krzesinski
  0 siblings, 0 replies; 18+ messages in thread
From: Herton Ronaldo Krzesinski @ 2008-06-26 21:15 UTC (permalink / raw)
  To: Larry Finger
  Cc: Hin-Tak Leung, Pavel Roskin, Matthew Garrett, John W. Linville,
	linux-wireless, flamingice, andreamrl, linville

Em Thursday 26 June 2008 17:44:43 Larry Finger escreveu:
> Hin-Tak Leung wrote:
<snip>
> 
> > Herton's code also seem to distinguish revC/revD/revE of different 
> > 8187B's -
> > I don't seem to have seen those distinctions in the original vendor 
> > code, but
> > maybe I haven't look hard enough :-).
> 
> I have not found them either. FWIW, my device is reported as 
> RTL8187BvE V0 + rtl8225z2. The decision comes from 
> rtl818x_ioread8(priv, (u8 *)0xFFE1), but I don't know what is at that 
> address.

In the vendor driver this is commented as being the 8187B hardware version
register (it's a raw value address used in the code with a comment). I should
have commented the line as something like "read 8187b hardware version
register", or may be add a field to struct rtl818x_csr. One more thing to add
to the patch. In fact I would like to have a datasheet or ask to someone that
has to confirm this.

> 
> Larry
> 

--
[]'s
Herton

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-26 20:40                   ` Herton Ronaldo Krzesinski
@ 2008-06-26 21:24                     ` Herton Ronaldo Krzesinski
  2008-06-26 21:53                       ` Larry Finger
  0 siblings, 1 reply; 18+ messages in thread
From: Herton Ronaldo Krzesinski @ 2008-06-26 21:24 UTC (permalink / raw)
  To: Hin-Tak Leung
  Cc: Pavel Roskin, Larry Finger, Matthew Garrett, John W. Linville,
	linux-wireless, flamingice, andreamrl, linville

Small corrections to last message:

Em Thursday 26 June 2008 17:40:09 Herton Ronaldo Krzesinski escreveu:
> 
> There are main 6 changes on the diff above:
> 
> - len is probably plcp_len field like on r818{0,5}, on vendor driver it was
> specified as 'length'
> - To turn ANAPARAM off we need especial value like when turning on, for
> ANAPARAM*_OFF values I used the stock values from the hardware after
> a cold boot
> - The write to the address 0xFFF0 seems to need always a write to ACM_CONTROL

I mean 0xFFF0 to 0xFFFC

> after this with value '0', the vendor driver both on win/linux does this, was
> another mistake that I didn't see:
>  	rtl818x_iowrite32(priv, (__le32 *)0xFFF0, (7 << 12) | (3 << 8) | 28);
> +	rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
> 
> - Win driver writes to 0xFF4E and , so I added the same thing:

"- Win driver writes to 0xFF4E, so I added the same thing:"

> +	rtl818x_iowrite8_idx(priv, (u8 *)0xFF4E, 1, 2);
> and does things in another order, so I moved code:
> +	rtl8225_write_phy_cck(dev, 0xc1, 0x88); msleep(1);
> +	rtl8225_write_phy_ofdm(dev, 0x97, 0x46); msleep(1);
> +	rtl8225_write_phy_ofdm(dev, 0xa4, 0x86); msleep(1);
> +	rtl8225_write_phy_ofdm(dev, 0x85, 0xfb); msleep(1);
> 
> - I changed "static const u8 rtl8225z2_ofdm[]" because of when looking the usb
> traffic with usbmon and ndiswrapper it was different in that values, the win
> driver has the values.

"- I changed "static const u8 rtl8225z2_ofdm[]" because of when looking the usb
 traffic with usbmon and ndiswrapper it was different in that values" (drop last sentence)

> - I placed msleep(1) after write TX_ANTENNA, as all already in kernel realtek
> code need this why rtl8187b does not? Better to play safe.
> 
> As I don't have docs I have to appeal to this kind of things... sorry for the
> everything in one patch, I wasn't available to look more into this, but better
> post what I have found until now.
> 

-- 
[]'s
Herton

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189
  2008-06-26 21:24                     ` Herton Ronaldo Krzesinski
@ 2008-06-26 21:53                       ` Larry Finger
  0 siblings, 0 replies; 18+ messages in thread
From: Larry Finger @ 2008-06-26 21:53 UTC (permalink / raw)
  To: Herton Ronaldo Krzesinski
  Cc: Hin-Tak Leung, Pavel Roskin, Matthew Garrett, John W. Linville,
	linux-wireless, flamingice, andreamrl, linville

Herton Ronaldo Krzesinski wrote:
> Small corrections to last message:
> 
> Em Thursday 26 June 2008 17:40:09 Herton Ronaldo Krzesinski escreveu:
>> There are main 6 changes on the diff above:
>>
>> - len is probably plcp_len field like on r818{0,5}, on vendor driver it was
>> specified as 'length'
>> - To turn ANAPARAM off we need especial value like when turning on, for
>> ANAPARAM*_OFF values I used the stock values from the hardware after
>> a cold boot
>> - The write to the address 0xFFF0 seems to need always a write to ACM_CONTROL
> 
> I mean 0xFFF0 to 0xFFFC
> 
>> after this with value '0', the vendor driver both on win/linux does this, was
>> another mistake that I didn't see:
>>  	rtl818x_iowrite32(priv, (__le32 *)0xFFF0, (7 << 12) | (3 << 8) | 28);
>> +	rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
>>
>> - Win driver writes to 0xFF4E and , so I added the same thing:
> 
> "- Win driver writes to 0xFF4E, so I added the same thing:"
> 
>> +	rtl818x_iowrite8_idx(priv, (u8 *)0xFF4E, 1, 2);
>> and does things in another order, so I moved code:
>> +	rtl8225_write_phy_cck(dev, 0xc1, 0x88); msleep(1);
>> +	rtl8225_write_phy_ofdm(dev, 0x97, 0x46); msleep(1);
>> +	rtl8225_write_phy_ofdm(dev, 0xa4, 0x86); msleep(1);
>> +	rtl8225_write_phy_ofdm(dev, 0x85, 0xfb); msleep(1);
>>
>> - I changed "static const u8 rtl8225z2_ofdm[]" because of when looking the usb
>> traffic with usbmon and ndiswrapper it was different in that values, the win
>> driver has the values.
> 
> "- I changed "static const u8 rtl8225z2_ofdm[]" because of when looking the usb
>  traffic with usbmon and ndiswrapper it was different in that values" (drop last sentence)
> 
>> - I placed msleep(1) after write TX_ANTENNA, as all already in kernel realtek
>> code need this why rtl8187b does not? Better to play safe.
>>
>> As I don't have docs I have to appeal to this kind of things... sorry for the
>> everything in one patch, I wasn't available to look more into this, but better
>> post what I have found until now.

I have put your patch into the wireless-testing code. So far, I have 
not seen any particular improvement in the performance, etc. of the 
device, but I'll continue to play with it.

Larry

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2008-06-26 21:52 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-15  0:59 [RFC][PATCH] Realtek 8187B wireless support with product id 0x8197/0x8189 Hin-Tak Leung
2008-06-18 22:31 ` Uwe Hermann
2008-06-19  0:17   ` Hin-Tak Leung
2008-06-25 14:08 ` John W. Linville
2008-06-25 14:59   ` Larry Finger
2008-06-25 15:44     ` Hin-Tak Leung
2008-06-26  0:26     ` Matthew Garrett
2008-06-26  0:44       ` Hin-Tak Leung
2008-06-26  3:41         ` Larry Finger
2008-06-26 17:22           ` Hin-Tak Leung
2008-06-26 18:33             ` Larry Finger
2008-06-26 18:44               ` Pavel Roskin
2008-06-26 19:45                 ` Hin-Tak Leung
2008-06-26 20:40                   ` Herton Ronaldo Krzesinski
2008-06-26 21:24                     ` Herton Ronaldo Krzesinski
2008-06-26 21:53                       ` Larry Finger
2008-06-26 20:44                   ` Larry Finger
2008-06-26 21:15                     ` Herton Ronaldo Krzesinski

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).