Move all rtl818x files to a common directory.
This change improves the maintainability of these drivers. No functionality is changed. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:

committato da
John W. Linville

parent
55b3961953
commit
1c740ed221
7
drivers/net/wireless/rtl818x/Makefile
Normal file
7
drivers/net/wireless/rtl818x/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
|
||||
rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
|
||||
|
||||
obj-$(CONFIG_RTL8180) += rtl8180.o
|
||||
obj-$(CONFIG_RTL8187) += rtl8187.o
|
||||
|
||||
|
120
drivers/net/wireless/rtl818x/rtl8180.h
Normal file
120
drivers/net/wireless/rtl818x/rtl8180.h
Normal file
@@ -0,0 +1,120 @@
|
||||
#ifndef RTL8180_H
|
||||
#define RTL8180_H
|
||||
|
||||
#include "rtl818x.h"
|
||||
|
||||
#define MAX_RX_SIZE IEEE80211_MAX_RTS_THRESHOLD
|
||||
|
||||
#define RF_PARAM_ANALOGPHY (1 << 0)
|
||||
#define RF_PARAM_ANTBDEFAULT (1 << 1)
|
||||
#define RF_PARAM_CARRIERSENSE1 (1 << 2)
|
||||
#define RF_PARAM_CARRIERSENSE2 (1 << 3)
|
||||
|
||||
#define BB_ANTATTEN_CHAN14 0x0C
|
||||
#define BB_ANTENNA_B 0x40
|
||||
|
||||
#define BB_HOST_BANG (1 << 30)
|
||||
#define BB_HOST_BANG_EN (1 << 2)
|
||||
#define BB_HOST_BANG_CLK (1 << 1)
|
||||
#define BB_HOST_BANG_DATA 1
|
||||
|
||||
#define ANAPARAM_TXDACOFF_SHIFT 27
|
||||
#define ANAPARAM_PWR0_SHIFT 28
|
||||
#define ANAPARAM_PWR0_MASK (0x07 << ANAPARAM_PWR0_SHIFT)
|
||||
#define ANAPARAM_PWR1_SHIFT 20
|
||||
#define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT)
|
||||
|
||||
struct rtl8180_tx_desc {
|
||||
__le32 flags;
|
||||
__le16 rts_duration;
|
||||
__le16 plcp_len;
|
||||
__le32 tx_buf;
|
||||
__le32 frame_len;
|
||||
__le32 next_tx_desc;
|
||||
u8 cw;
|
||||
u8 retry_limit;
|
||||
u8 agc;
|
||||
u8 flags2;
|
||||
u32 reserved[2];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rtl8180_rx_desc {
|
||||
__le32 flags;
|
||||
__le32 flags2;
|
||||
union {
|
||||
__le32 rx_buf;
|
||||
__le64 tsft;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rtl8180_tx_ring {
|
||||
struct rtl8180_tx_desc *desc;
|
||||
dma_addr_t dma;
|
||||
unsigned int idx;
|
||||
unsigned int entries;
|
||||
struct sk_buff_head queue;
|
||||
};
|
||||
|
||||
struct rtl8180_priv {
|
||||
/* common between rtl818x drivers */
|
||||
struct rtl818x_csr __iomem *map;
|
||||
const struct rtl818x_rf_ops *rf;
|
||||
struct ieee80211_vif *vif;
|
||||
int mode;
|
||||
|
||||
/* rtl8180 driver specific */
|
||||
spinlock_t lock;
|
||||
struct rtl8180_rx_desc *rx_ring;
|
||||
dma_addr_t rx_ring_dma;
|
||||
unsigned int rx_idx;
|
||||
struct sk_buff *rx_buf[32];
|
||||
struct rtl8180_tx_ring tx_ring[4];
|
||||
struct ieee80211_channel channels[14];
|
||||
struct ieee80211_rate rates[12];
|
||||
struct ieee80211_supported_band band;
|
||||
struct pci_dev *pdev;
|
||||
u32 rx_conf;
|
||||
|
||||
int r8185;
|
||||
u32 anaparam;
|
||||
u16 rfparam;
|
||||
u8 csthreshold;
|
||||
};
|
||||
|
||||
void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
|
||||
void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam);
|
||||
|
||||
static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr)
|
||||
{
|
||||
return ioread8(addr);
|
||||
}
|
||||
|
||||
static inline u16 rtl818x_ioread16(struct rtl8180_priv *priv, __le16 __iomem *addr)
|
||||
{
|
||||
return ioread16(addr);
|
||||
}
|
||||
|
||||
static inline u32 rtl818x_ioread32(struct rtl8180_priv *priv, __le32 __iomem *addr)
|
||||
{
|
||||
return ioread32(addr);
|
||||
}
|
||||
|
||||
static inline void rtl818x_iowrite8(struct rtl8180_priv *priv,
|
||||
u8 __iomem *addr, u8 val)
|
||||
{
|
||||
iowrite8(val, addr);
|
||||
}
|
||||
|
||||
static inline void rtl818x_iowrite16(struct rtl8180_priv *priv,
|
||||
__le16 __iomem *addr, u16 val)
|
||||
{
|
||||
iowrite16(val, addr);
|
||||
}
|
||||
|
||||
static inline void rtl818x_iowrite32(struct rtl8180_priv *priv,
|
||||
__le32 __iomem *addr, u32 val)
|
||||
{
|
||||
iowrite32(val, addr);
|
||||
}
|
||||
|
||||
#endif /* RTL8180_H */
|
1081
drivers/net/wireless/rtl818x/rtl8180_dev.c
Normal file
1081
drivers/net/wireless/rtl818x/rtl8180_dev.c
Normal file
File diff soppresso perché troppo grande
Carica Diff
180
drivers/net/wireless/rtl818x/rtl8180_grf5101.c
Normal file
180
drivers/net/wireless/rtl818x/rtl8180_grf5101.c
Normal file
@@ -0,0 +1,180 @@
|
||||
|
||||
/*
|
||||
* Radio tuning for GCT GRF5101 on RTL8180
|
||||
*
|
||||
* Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Code from the BSD driver and the rtl8181 project have been
|
||||
* very useful to understand certain things
|
||||
*
|
||||
* I want to thanks the Authors of such projects and the Ndiswrapper
|
||||
* project Authors.
|
||||
*
|
||||
* A special Big Thanks also is for all people who donated me cards,
|
||||
* making possible the creation of the original rtl8180 driver
|
||||
* from which this code is derived!
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "rtl8180.h"
|
||||
#include "rtl8180_grf5101.h"
|
||||
|
||||
static const int grf5101_encode[] = {
|
||||
0x0, 0x8, 0x4, 0xC,
|
||||
0x2, 0xA, 0x6, 0xE,
|
||||
0x1, 0x9, 0x5, 0xD,
|
||||
0x3, 0xB, 0x7, 0xF
|
||||
};
|
||||
|
||||
static void write_grf5101(struct ieee80211_hw *dev, u8 addr, u32 data)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u32 phy_config;
|
||||
|
||||
phy_config = grf5101_encode[(data >> 8) & 0xF];
|
||||
phy_config |= grf5101_encode[(data >> 4) & 0xF] << 4;
|
||||
phy_config |= grf5101_encode[data & 0xF] << 8;
|
||||
phy_config |= grf5101_encode[(addr >> 1) & 0xF] << 12;
|
||||
phy_config |= (addr & 1) << 16;
|
||||
phy_config |= grf5101_encode[(data & 0xf000) >> 12] << 24;
|
||||
|
||||
/* MAC will bang bits to the chip */
|
||||
phy_config |= 0x90000000;
|
||||
|
||||
rtl818x_iowrite32(priv,
|
||||
(__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
|
||||
|
||||
msleep(3);
|
||||
}
|
||||
|
||||
static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u8 ant = GRF5101_ANTENNA;
|
||||
|
||||
if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
|
||||
ant |= BB_ANTENNA_B;
|
||||
|
||||
if (chan == 14)
|
||||
ant |= BB_ANTATTEN_CHAN14;
|
||||
|
||||
rtl8180_write_phy(dev, 0x10, ant);
|
||||
}
|
||||
|
||||
static void grf5101_rf_set_channel(struct ieee80211_hw *dev,
|
||||
struct ieee80211_conf *conf)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
|
||||
u32 txpw = priv->channels[channel - 1].hw_value & 0xFF;
|
||||
u32 chan = channel - 1;
|
||||
|
||||
/* set TX power */
|
||||
write_grf5101(dev, 0x15, 0x0);
|
||||
write_grf5101(dev, 0x06, txpw);
|
||||
write_grf5101(dev, 0x15, 0x10);
|
||||
write_grf5101(dev, 0x15, 0x0);
|
||||
|
||||
/* set frequency */
|
||||
write_grf5101(dev, 0x07, 0x0);
|
||||
write_grf5101(dev, 0x0B, chan);
|
||||
write_grf5101(dev, 0x07, 0x1000);
|
||||
|
||||
grf5101_write_phy_antenna(dev, channel);
|
||||
}
|
||||
|
||||
static void grf5101_rf_stop(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u32 anaparam;
|
||||
|
||||
anaparam = priv->anaparam;
|
||||
anaparam &= 0x000fffff;
|
||||
anaparam |= 0x3f900000;
|
||||
rtl8180_set_anaparam(priv, anaparam);
|
||||
|
||||
write_grf5101(dev, 0x07, 0x0);
|
||||
write_grf5101(dev, 0x1f, 0x45);
|
||||
write_grf5101(dev, 0x1f, 0x5);
|
||||
write_grf5101(dev, 0x00, 0x8e4);
|
||||
}
|
||||
|
||||
static void grf5101_rf_init(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
|
||||
rtl8180_set_anaparam(priv, priv->anaparam);
|
||||
|
||||
write_grf5101(dev, 0x1f, 0x0);
|
||||
write_grf5101(dev, 0x1f, 0x0);
|
||||
write_grf5101(dev, 0x1f, 0x40);
|
||||
write_grf5101(dev, 0x1f, 0x60);
|
||||
write_grf5101(dev, 0x1f, 0x61);
|
||||
write_grf5101(dev, 0x1f, 0x61);
|
||||
write_grf5101(dev, 0x00, 0xae4);
|
||||
write_grf5101(dev, 0x1f, 0x1);
|
||||
write_grf5101(dev, 0x1f, 0x41);
|
||||
write_grf5101(dev, 0x1f, 0x61);
|
||||
|
||||
write_grf5101(dev, 0x01, 0x1a23);
|
||||
write_grf5101(dev, 0x02, 0x4971);
|
||||
write_grf5101(dev, 0x03, 0x41de);
|
||||
write_grf5101(dev, 0x04, 0x2d80);
|
||||
write_grf5101(dev, 0x05, 0x68ff); /* 0x61ff original value */
|
||||
write_grf5101(dev, 0x06, 0x0);
|
||||
write_grf5101(dev, 0x07, 0x0);
|
||||
write_grf5101(dev, 0x08, 0x7533);
|
||||
write_grf5101(dev, 0x09, 0xc401);
|
||||
write_grf5101(dev, 0x0a, 0x0);
|
||||
write_grf5101(dev, 0x0c, 0x1c7);
|
||||
write_grf5101(dev, 0x0d, 0x29d3);
|
||||
write_grf5101(dev, 0x0e, 0x2e8);
|
||||
write_grf5101(dev, 0x10, 0x192);
|
||||
write_grf5101(dev, 0x11, 0x248);
|
||||
write_grf5101(dev, 0x12, 0x0);
|
||||
write_grf5101(dev, 0x13, 0x20c4);
|
||||
write_grf5101(dev, 0x14, 0xf4fc);
|
||||
write_grf5101(dev, 0x15, 0x0);
|
||||
write_grf5101(dev, 0x16, 0x1500);
|
||||
|
||||
write_grf5101(dev, 0x07, 0x1000);
|
||||
|
||||
/* baseband configuration */
|
||||
rtl8180_write_phy(dev, 0, 0xa8);
|
||||
rtl8180_write_phy(dev, 3, 0x0);
|
||||
rtl8180_write_phy(dev, 4, 0xc0);
|
||||
rtl8180_write_phy(dev, 5, 0x90);
|
||||
rtl8180_write_phy(dev, 6, 0x1e);
|
||||
rtl8180_write_phy(dev, 7, 0x64);
|
||||
|
||||
grf5101_write_phy_antenna(dev, 1);
|
||||
|
||||
rtl8180_write_phy(dev, 0x11, 0x88);
|
||||
|
||||
if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
|
||||
RTL818X_CONFIG2_ANTENNA_DIV)
|
||||
rtl8180_write_phy(dev, 0x12, 0xc0); /* enable ant diversity */
|
||||
else
|
||||
rtl8180_write_phy(dev, 0x12, 0x40); /* disable ant diversity */
|
||||
|
||||
rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
|
||||
|
||||
rtl8180_write_phy(dev, 0x19, 0x0);
|
||||
rtl8180_write_phy(dev, 0x1a, 0xa0);
|
||||
rtl8180_write_phy(dev, 0x1b, 0x44);
|
||||
}
|
||||
|
||||
const struct rtl818x_rf_ops grf5101_rf_ops = {
|
||||
.name = "GCT",
|
||||
.init = grf5101_rf_init,
|
||||
.stop = grf5101_rf_stop,
|
||||
.set_chan = grf5101_rf_set_channel
|
||||
};
|
28
drivers/net/wireless/rtl818x/rtl8180_grf5101.h
Normal file
28
drivers/net/wireless/rtl818x/rtl8180_grf5101.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef RTL8180_GRF5101_H
|
||||
#define RTL8180_GRF5101_H
|
||||
|
||||
/*
|
||||
* Radio tuning for GCT GRF5101 on RTL8180
|
||||
*
|
||||
* Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Code from the BSD driver and the rtl8181 project have been
|
||||
* very useful to understand certain things
|
||||
*
|
||||
* I want to thanks the Authors of such projects and the Ndiswrapper
|
||||
* project Authors.
|
||||
*
|
||||
* A special Big Thanks also is for all people who donated me cards,
|
||||
* making possible the creation of the original rtl8180 driver
|
||||
* from which this code is derived!
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define GRF5101_ANTENNA 0xA3
|
||||
|
||||
extern const struct rtl818x_rf_ops grf5101_rf_ops;
|
||||
|
||||
#endif /* RTL8180_GRF5101_H */
|
152
drivers/net/wireless/rtl818x/rtl8180_max2820.c
Normal file
152
drivers/net/wireless/rtl818x/rtl8180_max2820.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Radio tuning for Maxim max2820 on RTL8180
|
||||
*
|
||||
* Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Code from the BSD driver and the rtl8181 project have been
|
||||
* very useful to understand certain things
|
||||
*
|
||||
* I want to thanks the Authors of such projects and the Ndiswrapper
|
||||
* project Authors.
|
||||
*
|
||||
* A special Big Thanks also is for all people who donated me cards,
|
||||
* making possible the creation of the original rtl8180 driver
|
||||
* from which this code is derived!
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "rtl8180.h"
|
||||
#include "rtl8180_max2820.h"
|
||||
|
||||
static const u32 max2820_chan[] = {
|
||||
12, /* CH 1 */
|
||||
17,
|
||||
22,
|
||||
27,
|
||||
32,
|
||||
37,
|
||||
42,
|
||||
47,
|
||||
52,
|
||||
57,
|
||||
62,
|
||||
67,
|
||||
72,
|
||||
84, /* CH 14 */
|
||||
};
|
||||
|
||||
static void write_max2820(struct ieee80211_hw *dev, u8 addr, u32 data)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u32 phy_config;
|
||||
|
||||
phy_config = 0x90 + (data & 0xf);
|
||||
phy_config <<= 16;
|
||||
phy_config += addr;
|
||||
phy_config <<= 8;
|
||||
phy_config += (data >> 4) & 0xff;
|
||||
|
||||
rtl818x_iowrite32(priv,
|
||||
(__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
|
||||
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u8 ant;
|
||||
|
||||
ant = MAXIM_ANTENNA;
|
||||
if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
|
||||
ant |= BB_ANTENNA_B;
|
||||
if (chan == 14)
|
||||
ant |= BB_ANTATTEN_CHAN14;
|
||||
|
||||
rtl8180_write_phy(dev, 0x10, ant);
|
||||
}
|
||||
|
||||
static void max2820_rf_set_channel(struct ieee80211_hw *dev,
|
||||
struct ieee80211_conf *conf)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
int channel = conf ?
|
||||
ieee80211_frequency_to_channel(conf->channel->center_freq) : 1;
|
||||
unsigned int chan_idx = channel - 1;
|
||||
u32 txpw = priv->channels[chan_idx].hw_value & 0xFF;
|
||||
u32 chan = max2820_chan[chan_idx];
|
||||
|
||||
/* While philips SA2400 drive the PA bias from
|
||||
* sa2400, for MAXIM we do this directly from BB */
|
||||
rtl8180_write_phy(dev, 3, txpw);
|
||||
|
||||
max2820_write_phy_antenna(dev, channel);
|
||||
write_max2820(dev, 3, chan);
|
||||
}
|
||||
|
||||
static void max2820_rf_stop(struct ieee80211_hw *dev)
|
||||
{
|
||||
rtl8180_write_phy(dev, 3, 0x8);
|
||||
write_max2820(dev, 1, 0);
|
||||
}
|
||||
|
||||
|
||||
static void max2820_rf_init(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
|
||||
/* MAXIM from netbsd driver */
|
||||
write_max2820(dev, 0, 0x007); /* test mode as indicated in datasheet */
|
||||
write_max2820(dev, 1, 0x01e); /* enable register */
|
||||
write_max2820(dev, 2, 0x001); /* synt register */
|
||||
|
||||
max2820_rf_set_channel(dev, NULL);
|
||||
|
||||
write_max2820(dev, 4, 0x313); /* rx register */
|
||||
|
||||
/* PA is driven directly by the BB, we keep the MAXIM bias
|
||||
* at the highest value in case that setting it to lower
|
||||
* values may introduce some further attenuation somewhere..
|
||||
*/
|
||||
write_max2820(dev, 5, 0x00f);
|
||||
|
||||
/* baseband configuration */
|
||||
rtl8180_write_phy(dev, 0, 0x88); /* sys1 */
|
||||
rtl8180_write_phy(dev, 3, 0x08); /* txagc */
|
||||
rtl8180_write_phy(dev, 4, 0xf8); /* lnadet */
|
||||
rtl8180_write_phy(dev, 5, 0x90); /* ifagcinit */
|
||||
rtl8180_write_phy(dev, 6, 0x1a); /* ifagclimit */
|
||||
rtl8180_write_phy(dev, 7, 0x64); /* ifagcdet */
|
||||
|
||||
max2820_write_phy_antenna(dev, 1);
|
||||
|
||||
rtl8180_write_phy(dev, 0x11, 0x88); /* trl */
|
||||
|
||||
if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
|
||||
RTL818X_CONFIG2_ANTENNA_DIV)
|
||||
rtl8180_write_phy(dev, 0x12, 0xc7);
|
||||
else
|
||||
rtl8180_write_phy(dev, 0x12, 0x47);
|
||||
|
||||
rtl8180_write_phy(dev, 0x13, 0x9b);
|
||||
|
||||
rtl8180_write_phy(dev, 0x19, 0x0); /* CHESTLIM */
|
||||
rtl8180_write_phy(dev, 0x1a, 0x9f); /* CHSQLIM */
|
||||
|
||||
max2820_rf_set_channel(dev, NULL);
|
||||
}
|
||||
|
||||
const struct rtl818x_rf_ops max2820_rf_ops = {
|
||||
.name = "Maxim",
|
||||
.init = max2820_rf_init,
|
||||
.stop = max2820_rf_stop,
|
||||
.set_chan = max2820_rf_set_channel
|
||||
};
|
28
drivers/net/wireless/rtl818x/rtl8180_max2820.h
Normal file
28
drivers/net/wireless/rtl818x/rtl8180_max2820.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef RTL8180_MAX2820_H
|
||||
#define RTL8180_MAX2820_H
|
||||
|
||||
/*
|
||||
* Radio tuning for Maxim max2820 on RTL8180
|
||||
*
|
||||
* Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Code from the BSD driver and the rtl8181 project have been
|
||||
* very useful to understand certain things
|
||||
*
|
||||
* I want to thanks the Authors of such projects and the Ndiswrapper
|
||||
* project Authors.
|
||||
*
|
||||
* A special Big Thanks also is for all people who donated me cards,
|
||||
* making possible the creation of the original rtl8180 driver
|
||||
* from which this code is derived!
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define MAXIM_ANTENNA 0xb3
|
||||
|
||||
extern const struct rtl818x_rf_ops max2820_rf_ops;
|
||||
|
||||
#endif /* RTL8180_MAX2820_H */
|
780
drivers/net/wireless/rtl818x/rtl8180_rtl8225.c
Normal file
780
drivers/net/wireless/rtl818x/rtl8180_rtl8225.c
Normal file
@@ -0,0 +1,780 @@
|
||||
|
||||
/*
|
||||
* Radio tuning for RTL8225 on RTL8180
|
||||
*
|
||||
* Copyright 2007 Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Based on the r8180 driver, which is:
|
||||
* Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
|
||||
*
|
||||
* Thanks to Realtek for their support!
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "rtl8180.h"
|
||||
#include "rtl8180_rtl8225.h"
|
||||
|
||||
static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u16 reg80, reg84, reg82;
|
||||
u32 bangdata;
|
||||
int i;
|
||||
|
||||
bangdata = (data << 4) | (addr & 0xf);
|
||||
|
||||
reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
|
||||
reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
|
||||
|
||||
reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400);
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(10);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(10);
|
||||
|
||||
for (i = 15; i >= 0; i--) {
|
||||
u16 reg = reg80 | !!(bangdata & (1 << i));
|
||||
|
||||
if (i & 1)
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
|
||||
|
||||
if (!(i & 1))
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
|
||||
}
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(10);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
|
||||
}
|
||||
|
||||
static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u16 reg80, reg82, reg84, out;
|
||||
int i;
|
||||
|
||||
reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
|
||||
reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
|
||||
reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400;
|
||||
|
||||
reg80 &= ~0xF;
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(4);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(5);
|
||||
|
||||
for (i = 4; i >= 0; i--) {
|
||||
u16 reg = reg80 | ((addr >> i) & 1);
|
||||
|
||||
if (!(i & 1)) {
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg | (1 << 1));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg | (1 << 1));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(2);
|
||||
|
||||
if (i & 1) {
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E);
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3) | (1 << 1));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(2);
|
||||
|
||||
out = 0;
|
||||
for (i = 11; i >= 0; i--) {
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(1);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3) | (1 << 1));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3) | (1 << 1));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3) | (1 << 1));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(2);
|
||||
|
||||
if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
|
||||
out |= 1 << i;
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3) | (1 << 2));
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
udelay(2);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static const u16 rtl8225bcd_rxgain[] = {
|
||||
0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
|
||||
0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
|
||||
0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
|
||||
0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
|
||||
0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
|
||||
0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
|
||||
0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
|
||||
0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
|
||||
0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
|
||||
0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
|
||||
0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
|
||||
0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
|
||||
};
|
||||
|
||||
static const u8 rtl8225_agc[] = {
|
||||
0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
|
||||
0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
|
||||
0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
|
||||
0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
|
||||
0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
|
||||
0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
|
||||
0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
|
||||
0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
|
||||
0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
|
||||
0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
|
||||
0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
|
||||
0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
|
||||
0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
|
||||
};
|
||||
|
||||
static const u8 rtl8225_gain[] = {
|
||||
0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
|
||||
0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
|
||||
0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
|
||||
0x33, 0x80, 0x79, 0xc5, /* -78dbm */
|
||||
0x43, 0x78, 0x76, 0xc5, /* -74dbm */
|
||||
0x53, 0x60, 0x73, 0xc5, /* -70dbm */
|
||||
0x63, 0x58, 0x70, 0xc5, /* -66dbm */
|
||||
};
|
||||
|
||||
static const u8 rtl8225_threshold[] = {
|
||||
0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
|
||||
};
|
||||
|
||||
static const u8 rtl8225_tx_gain_cck_ofdm[] = {
|
||||
0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
|
||||
};
|
||||
|
||||
static const u8 rtl8225_tx_power_cck[] = {
|
||||
0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
|
||||
0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
|
||||
0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
|
||||
0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
|
||||
0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
|
||||
0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
|
||||
};
|
||||
|
||||
static const u8 rtl8225_tx_power_cck_ch14[] = {
|
||||
0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
|
||||
0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const u8 rtl8225_tx_power_ofdm[] = {
|
||||
0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
|
||||
};
|
||||
|
||||
static const u32 rtl8225_chan[] = {
|
||||
0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
|
||||
0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
|
||||
};
|
||||
|
||||
static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u8 cck_power, ofdm_power;
|
||||
const u8 *tmp;
|
||||
u32 reg;
|
||||
int i;
|
||||
|
||||
cck_power = priv->channels[channel - 1].hw_value & 0xFF;
|
||||
ofdm_power = priv->channels[channel - 1].hw_value >> 8;
|
||||
|
||||
cck_power = min(cck_power, (u8)35);
|
||||
ofdm_power = min(ofdm_power, (u8)35);
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
|
||||
rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
|
||||
|
||||
if (channel == 14)
|
||||
tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
|
||||
else
|
||||
tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
|
||||
|
||||
msleep(1); /* FIXME: optional? */
|
||||
|
||||
/* anaparam2 on */
|
||||
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_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
|
||||
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
|
||||
rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1);
|
||||
|
||||
tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
|
||||
|
||||
rtl8225_write_phy_ofdm(dev, 5, *tmp);
|
||||
rtl8225_write_phy_ofdm(dev, 7, *tmp);
|
||||
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
static void rtl8225_rf_init(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
int i;
|
||||
|
||||
rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);
|
||||
|
||||
/* host_pci_init */
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
|
||||
rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
msleep(200); /* FIXME: ehh?? */
|
||||
rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
|
||||
|
||||
rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
|
||||
|
||||
/* TODO: check if we need really to change BRSR to do RF config */
|
||||
rtl818x_ioread16(priv, &priv->map->BRSR);
|
||||
rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
|
||||
rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
|
||||
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
|
||||
rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
|
||||
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x067);
|
||||
rtl8225_write(dev, 0x1, 0xFE0);
|
||||
rtl8225_write(dev, 0x2, 0x44D);
|
||||
rtl8225_write(dev, 0x3, 0x441);
|
||||
rtl8225_write(dev, 0x4, 0x8BE);
|
||||
rtl8225_write(dev, 0x5, 0xBF0); /* TODO: minipci */
|
||||
rtl8225_write(dev, 0x6, 0xAE6);
|
||||
rtl8225_write(dev, 0x7, rtl8225_chan[0]);
|
||||
rtl8225_write(dev, 0x8, 0x01F);
|
||||
rtl8225_write(dev, 0x9, 0x334);
|
||||
rtl8225_write(dev, 0xA, 0xFD4);
|
||||
rtl8225_write(dev, 0xB, 0x391);
|
||||
rtl8225_write(dev, 0xC, 0x050);
|
||||
rtl8225_write(dev, 0xD, 0x6DB);
|
||||
rtl8225_write(dev, 0xE, 0x029);
|
||||
rtl8225_write(dev, 0xF, 0x914); msleep(1);
|
||||
|
||||
rtl8225_write(dev, 0x2, 0xC4D); msleep(100);
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x127);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
|
||||
rtl8225_write(dev, 0x1, i + 1);
|
||||
rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
|
||||
}
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x027);
|
||||
rtl8225_write(dev, 0x0, 0x22F);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
|
||||
rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
|
||||
msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
msleep(1);
|
||||
|
||||
rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x06, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x08, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x11, 0x03); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
|
||||
|
||||
rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x13, 0xd0);
|
||||
rtl8225_write_phy_cck(dev, 0x19, 0x00);
|
||||
rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
|
||||
rtl8225_write_phy_cck(dev, 0x1b, 0x08);
|
||||
rtl8225_write_phy_cck(dev, 0x40, 0x86);
|
||||
rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); msleep(1);
|
||||
|
||||
rtl8225_rf_set_tx_power(dev, 1);
|
||||
|
||||
/* RX antenna default to A */
|
||||
rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */
|
||||
rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
|
||||
msleep(1);
|
||||
rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
|
||||
|
||||
rtl8225_write(dev, 0x0c, 0x50);
|
||||
/* set OFDM initial gain */
|
||||
rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]);
|
||||
/* set CCK threshold */
|
||||
rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]);
|
||||
}
|
||||
|
||||
static const u8 rtl8225z2_tx_power_cck_ch14[] = {
|
||||
0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const u8 rtl8225z2_tx_power_cck_B[] = {
|
||||
0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04
|
||||
};
|
||||
|
||||
static const u8 rtl8225z2_tx_power_cck_A[] = {
|
||||
0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04
|
||||
};
|
||||
|
||||
static const u8 rtl8225z2_tx_power_cck[] = {
|
||||
0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
|
||||
};
|
||||
|
||||
static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u8 cck_power, ofdm_power;
|
||||
const u8 *tmp;
|
||||
int i;
|
||||
|
||||
cck_power = priv->channels[channel - 1].hw_value & 0xFF;
|
||||
ofdm_power = priv->channels[channel - 1].hw_value >> 8;
|
||||
|
||||
if (channel == 14)
|
||||
tmp = rtl8225z2_tx_power_cck_ch14;
|
||||
else if (cck_power == 12)
|
||||
tmp = rtl8225z2_tx_power_cck_B;
|
||||
else if (cck_power == 13)
|
||||
tmp = rtl8225z2_tx_power_cck_A;
|
||||
else
|
||||
tmp = rtl8225z2_tx_power_cck;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
|
||||
|
||||
cck_power = min(cck_power, (u8)35);
|
||||
if (cck_power == 13 || cck_power == 14)
|
||||
cck_power = 12;
|
||||
if (cck_power >= 15)
|
||||
cck_power -= 2;
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, cck_power);
|
||||
rtl818x_ioread8(priv, &priv->map->TX_GAIN_CCK);
|
||||
msleep(1);
|
||||
|
||||
ofdm_power = min(ofdm_power, (u8)35);
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, ofdm_power);
|
||||
|
||||
rtl8225_write_phy_ofdm(dev, 2, 0x62);
|
||||
rtl8225_write_phy_ofdm(dev, 5, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 6, 0x40);
|
||||
rtl8225_write_phy_ofdm(dev, 7, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 8, 0x40);
|
||||
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
static const u16 rtl8225z2_rxgain[] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
|
||||
0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
|
||||
0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
|
||||
0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
|
||||
0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
|
||||
0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
|
||||
0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
|
||||
0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
|
||||
0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
|
||||
0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
|
||||
0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
|
||||
0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
|
||||
};
|
||||
|
||||
static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
int i;
|
||||
|
||||
rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);
|
||||
|
||||
/* host_pci_init */
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
|
||||
rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
msleep(200); /* FIXME: ehh?? */
|
||||
rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
|
||||
|
||||
rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00088008);
|
||||
|
||||
/* TODO: check if we need really to change BRSR to do RF config */
|
||||
rtl818x_ioread16(priv, &priv->map->BRSR);
|
||||
rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
|
||||
rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
|
||||
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
|
||||
rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
|
||||
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
|
||||
|
||||
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(100);
|
||||
|
||||
if (!(rtl8225_read(dev, 6) & (1 << 7))) {
|
||||
rtl8225_write(dev, 0x02, 0x0C4D);
|
||||
msleep(200);
|
||||
rtl8225_write(dev, 0x02, 0x044D);
|
||||
msleep(100);
|
||||
/* TODO: readd calibration failure message when the calibration
|
||||
check works */
|
||||
}
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x1B7);
|
||||
rtl8225_write(dev, 0x3, 0x002);
|
||||
rtl8225_write(dev, 0x5, 0x004);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
|
||||
rtl8225_write(dev, 0x1, i + 1);
|
||||
rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
|
||||
}
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x0B7); msleep(100);
|
||||
rtl8225_write(dev, 0x2, 0xC4D);
|
||||
|
||||
msleep(200);
|
||||
rtl8225_write(dev, 0x2, 0x44D);
|
||||
msleep(100);
|
||||
|
||||
rtl8225_write(dev, 0x00, 0x2BF);
|
||||
rtl8225_write(dev, 0xFF, 0xFFFF);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
|
||||
rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
|
||||
msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
msleep(1);
|
||||
|
||||
rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1b, 0x11); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1e, 0xb3); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); /* FIXME: not needed? */
|
||||
rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
|
||||
rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
|
||||
|
||||
rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x13, 0xd0);
|
||||
rtl8225_write_phy_cck(dev, 0x19, 0x00);
|
||||
rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
|
||||
rtl8225_write_phy_cck(dev, 0x1b, 0x08);
|
||||
rtl8225_write_phy_cck(dev, 0x40, 0x86);
|
||||
rtl8225_write_phy_cck(dev, 0x41, 0x8a); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1);
|
||||
rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
|
||||
|
||||
rtl818x_iowrite8(priv, (u8 __iomem *)((void __iomem *)priv->map + 0x5B), 0x0D); msleep(1);
|
||||
|
||||
rtl8225z2_rf_set_tx_power(dev, 1);
|
||||
|
||||
/* RX antenna default to A */
|
||||
rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */
|
||||
rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
|
||||
msleep(1);
|
||||
rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
|
||||
}
|
||||
|
||||
static void rtl8225_rf_stop(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u8 reg;
|
||||
|
||||
rtl8225_write(dev, 0x4, 0x1f); msleep(1);
|
||||
|
||||
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);
|
||||
rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
|
||||
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
|
||||
}
|
||||
|
||||
static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
|
||||
struct ieee80211_conf *conf)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
int chan = ieee80211_frequency_to_channel(conf->channel->center_freq);
|
||||
|
||||
if (priv->rf->init == rtl8225_rf_init)
|
||||
rtl8225_rf_set_tx_power(dev, chan);
|
||||
else
|
||||
rtl8225z2_rf_set_tx_power(dev, chan);
|
||||
|
||||
rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
|
||||
msleep(10);
|
||||
|
||||
if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
|
||||
rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
|
||||
rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
|
||||
rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
|
||||
rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
|
||||
rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
|
||||
} else {
|
||||
rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
|
||||
rtl818x_iowrite8(priv, &priv->map->SIFS, 0x44);
|
||||
rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
|
||||
rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
|
||||
rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct rtl818x_rf_ops rtl8225_ops = {
|
||||
.name = "rtl8225",
|
||||
.init = rtl8225_rf_init,
|
||||
.stop = rtl8225_rf_stop,
|
||||
.set_chan = rtl8225_rf_set_channel
|
||||
};
|
||||
|
||||
static const struct rtl818x_rf_ops rtl8225z2_ops = {
|
||||
.name = "rtl8225z2",
|
||||
.init = rtl8225z2_rf_init,
|
||||
.stop = rtl8225_rf_stop,
|
||||
.set_chan = rtl8225_rf_set_channel
|
||||
};
|
||||
|
||||
const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u16 reg8, reg9;
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
|
||||
rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
|
||||
msleep(100);
|
||||
|
||||
rtl8225_write(dev, 0, 0x1B7);
|
||||
|
||||
reg8 = rtl8225_read(dev, 8);
|
||||
reg9 = rtl8225_read(dev, 9);
|
||||
|
||||
rtl8225_write(dev, 0, 0x0B7);
|
||||
|
||||
if (reg8 != 0x588 || reg9 != 0x700)
|
||||
return &rtl8225_ops;
|
||||
|
||||
return &rtl8225z2_ops;
|
||||
}
|
23
drivers/net/wireless/rtl818x/rtl8180_rtl8225.h
Normal file
23
drivers/net/wireless/rtl818x/rtl8180_rtl8225.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef RTL8180_RTL8225_H
|
||||
#define RTL8180_RTL8225_H
|
||||
|
||||
#define RTL8225_ANAPARAM_ON 0xa0000b59
|
||||
#define RTL8225_ANAPARAM2_ON 0x860dec11
|
||||
#define RTL8225_ANAPARAM_OFF 0xa00beb59
|
||||
#define RTL8225_ANAPARAM2_OFF 0x840dec11
|
||||
|
||||
const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *);
|
||||
|
||||
static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev,
|
||||
u8 addr, u8 data)
|
||||
{
|
||||
rtl8180_write_phy(dev, addr, data);
|
||||
}
|
||||
|
||||
static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev,
|
||||
u8 addr, u8 data)
|
||||
{
|
||||
rtl8180_write_phy(dev, addr, data | 0x10000);
|
||||
}
|
||||
|
||||
#endif /* RTL8180_RTL8225_H */
|
202
drivers/net/wireless/rtl818x/rtl8180_sa2400.c
Normal file
202
drivers/net/wireless/rtl818x/rtl8180_sa2400.c
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
/*
|
||||
* Radio tuning for Philips SA2400 on RTL8180
|
||||
*
|
||||
* Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Code from the BSD driver and the rtl8181 project have been
|
||||
* very useful to understand certain things
|
||||
*
|
||||
* I want to thanks the Authors of such projects and the Ndiswrapper
|
||||
* project Authors.
|
||||
*
|
||||
* A special Big Thanks also is for all people who donated me cards,
|
||||
* making possible the creation of the original rtl8180 driver
|
||||
* from which this code is derived!
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "rtl8180.h"
|
||||
#include "rtl8180_sa2400.h"
|
||||
|
||||
static const u32 sa2400_chan[] = {
|
||||
0x00096c, /* ch1 */
|
||||
0x080970,
|
||||
0x100974,
|
||||
0x180978,
|
||||
0x000980,
|
||||
0x080984,
|
||||
0x100988,
|
||||
0x18098c,
|
||||
0x000994,
|
||||
0x080998,
|
||||
0x10099c,
|
||||
0x1809a0,
|
||||
0x0009a8,
|
||||
0x0009b4, /* ch 14 */
|
||||
};
|
||||
|
||||
static void write_sa2400(struct ieee80211_hw *dev, u8 addr, u32 data)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u32 phy_config;
|
||||
|
||||
/* MAC will bang bits to the sa2400. sw 3-wire is NOT used */
|
||||
phy_config = 0xb0000000;
|
||||
|
||||
phy_config |= ((u32)(addr & 0xf)) << 24;
|
||||
phy_config |= data & 0xffffff;
|
||||
|
||||
rtl818x_iowrite32(priv,
|
||||
(__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
|
||||
|
||||
msleep(3);
|
||||
}
|
||||
|
||||
static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u8 ant = SA2400_ANTENNA;
|
||||
|
||||
if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
|
||||
ant |= BB_ANTENNA_B;
|
||||
|
||||
if (chan == 14)
|
||||
ant |= BB_ANTATTEN_CHAN14;
|
||||
|
||||
rtl8180_write_phy(dev, 0x10, ant);
|
||||
|
||||
}
|
||||
|
||||
static void sa2400_rf_set_channel(struct ieee80211_hw *dev,
|
||||
struct ieee80211_conf *conf)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
|
||||
u32 txpw = priv->channels[channel - 1].hw_value & 0xFF;
|
||||
u32 chan = sa2400_chan[channel - 1];
|
||||
|
||||
write_sa2400(dev, 7, txpw);
|
||||
|
||||
sa2400_write_phy_antenna(dev, channel);
|
||||
|
||||
write_sa2400(dev, 0, chan);
|
||||
write_sa2400(dev, 1, 0xbb50);
|
||||
write_sa2400(dev, 2, 0x80);
|
||||
write_sa2400(dev, 3, 0);
|
||||
}
|
||||
|
||||
static void sa2400_rf_stop(struct ieee80211_hw *dev)
|
||||
{
|
||||
write_sa2400(dev, 4, 0);
|
||||
}
|
||||
|
||||
static void sa2400_rf_init(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
u32 anaparam, txconf;
|
||||
u8 firdac;
|
||||
int analogphy = priv->rfparam & RF_PARAM_ANALOGPHY;
|
||||
|
||||
anaparam = priv->anaparam;
|
||||
anaparam &= ~(1 << ANAPARAM_TXDACOFF_SHIFT);
|
||||
anaparam &= ~ANAPARAM_PWR1_MASK;
|
||||
anaparam &= ~ANAPARAM_PWR0_MASK;
|
||||
|
||||
if (analogphy) {
|
||||
anaparam |= SA2400_ANA_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT;
|
||||
firdac = 0;
|
||||
} else {
|
||||
anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT);
|
||||
anaparam |= (SA2400_ANAPARAM_PWR0_ON << ANAPARAM_PWR0_SHIFT);
|
||||
firdac = 1 << SA2400_REG4_FIRDAC_SHIFT;
|
||||
}
|
||||
|
||||
rtl8180_set_anaparam(priv, anaparam);
|
||||
|
||||
write_sa2400(dev, 0, sa2400_chan[0]);
|
||||
write_sa2400(dev, 1, 0xbb50);
|
||||
write_sa2400(dev, 2, 0x80);
|
||||
write_sa2400(dev, 3, 0);
|
||||
write_sa2400(dev, 4, 0x19340 | firdac);
|
||||
write_sa2400(dev, 5, 0x1dfb | (SA2400_MAX_SENS - 54) << 15);
|
||||
write_sa2400(dev, 4, 0x19348 | firdac); /* calibrate VCO */
|
||||
|
||||
if (!analogphy)
|
||||
write_sa2400(dev, 4, 0x1938c); /*???*/
|
||||
|
||||
write_sa2400(dev, 4, 0x19340 | firdac);
|
||||
|
||||
write_sa2400(dev, 0, sa2400_chan[0]);
|
||||
write_sa2400(dev, 1, 0xbb50);
|
||||
write_sa2400(dev, 2, 0x80);
|
||||
write_sa2400(dev, 3, 0);
|
||||
write_sa2400(dev, 4, 0x19344 | firdac); /* calibrate filter */
|
||||
|
||||
/* new from rtl8180 embedded driver (rtl8181 project) */
|
||||
write_sa2400(dev, 6, 0x13ff | (1 << 23)); /* MANRX */
|
||||
write_sa2400(dev, 8, 0); /* VCO */
|
||||
|
||||
if (analogphy) {
|
||||
rtl8180_set_anaparam(priv, anaparam |
|
||||
(1 << ANAPARAM_TXDACOFF_SHIFT));
|
||||
|
||||
txconf = rtl818x_ioread32(priv, &priv->map->TX_CONF);
|
||||
rtl818x_iowrite32(priv, &priv->map->TX_CONF,
|
||||
txconf | RTL818X_TX_CONF_LOOPBACK_CONT);
|
||||
|
||||
write_sa2400(dev, 4, 0x19341); /* calibrates DC */
|
||||
|
||||
/* a 5us sleep is required here,
|
||||
* we rely on the 3ms delay introduced in write_sa2400 */
|
||||
write_sa2400(dev, 4, 0x19345);
|
||||
|
||||
/* a 20us sleep is required here,
|
||||
* we rely on the 3ms delay introduced in write_sa2400 */
|
||||
|
||||
rtl818x_iowrite32(priv, &priv->map->TX_CONF, txconf);
|
||||
|
||||
rtl8180_set_anaparam(priv, anaparam);
|
||||
}
|
||||
/* end new code */
|
||||
|
||||
write_sa2400(dev, 4, 0x19341 | firdac); /* RTX MODE */
|
||||
|
||||
/* baseband configuration */
|
||||
rtl8180_write_phy(dev, 0, 0x98);
|
||||
rtl8180_write_phy(dev, 3, 0x38);
|
||||
rtl8180_write_phy(dev, 4, 0xe0);
|
||||
rtl8180_write_phy(dev, 5, 0x90);
|
||||
rtl8180_write_phy(dev, 6, 0x1a);
|
||||
rtl8180_write_phy(dev, 7, 0x64);
|
||||
|
||||
sa2400_write_phy_antenna(dev, 1);
|
||||
|
||||
rtl8180_write_phy(dev, 0x11, 0x80);
|
||||
|
||||
if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
|
||||
RTL818X_CONFIG2_ANTENNA_DIV)
|
||||
rtl8180_write_phy(dev, 0x12, 0xc7); /* enable ant diversity */
|
||||
else
|
||||
rtl8180_write_phy(dev, 0x12, 0x47); /* disable ant diversity */
|
||||
|
||||
rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
|
||||
|
||||
rtl8180_write_phy(dev, 0x19, 0x0);
|
||||
rtl8180_write_phy(dev, 0x1a, 0xa0);
|
||||
}
|
||||
|
||||
const struct rtl818x_rf_ops sa2400_rf_ops = {
|
||||
.name = "Philips",
|
||||
.init = sa2400_rf_init,
|
||||
.stop = sa2400_rf_stop,
|
||||
.set_chan = sa2400_rf_set_channel
|
||||
};
|
36
drivers/net/wireless/rtl818x/rtl8180_sa2400.h
Normal file
36
drivers/net/wireless/rtl818x/rtl8180_sa2400.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef RTL8180_SA2400_H
|
||||
#define RTL8180_SA2400_H
|
||||
|
||||
/*
|
||||
* Radio tuning for Philips SA2400 on RTL8180
|
||||
*
|
||||
* Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Code from the BSD driver and the rtl8181 project have been
|
||||
* very useful to understand certain things
|
||||
*
|
||||
* I want to thanks the Authors of such projects and the Ndiswrapper
|
||||
* project Authors.
|
||||
*
|
||||
* A special Big Thanks also is for all people who donated me cards,
|
||||
* making possible the creation of the original rtl8180 driver
|
||||
* from which this code is derived!
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define SA2400_ANTENNA 0x91
|
||||
#define SA2400_DIG_ANAPARAM_PWR1_ON 0x8
|
||||
#define SA2400_ANA_ANAPARAM_PWR1_ON 0x28
|
||||
#define SA2400_ANAPARAM_PWR0_ON 0x3
|
||||
|
||||
/* RX sensitivity in dbm */
|
||||
#define SA2400_MAX_SENS 85
|
||||
|
||||
#define SA2400_REG4_FIRDAC_SHIFT 7
|
||||
|
||||
extern const struct rtl818x_rf_ops sa2400_rf_ops;
|
||||
|
||||
#endif /* RTL8180_SA2400_H */
|
220
drivers/net/wireless/rtl818x/rtl8187.h
Normal file
220
drivers/net/wireless/rtl818x/rtl8187.h
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Definitions for RTL8187 hardware
|
||||
*
|
||||
* Copyright 2007 Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Based on the r8187 driver, which is:
|
||||
* Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef RTL8187_H
|
||||
#define RTL8187_H
|
||||
|
||||
#include "rtl818x.h"
|
||||
|
||||
#define RTL8187_EEPROM_TXPWR_BASE 0x05
|
||||
#define RTL8187_EEPROM_MAC_ADDR 0x07
|
||||
#define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */
|
||||
#define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */
|
||||
#define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */
|
||||
|
||||
#define RTL8187_REQT_READ 0xC0
|
||||
#define RTL8187_REQT_WRITE 0x40
|
||||
#define RTL8187_REQ_GET_REG 0x05
|
||||
#define RTL8187_REQ_SET_REG 0x05
|
||||
|
||||
#define RTL8187_MAX_RX 0x9C4
|
||||
|
||||
struct rtl8187_rx_info {
|
||||
struct urb *urb;
|
||||
struct ieee80211_hw *dev;
|
||||
};
|
||||
|
||||
struct rtl8187_rx_hdr {
|
||||
__le32 flags;
|
||||
u8 noise;
|
||||
u8 signal;
|
||||
u8 agc;
|
||||
u8 reserved;
|
||||
__le64 mac_time;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct rtl8187b_rx_hdr {
|
||||
__le32 flags;
|
||||
__le64 mac_time;
|
||||
u8 sq;
|
||||
u8 rssi;
|
||||
u8 agc;
|
||||
u8 flags2;
|
||||
__le16 snr_long2end;
|
||||
s8 pwdb_g12;
|
||||
u8 fot;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* {rtl8187,rtl8187b}_tx_info is in skb */
|
||||
|
||||
struct rtl8187_tx_hdr {
|
||||
__le32 flags;
|
||||
__le16 rts_duration;
|
||||
__le16 len;
|
||||
__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));
|
||||
|
||||
enum {
|
||||
DEVICE_RTL8187,
|
||||
DEVICE_RTL8187B
|
||||
};
|
||||
|
||||
struct rtl8187_priv {
|
||||
/* common between rtl818x drivers */
|
||||
struct rtl818x_csr *map;
|
||||
const struct rtl818x_rf_ops *rf;
|
||||
struct ieee80211_vif *vif;
|
||||
int mode;
|
||||
/* The mutex protects the TX loopback state.
|
||||
* Any attempt to set channels concurrently locks the device.
|
||||
*/
|
||||
struct mutex conf_mutex;
|
||||
|
||||
/* rtl8187 specific */
|
||||
struct ieee80211_channel channels[14];
|
||||
struct ieee80211_rate rates[12];
|
||||
struct ieee80211_supported_band band;
|
||||
struct usb_device *udev;
|
||||
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_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, idx & 0x03, &val,
|
||||
sizeof(val), HZ / 2);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
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, idx & 0x03, &val,
|
||||
sizeof(val), HZ / 2);
|
||||
|
||||
return le16_to_cpu(val);
|
||||
}
|
||||
|
||||
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, idx & 0x03, &val,
|
||||
sizeof(val), HZ / 2);
|
||||
|
||||
return le32_to_cpu(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, idx & 0x03, &val,
|
||||
sizeof(val), HZ / 2);
|
||||
}
|
||||
|
||||
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, 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_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, 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 */
|
1298
drivers/net/wireless/rtl818x/rtl8187_dev.c
Normal file
1298
drivers/net/wireless/rtl818x/rtl8187_dev.c
Normal file
File diff soppresso perché troppo grande
Carica Diff
977
drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
Normal file
977
drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
Normal file
@@ -0,0 +1,977 @@
|
||||
/*
|
||||
* Radio tuning for RTL8225 on RTL8187
|
||||
*
|
||||
* Copyright 2007 Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Based on the r8187 driver, which is:
|
||||
* Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
|
||||
*
|
||||
* Magic delays, register offsets, and phy value tables below are
|
||||
* taken from the original r8187 driver sources. Thanks to Realtek
|
||||
* for their support!
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/usb.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "rtl8187.h"
|
||||
#include "rtl8187_rtl8225.h"
|
||||
|
||||
static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
u16 reg80, reg84, reg82;
|
||||
u32 bangdata;
|
||||
int i;
|
||||
|
||||
bangdata = (data << 4) | (addr & 0xf);
|
||||
|
||||
reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
|
||||
reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
|
||||
|
||||
reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7);
|
||||
udelay(10);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
|
||||
udelay(10);
|
||||
|
||||
for (i = 15; i >= 0; i--) {
|
||||
u16 reg = reg80 | (bangdata & (1 << i)) >> i;
|
||||
|
||||
if (i & 1)
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
|
||||
|
||||
if (!(i & 1))
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
|
||||
}
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
|
||||
udelay(10);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
|
||||
}
|
||||
|
||||
static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
u16 reg80, reg82, reg84;
|
||||
|
||||
reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
|
||||
reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
|
||||
reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
|
||||
|
||||
reg80 &= ~(0x3 << 2);
|
||||
reg84 &= ~0xF;
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x0007);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x0007);
|
||||
udelay(10);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
|
||||
udelay(2);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
|
||||
udelay(10);
|
||||
|
||||
usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
|
||||
RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
|
||||
addr, 0x8225, &data, sizeof(data), HZ / 2);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
|
||||
udelay(10);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
|
||||
}
|
||||
|
||||
static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
|
||||
if (priv->asic_rev)
|
||||
rtl8225_write_8051(dev, addr, cpu_to_le16(data));
|
||||
else
|
||||
rtl8225_write_bitbang(dev, addr, data);
|
||||
}
|
||||
|
||||
static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
u16 reg80, reg82, reg84, out;
|
||||
int i;
|
||||
|
||||
reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
|
||||
reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
|
||||
reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
|
||||
|
||||
reg80 &= ~0xF;
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
|
||||
udelay(4);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
|
||||
udelay(5);
|
||||
|
||||
for (i = 4; i >= 0; i--) {
|
||||
u16 reg = reg80 | ((addr >> i) & 1);
|
||||
|
||||
if (!(i & 1)) {
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg | (1 << 1));
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg | (1 << 1));
|
||||
udelay(2);
|
||||
|
||||
if (i & 1) {
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3) | (1 << 1));
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3));
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3));
|
||||
udelay(2);
|
||||
|
||||
out = 0;
|
||||
for (i = 11; i >= 0; i--) {
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3));
|
||||
udelay(1);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3) | (1 << 1));
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3) | (1 << 1));
|
||||
udelay(2);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3) | (1 << 1));
|
||||
udelay(2);
|
||||
|
||||
if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
|
||||
out |= 1 << i;
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3));
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
|
||||
reg80 | (1 << 3) | (1 << 2));
|
||||
udelay(2);
|
||||
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static const u16 rtl8225bcd_rxgain[] = {
|
||||
0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
|
||||
0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
|
||||
0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
|
||||
0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
|
||||
0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
|
||||
0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
|
||||
0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
|
||||
0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
|
||||
0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
|
||||
0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
|
||||
0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
|
||||
0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
|
||||
};
|
||||
|
||||
static const u8 rtl8225_agc[] = {
|
||||
0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
|
||||
0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
|
||||
0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
|
||||
0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
|
||||
0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
|
||||
0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
|
||||
0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
|
||||
0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
|
||||
0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
|
||||
0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
|
||||
0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
|
||||
0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
|
||||
0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
|
||||
};
|
||||
|
||||
static const u8 rtl8225_gain[] = {
|
||||
0x23, 0x88, 0x7c, 0xa5, /* -82dBm */
|
||||
0x23, 0x88, 0x7c, 0xb5, /* -82dBm */
|
||||
0x23, 0x88, 0x7c, 0xc5, /* -82dBm */
|
||||
0x33, 0x80, 0x79, 0xc5, /* -78dBm */
|
||||
0x43, 0x78, 0x76, 0xc5, /* -74dBm */
|
||||
0x53, 0x60, 0x73, 0xc5, /* -70dBm */
|
||||
0x63, 0x58, 0x70, 0xc5, /* -66dBm */
|
||||
};
|
||||
|
||||
static const u8 rtl8225_threshold[] = {
|
||||
0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
|
||||
};
|
||||
|
||||
static const u8 rtl8225_tx_gain_cck_ofdm[] = {
|
||||
0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
|
||||
};
|
||||
|
||||
static const u8 rtl8225_tx_power_cck[] = {
|
||||
0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
|
||||
0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
|
||||
0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
|
||||
0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
|
||||
0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
|
||||
0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
|
||||
};
|
||||
|
||||
static const u8 rtl8225_tx_power_cck_ch14[] = {
|
||||
0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
|
||||
0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const u8 rtl8225_tx_power_ofdm[] = {
|
||||
0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
|
||||
};
|
||||
|
||||
static const u32 rtl8225_chan[] = {
|
||||
0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
|
||||
0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
|
||||
};
|
||||
|
||||
static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
u8 cck_power, ofdm_power;
|
||||
const u8 *tmp;
|
||||
u32 reg;
|
||||
int i;
|
||||
|
||||
cck_power = priv->channels[channel - 1].hw_value & 0xF;
|
||||
ofdm_power = priv->channels[channel - 1].hw_value >> 4;
|
||||
|
||||
cck_power = min(cck_power, (u8)11);
|
||||
ofdm_power = min(ofdm_power, (u8)35);
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
|
||||
rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
|
||||
|
||||
if (channel == 14)
|
||||
tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
|
||||
else
|
||||
tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
|
||||
|
||||
msleep(1); // FIXME: optional?
|
||||
|
||||
/* anaparam2 on */
|
||||
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,
|
||||
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);
|
||||
|
||||
rtl8225_write_phy_ofdm(dev, 2, 0x42);
|
||||
rtl8225_write_phy_ofdm(dev, 6, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 8, 0x00);
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
|
||||
rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1);
|
||||
|
||||
tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
|
||||
|
||||
rtl8225_write_phy_ofdm(dev, 5, *tmp);
|
||||
rtl8225_write_phy_ofdm(dev, 7, *tmp);
|
||||
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
static void rtl8225_rf_init(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
int i;
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x067);
|
||||
rtl8225_write(dev, 0x1, 0xFE0);
|
||||
rtl8225_write(dev, 0x2, 0x44D);
|
||||
rtl8225_write(dev, 0x3, 0x441);
|
||||
rtl8225_write(dev, 0x4, 0x486);
|
||||
rtl8225_write(dev, 0x5, 0xBC0);
|
||||
rtl8225_write(dev, 0x6, 0xAE6);
|
||||
rtl8225_write(dev, 0x7, 0x82A);
|
||||
rtl8225_write(dev, 0x8, 0x01F);
|
||||
rtl8225_write(dev, 0x9, 0x334);
|
||||
rtl8225_write(dev, 0xA, 0xFD4);
|
||||
rtl8225_write(dev, 0xB, 0x391);
|
||||
rtl8225_write(dev, 0xC, 0x050);
|
||||
rtl8225_write(dev, 0xD, 0x6DB);
|
||||
rtl8225_write(dev, 0xE, 0x029);
|
||||
rtl8225_write(dev, 0xF, 0x914); msleep(100);
|
||||
|
||||
rtl8225_write(dev, 0x2, 0xC4D); msleep(200);
|
||||
rtl8225_write(dev, 0x2, 0x44D); msleep(200);
|
||||
|
||||
if (!(rtl8225_read(dev, 6) & (1 << 7))) {
|
||||
rtl8225_write(dev, 0x02, 0x0c4d);
|
||||
msleep(200);
|
||||
rtl8225_write(dev, 0x02, 0x044d);
|
||||
msleep(100);
|
||||
if (!(rtl8225_read(dev, 6) & (1 << 7)))
|
||||
printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
|
||||
wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
|
||||
}
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x127);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
|
||||
rtl8225_write(dev, 0x1, i + 1);
|
||||
rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
|
||||
}
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x027);
|
||||
rtl8225_write(dev, 0x0, 0x22F);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
|
||||
rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
|
||||
rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
|
||||
}
|
||||
|
||||
msleep(1);
|
||||
|
||||
rtl8225_write_phy_ofdm(dev, 0x00, 0x01);
|
||||
rtl8225_write_phy_ofdm(dev, 0x01, 0x02);
|
||||
rtl8225_write_phy_ofdm(dev, 0x02, 0x42);
|
||||
rtl8225_write_phy_ofdm(dev, 0x03, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x04, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x05, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x06, 0x40);
|
||||
rtl8225_write_phy_ofdm(dev, 0x07, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x08, 0x40);
|
||||
rtl8225_write_phy_ofdm(dev, 0x09, 0xfe);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0a, 0x09);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0b, 0x80);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0c, 0x01);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0f, 0x38);
|
||||
rtl8225_write_phy_ofdm(dev, 0x10, 0x84);
|
||||
rtl8225_write_phy_ofdm(dev, 0x11, 0x06);
|
||||
rtl8225_write_phy_ofdm(dev, 0x12, 0x20);
|
||||
rtl8225_write_phy_ofdm(dev, 0x13, 0x20);
|
||||
rtl8225_write_phy_ofdm(dev, 0x14, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x15, 0x40);
|
||||
rtl8225_write_phy_ofdm(dev, 0x16, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x17, 0x40);
|
||||
rtl8225_write_phy_ofdm(dev, 0x18, 0xef);
|
||||
rtl8225_write_phy_ofdm(dev, 0x19, 0x19);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1a, 0x20);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1b, 0x76);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1c, 0x04);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1e, 0x95);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1f, 0x75);
|
||||
rtl8225_write_phy_ofdm(dev, 0x20, 0x1f);
|
||||
rtl8225_write_phy_ofdm(dev, 0x21, 0x27);
|
||||
rtl8225_write_phy_ofdm(dev, 0x22, 0x16);
|
||||
rtl8225_write_phy_ofdm(dev, 0x24, 0x46);
|
||||
rtl8225_write_phy_ofdm(dev, 0x25, 0x20);
|
||||
rtl8225_write_phy_ofdm(dev, 0x26, 0x90);
|
||||
rtl8225_write_phy_ofdm(dev, 0x27, 0x88);
|
||||
|
||||
rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
|
||||
|
||||
rtl8225_write_phy_cck(dev, 0x00, 0x98);
|
||||
rtl8225_write_phy_cck(dev, 0x03, 0x20);
|
||||
rtl8225_write_phy_cck(dev, 0x04, 0x7e);
|
||||
rtl8225_write_phy_cck(dev, 0x05, 0x12);
|
||||
rtl8225_write_phy_cck(dev, 0x06, 0xfc);
|
||||
rtl8225_write_phy_cck(dev, 0x07, 0x78);
|
||||
rtl8225_write_phy_cck(dev, 0x08, 0x2e);
|
||||
rtl8225_write_phy_cck(dev, 0x10, 0x9b);
|
||||
rtl8225_write_phy_cck(dev, 0x11, 0x88);
|
||||
rtl8225_write_phy_cck(dev, 0x12, 0x47);
|
||||
rtl8225_write_phy_cck(dev, 0x13, 0xd0);
|
||||
rtl8225_write_phy_cck(dev, 0x19, 0x00);
|
||||
rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
|
||||
rtl8225_write_phy_cck(dev, 0x1b, 0x08);
|
||||
rtl8225_write_phy_cck(dev, 0x40, 0x86);
|
||||
rtl8225_write_phy_cck(dev, 0x41, 0x8d);
|
||||
rtl8225_write_phy_cck(dev, 0x42, 0x15);
|
||||
rtl8225_write_phy_cck(dev, 0x43, 0x18);
|
||||
rtl8225_write_phy_cck(dev, 0x44, 0x1f);
|
||||
rtl8225_write_phy_cck(dev, 0x45, 0x1e);
|
||||
rtl8225_write_phy_cck(dev, 0x46, 0x1a);
|
||||
rtl8225_write_phy_cck(dev, 0x47, 0x15);
|
||||
rtl8225_write_phy_cck(dev, 0x48, 0x10);
|
||||
rtl8225_write_phy_cck(dev, 0x49, 0x0a);
|
||||
rtl8225_write_phy_cck(dev, 0x4a, 0x05);
|
||||
rtl8225_write_phy_cck(dev, 0x4b, 0x02);
|
||||
rtl8225_write_phy_cck(dev, 0x4c, 0x05);
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D);
|
||||
|
||||
rtl8225_rf_set_tx_power(dev, 1);
|
||||
|
||||
/* RX antenna default to A */
|
||||
rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */
|
||||
rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
|
||||
msleep(1);
|
||||
rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
|
||||
|
||||
/* set sensitivity */
|
||||
rtl8225_write(dev, 0x0c, 0x50);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
|
||||
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,
|
||||
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,
|
||||
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[] = {
|
||||
0x42, 0x00, 0x40, 0x00, 0x40
|
||||
};
|
||||
|
||||
static const u8 rtl8225z2_tx_gain_cck_ofdm[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
|
||||
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
|
||||
0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
|
||||
0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
|
||||
};
|
||||
|
||||
static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
u8 cck_power, ofdm_power;
|
||||
const u8 *tmp;
|
||||
u32 reg;
|
||||
int i;
|
||||
|
||||
cck_power = priv->channels[channel - 1].hw_value & 0xF;
|
||||
ofdm_power = priv->channels[channel - 1].hw_value >> 4;
|
||||
|
||||
cck_power = min(cck_power, (u8)15);
|
||||
cck_power += priv->txpwr_base & 0xF;
|
||||
cck_power = min(cck_power, (u8)35);
|
||||
|
||||
ofdm_power = min(ofdm_power, (u8)15);
|
||||
ofdm_power += priv->txpwr_base >> 4;
|
||||
ofdm_power = min(ofdm_power, (u8)35);
|
||||
|
||||
if (channel == 14)
|
||||
tmp = rtl8225z2_tx_power_cck_ch14;
|
||||
else
|
||||
tmp = rtl8225z2_tx_power_cck;
|
||||
|
||||
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);
|
||||
|
||||
/* anaparam2 on */
|
||||
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,
|
||||
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);
|
||||
|
||||
rtl8225_write_phy_ofdm(dev, 2, 0x42);
|
||||
rtl8225_write_phy_ofdm(dev, 5, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 6, 0x40);
|
||||
rtl8225_write_phy_ofdm(dev, 7, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 8, 0x40);
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
|
||||
rtl8225z2_tx_gain_cck_ofdm[ofdm_power]);
|
||||
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] << 1);
|
||||
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,
|
||||
0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
|
||||
0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
|
||||
0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
|
||||
0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
|
||||
0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
|
||||
0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
|
||||
0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
|
||||
0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
|
||||
0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
|
||||
0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
|
||||
};
|
||||
|
||||
static const u8 rtl8225z2_gain_bg[] = {
|
||||
0x23, 0x15, 0xa5, /* -82-1dBm */
|
||||
0x23, 0x15, 0xb5, /* -82-2dBm */
|
||||
0x23, 0x15, 0xc5, /* -82-3dBm */
|
||||
0x33, 0x15, 0xc5, /* -78dBm */
|
||||
0x43, 0x15, 0xc5, /* -74dBm */
|
||||
0x53, 0x15, 0xc5, /* -70dBm */
|
||||
0x63, 0x15, 0xc5 /* -66dBm */
|
||||
};
|
||||
|
||||
static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
int i;
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x2BF);
|
||||
rtl8225_write(dev, 0x1, 0xEE0);
|
||||
rtl8225_write(dev, 0x2, 0x44D);
|
||||
rtl8225_write(dev, 0x3, 0x441);
|
||||
rtl8225_write(dev, 0x4, 0x8C3);
|
||||
rtl8225_write(dev, 0x5, 0xC72);
|
||||
rtl8225_write(dev, 0x6, 0x0E6);
|
||||
rtl8225_write(dev, 0x7, 0x82A);
|
||||
rtl8225_write(dev, 0x8, 0x03F);
|
||||
rtl8225_write(dev, 0x9, 0x335);
|
||||
rtl8225_write(dev, 0xa, 0x9D4);
|
||||
rtl8225_write(dev, 0xb, 0x7BB);
|
||||
rtl8225_write(dev, 0xc, 0x850);
|
||||
rtl8225_write(dev, 0xd, 0xCDF);
|
||||
rtl8225_write(dev, 0xe, 0x02B);
|
||||
rtl8225_write(dev, 0xf, 0x114);
|
||||
msleep(100);
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x1B7);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
|
||||
rtl8225_write(dev, 0x1, i + 1);
|
||||
rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
|
||||
}
|
||||
|
||||
rtl8225_write(dev, 0x3, 0x080);
|
||||
rtl8225_write(dev, 0x5, 0x004);
|
||||
rtl8225_write(dev, 0x0, 0x0B7);
|
||||
rtl8225_write(dev, 0x2, 0xc4D);
|
||||
|
||||
msleep(200);
|
||||
rtl8225_write(dev, 0x2, 0x44D);
|
||||
msleep(100);
|
||||
|
||||
if (!(rtl8225_read(dev, 6) & (1 << 7))) {
|
||||
rtl8225_write(dev, 0x02, 0x0C4D);
|
||||
msleep(200);
|
||||
rtl8225_write(dev, 0x02, 0x044D);
|
||||
msleep(100);
|
||||
if (!(rtl8225_read(dev, 6) & (1 << 7)))
|
||||
printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
|
||||
wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
|
||||
}
|
||||
|
||||
msleep(200);
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x2BF);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
|
||||
rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
|
||||
rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
|
||||
}
|
||||
|
||||
msleep(1);
|
||||
|
||||
rtl8225_write_phy_ofdm(dev, 0x00, 0x01);
|
||||
rtl8225_write_phy_ofdm(dev, 0x01, 0x02);
|
||||
rtl8225_write_phy_ofdm(dev, 0x02, 0x42);
|
||||
rtl8225_write_phy_ofdm(dev, 0x03, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x04, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x05, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x06, 0x40);
|
||||
rtl8225_write_phy_ofdm(dev, 0x07, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x08, 0x40);
|
||||
rtl8225_write_phy_ofdm(dev, 0x09, 0xfe);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0a, 0x08);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0b, 0x80);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0c, 0x01);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3);
|
||||
rtl8225_write_phy_ofdm(dev, 0x0f, 0x38);
|
||||
rtl8225_write_phy_ofdm(dev, 0x10, 0x84);
|
||||
rtl8225_write_phy_ofdm(dev, 0x11, 0x07);
|
||||
rtl8225_write_phy_ofdm(dev, 0x12, 0x20);
|
||||
rtl8225_write_phy_ofdm(dev, 0x13, 0x20);
|
||||
rtl8225_write_phy_ofdm(dev, 0x14, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x15, 0x40);
|
||||
rtl8225_write_phy_ofdm(dev, 0x16, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x17, 0x40);
|
||||
rtl8225_write_phy_ofdm(dev, 0x18, 0xef);
|
||||
rtl8225_write_phy_ofdm(dev, 0x19, 0x19);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1a, 0x20);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1b, 0x15);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1c, 0x04);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1e, 0x95);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1f, 0x75);
|
||||
rtl8225_write_phy_ofdm(dev, 0x20, 0x1f);
|
||||
rtl8225_write_phy_ofdm(dev, 0x21, 0x17);
|
||||
rtl8225_write_phy_ofdm(dev, 0x22, 0x16);
|
||||
rtl8225_write_phy_ofdm(dev, 0x23, 0x80);
|
||||
rtl8225_write_phy_ofdm(dev, 0x24, 0x46);
|
||||
rtl8225_write_phy_ofdm(dev, 0x25, 0x00);
|
||||
rtl8225_write_phy_ofdm(dev, 0x26, 0x90);
|
||||
rtl8225_write_phy_ofdm(dev, 0x27, 0x88);
|
||||
|
||||
rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]);
|
||||
rtl8225_write_phy_ofdm(dev, 0x21, 0x37);
|
||||
|
||||
rtl8225_write_phy_cck(dev, 0x00, 0x98);
|
||||
rtl8225_write_phy_cck(dev, 0x03, 0x20);
|
||||
rtl8225_write_phy_cck(dev, 0x04, 0x7e);
|
||||
rtl8225_write_phy_cck(dev, 0x05, 0x12);
|
||||
rtl8225_write_phy_cck(dev, 0x06, 0xfc);
|
||||
rtl8225_write_phy_cck(dev, 0x07, 0x78);
|
||||
rtl8225_write_phy_cck(dev, 0x08, 0x2e);
|
||||
rtl8225_write_phy_cck(dev, 0x10, 0x9b);
|
||||
rtl8225_write_phy_cck(dev, 0x11, 0x88);
|
||||
rtl8225_write_phy_cck(dev, 0x12, 0x47);
|
||||
rtl8225_write_phy_cck(dev, 0x13, 0xd0);
|
||||
rtl8225_write_phy_cck(dev, 0x19, 0x00);
|
||||
rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
|
||||
rtl8225_write_phy_cck(dev, 0x1b, 0x08);
|
||||
rtl8225_write_phy_cck(dev, 0x40, 0x86);
|
||||
rtl8225_write_phy_cck(dev, 0x41, 0x8d);
|
||||
rtl8225_write_phy_cck(dev, 0x42, 0x15);
|
||||
rtl8225_write_phy_cck(dev, 0x43, 0x18);
|
||||
rtl8225_write_phy_cck(dev, 0x44, 0x36);
|
||||
rtl8225_write_phy_cck(dev, 0x45, 0x35);
|
||||
rtl8225_write_phy_cck(dev, 0x46, 0x2e);
|
||||
rtl8225_write_phy_cck(dev, 0x47, 0x25);
|
||||
rtl8225_write_phy_cck(dev, 0x48, 0x1c);
|
||||
rtl8225_write_phy_cck(dev, 0x49, 0x12);
|
||||
rtl8225_write_phy_cck(dev, 0x4a, 0x09);
|
||||
rtl8225_write_phy_cck(dev, 0x4b, 0x04);
|
||||
rtl8225_write_phy_cck(dev, 0x4c, 0x05);
|
||||
|
||||
rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1);
|
||||
|
||||
rtl8225z2_rf_set_tx_power(dev, 1);
|
||||
|
||||
/* RX antenna default to A */
|
||||
rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */
|
||||
rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
|
||||
msleep(1);
|
||||
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);
|
||||
rtl8225_write(dev, 0x1, 0xEE0);
|
||||
rtl8225_write(dev, 0x2, 0x44D);
|
||||
rtl8225_write(dev, 0x3, 0x441);
|
||||
rtl8225_write(dev, 0x4, 0x8C3);
|
||||
rtl8225_write(dev, 0x5, 0xC72);
|
||||
rtl8225_write(dev, 0x6, 0x0E6);
|
||||
rtl8225_write(dev, 0x7, 0x82A);
|
||||
rtl8225_write(dev, 0x8, 0x03F);
|
||||
rtl8225_write(dev, 0x9, 0x335);
|
||||
rtl8225_write(dev, 0xa, 0x9D4);
|
||||
rtl8225_write(dev, 0xb, 0x7BB);
|
||||
rtl8225_write(dev, 0xc, 0x850);
|
||||
rtl8225_write(dev, 0xd, 0xCDF);
|
||||
rtl8225_write(dev, 0xe, 0x02B);
|
||||
rtl8225_write(dev, 0xf, 0x114);
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x1B7);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
|
||||
rtl8225_write(dev, 0x1, i + 1);
|
||||
rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
|
||||
}
|
||||
|
||||
rtl8225_write(dev, 0x3, 0x080);
|
||||
rtl8225_write(dev, 0x5, 0x004);
|
||||
rtl8225_write(dev, 0x0, 0x0B7);
|
||||
|
||||
rtl8225_write(dev, 0x2, 0xC4D);
|
||||
|
||||
rtl8225_write(dev, 0x2, 0x44D);
|
||||
rtl8225_write(dev, 0x0, 0x2BF);
|
||||
|
||||
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_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);
|
||||
rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6);
|
||||
rtl8225_write_phy_ofdm(dev, 0x85, 0xfc);
|
||||
rtl8225_write_phy_cck(dev, 0xc1, 0x88);
|
||||
}
|
||||
|
||||
static void rtl8225_rf_stop(struct ieee80211_hw *dev)
|
||||
{
|
||||
u8 reg;
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
|
||||
rtl8225_write(dev, 0x4, 0x1f);
|
||||
|
||||
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);
|
||||
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_iowrite8(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);
|
||||
}
|
||||
|
||||
static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
|
||||
struct ieee80211_conf *conf)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
int chan = ieee80211_frequency_to_channel(conf->channel->center_freq);
|
||||
|
||||
if (priv->rf->init == rtl8225_rf_init)
|
||||
rtl8225_rf_set_tx_power(dev, chan);
|
||||
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);
|
||||
}
|
||||
|
||||
static const struct rtl818x_rf_ops rtl8225_ops = {
|
||||
.name = "rtl8225",
|
||||
.init = rtl8225_rf_init,
|
||||
.stop = rtl8225_rf_stop,
|
||||
.set_chan = rtl8225_rf_set_channel
|
||||
};
|
||||
|
||||
static const struct rtl818x_rf_ops rtl8225z2_ops = {
|
||||
.name = "rtl8225z2",
|
||||
.init = rtl8225z2_rf_init,
|
||||
.stop = rtl8225_rf_stop,
|
||||
.set_chan = rtl8225_rf_set_channel
|
||||
};
|
||||
|
||||
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);
|
||||
reg9 = rtl8225_read(dev, 9);
|
||||
|
||||
rtl8225_write(dev, 0, 0x0B7);
|
||||
|
||||
if (reg8 != 0x588 || reg9 != 0x700)
|
||||
return &rtl8225_ops;
|
||||
|
||||
return &rtl8225z2_ops;
|
||||
} else
|
||||
return &rtl8225z2_b_ops;
|
||||
}
|
44
drivers/net/wireless/rtl818x/rtl8187_rtl8225.h
Normal file
44
drivers/net/wireless/rtl818x/rtl8187_rtl8225.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Radio tuning definitions for RTL8225 on RTL8187
|
||||
*
|
||||
* Copyright 2007 Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Based on the r8187 driver, which is:
|
||||
* Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef RTL8187_RTL8225_H
|
||||
#define RTL8187_RTL8225_H
|
||||
|
||||
#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
|
||||
|
||||
const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *);
|
||||
|
||||
static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev,
|
||||
u8 addr, u32 data)
|
||||
{
|
||||
rtl8187_write_phy(dev, addr, data);
|
||||
}
|
||||
|
||||
static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev,
|
||||
u8 addr, u32 data)
|
||||
{
|
||||
rtl8187_write_phy(dev, addr, data | 0x10000);
|
||||
}
|
||||
|
||||
#endif /* RTL8187_RTL8225_H */
|
231
drivers/net/wireless/rtl818x/rtl818x.h
Normal file
231
drivers/net/wireless/rtl818x/rtl818x.h
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Definitions for RTL818x hardware
|
||||
*
|
||||
* Copyright 2007 Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Based on the r8187 driver, which is:
|
||||
* Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef RTL818X_H
|
||||
#define RTL818X_H
|
||||
|
||||
struct rtl818x_csr {
|
||||
u8 MAC[6];
|
||||
u8 reserved_0[2];
|
||||
__le32 MAR[2];
|
||||
u8 RX_FIFO_COUNT;
|
||||
u8 reserved_1;
|
||||
u8 TX_FIFO_COUNT;
|
||||
u8 BQREQ;
|
||||
u8 reserved_2[4];
|
||||
__le32 TSFT[2];
|
||||
__le32 TLPDA;
|
||||
__le32 TNPDA;
|
||||
__le32 THPDA;
|
||||
__le16 BRSR;
|
||||
u8 BSSID[6];
|
||||
u8 RESP_RATE;
|
||||
u8 EIFS;
|
||||
u8 reserved_3[1];
|
||||
u8 CMD;
|
||||
#define RTL818X_CMD_TX_ENABLE (1 << 2)
|
||||
#define RTL818X_CMD_RX_ENABLE (1 << 3)
|
||||
#define RTL818X_CMD_RESET (1 << 4)
|
||||
u8 reserved_4[4];
|
||||
__le16 INT_MASK;
|
||||
__le16 INT_STATUS;
|
||||
#define RTL818X_INT_RX_OK (1 << 0)
|
||||
#define RTL818X_INT_RX_ERR (1 << 1)
|
||||
#define RTL818X_INT_TXL_OK (1 << 2)
|
||||
#define RTL818X_INT_TXL_ERR (1 << 3)
|
||||
#define RTL818X_INT_RX_DU (1 << 4)
|
||||
#define RTL818X_INT_RX_FO (1 << 5)
|
||||
#define RTL818X_INT_TXN_OK (1 << 6)
|
||||
#define RTL818X_INT_TXN_ERR (1 << 7)
|
||||
#define RTL818X_INT_TXH_OK (1 << 8)
|
||||
#define RTL818X_INT_TXH_ERR (1 << 9)
|
||||
#define RTL818X_INT_TXB_OK (1 << 10)
|
||||
#define RTL818X_INT_TXB_ERR (1 << 11)
|
||||
#define RTL818X_INT_ATIM (1 << 12)
|
||||
#define RTL818X_INT_BEACON (1 << 13)
|
||||
#define RTL818X_INT_TIME_OUT (1 << 14)
|
||||
#define RTL818X_INT_TX_FO (1 << 15)
|
||||
__le32 TX_CONF;
|
||||
#define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17)
|
||||
#define RTL818X_TX_CONF_LOOPBACK_CONT (3 << 17)
|
||||
#define RTL818X_TX_CONF_NO_ICV (1 << 19)
|
||||
#define RTL818X_TX_CONF_DISCW (1 << 20)
|
||||
#define RTL818X_TX_CONF_SAT_HWPLCP (1 << 24)
|
||||
#define RTL818X_TX_CONF_R8180_ABCD (2 << 25)
|
||||
#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 (5 << 25)
|
||||
#define RTL818X_TX_CONF_R8187vD_B (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)
|
||||
__le32 RX_CONF;
|
||||
#define RTL818X_RX_CONF_MONITOR (1 << 0)
|
||||
#define RTL818X_RX_CONF_NICMAC (1 << 1)
|
||||
#define RTL818X_RX_CONF_MULTICAST (1 << 2)
|
||||
#define RTL818X_RX_CONF_BROADCAST (1 << 3)
|
||||
#define RTL818X_RX_CONF_FCS (1 << 5)
|
||||
#define RTL818X_RX_CONF_DATA (1 << 18)
|
||||
#define RTL818X_RX_CONF_CTRL (1 << 19)
|
||||
#define RTL818X_RX_CONF_MGMT (1 << 20)
|
||||
#define RTL818X_RX_CONF_ADDR3 (1 << 21)
|
||||
#define RTL818X_RX_CONF_PM (1 << 22)
|
||||
#define RTL818X_RX_CONF_BSSID (1 << 23)
|
||||
#define RTL818X_RX_CONF_RX_AUTORESETPHY (1 << 28)
|
||||
#define RTL818X_RX_CONF_CSDM1 (1 << 29)
|
||||
#define RTL818X_RX_CONF_CSDM2 (1 << 30)
|
||||
#define RTL818X_RX_CONF_ONLYERLPKT (1 << 31)
|
||||
__le32 INT_TIMEOUT;
|
||||
__le32 TBDA;
|
||||
u8 EEPROM_CMD;
|
||||
#define RTL818X_EEPROM_CMD_READ (1 << 0)
|
||||
#define RTL818X_EEPROM_CMD_WRITE (1 << 1)
|
||||
#define RTL818X_EEPROM_CMD_CK (1 << 2)
|
||||
#define RTL818X_EEPROM_CMD_CS (1 << 3)
|
||||
#define RTL818X_EEPROM_CMD_NORMAL (0 << 6)
|
||||
#define RTL818X_EEPROM_CMD_LOAD (1 << 6)
|
||||
#define RTL818X_EEPROM_CMD_PROGRAM (2 << 6)
|
||||
#define RTL818X_EEPROM_CMD_CONFIG (3 << 6)
|
||||
u8 CONFIG0;
|
||||
u8 CONFIG1;
|
||||
u8 CONFIG2;
|
||||
#define RTL818X_CONFIG2_ANTENNA_DIV (1 << 6)
|
||||
__le32 ANAPARAM;
|
||||
u8 MSR;
|
||||
#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)
|
||||
u8 TESTR;
|
||||
u8 reserved_9[2];
|
||||
u8 PGSELECT;
|
||||
u8 SECURITY;
|
||||
__le32 ANAPARAM2;
|
||||
u8 reserved_10[12];
|
||||
__le16 BEACON_INTERVAL;
|
||||
__le16 ATIM_WND;
|
||||
__le16 BEACON_INTERVAL_TIME;
|
||||
__le16 ATIMTR_INTERVAL;
|
||||
u8 PHY_DELAY;
|
||||
u8 CARRIER_SENSE_COUNTER;
|
||||
u8 reserved_11[2];
|
||||
u8 PHY[4];
|
||||
__le16 RFPinsOutput;
|
||||
__le16 RFPinsEnable;
|
||||
__le16 RFPinsSelect;
|
||||
__le16 RFPinsInput;
|
||||
__le32 RF_PARA;
|
||||
__le32 RF_TIMING;
|
||||
u8 GP_ENABLE;
|
||||
u8 GPIO;
|
||||
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)
|
||||
#define RTL818X_TX_AGC_CTL_FEEDBACK_ANT (1 << 2)
|
||||
u8 TX_GAIN_CCK;
|
||||
u8 TX_GAIN_OFDM;
|
||||
u8 TX_ANTENNA;
|
||||
u8 reserved_14[16];
|
||||
u8 WPA_CONF;
|
||||
u8 reserved_15[3];
|
||||
u8 SIFS;
|
||||
u8 DIFS;
|
||||
u8 SLOT;
|
||||
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;
|
||||
#define RTL818X_RATE_FALLBACK_ENABLE (1 << 7)
|
||||
u8 ACM_CONTROL;
|
||||
u8 reserved_17[24];
|
||||
u8 CONFIG5;
|
||||
u8 TX_DMA_POLLING;
|
||||
u8 reserved_18[2];
|
||||
__le16 CWR;
|
||||
u8 RETRY_CTR;
|
||||
u8 reserved_19[3];
|
||||
__le16 INT_MIG;
|
||||
/* RTL818X_R8187B_*: magic numbers from ioregisters */
|
||||
#define RTL818X_R8187B_B 0
|
||||
#define RTL818X_R8187B_D 1
|
||||
#define RTL818X_R8187B_E 2
|
||||
__le32 RDSAR;
|
||||
__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));
|
||||
|
||||
struct rtl818x_rf_ops {
|
||||
char *name;
|
||||
void (*init)(struct ieee80211_hw *);
|
||||
void (*stop)(struct ieee80211_hw *);
|
||||
void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
|
||||
};
|
||||
|
||||
/* Tx/Rx flags are common between RTL818X chips */
|
||||
|
||||
enum rtl818x_tx_desc_flags {
|
||||
RTL818X_TX_DESC_FLAG_NO_ENC = (1 << 15),
|
||||
RTL818X_TX_DESC_FLAG_TX_OK = (1 << 15),
|
||||
RTL818X_TX_DESC_FLAG_SPLCP = (1 << 16),
|
||||
RTL818X_TX_DESC_FLAG_RX_UNDER = (1 << 16),
|
||||
RTL818X_TX_DESC_FLAG_MOREFRAG = (1 << 17),
|
||||
RTL818X_TX_DESC_FLAG_CTS = (1 << 18),
|
||||
RTL818X_TX_DESC_FLAG_RTS = (1 << 23),
|
||||
RTL818X_TX_DESC_FLAG_LS = (1 << 28),
|
||||
RTL818X_TX_DESC_FLAG_FS = (1 << 29),
|
||||
RTL818X_TX_DESC_FLAG_DMA = (1 << 30),
|
||||
RTL818X_TX_DESC_FLAG_OWN = (1 << 31)
|
||||
};
|
||||
|
||||
enum rtl818x_rx_desc_flags {
|
||||
RTL818X_RX_DESC_FLAG_ICV_ERR = (1 << 12),
|
||||
RTL818X_RX_DESC_FLAG_CRC32_ERR = (1 << 13),
|
||||
RTL818X_RX_DESC_FLAG_PM = (1 << 14),
|
||||
RTL818X_RX_DESC_FLAG_RX_ERR = (1 << 15),
|
||||
RTL818X_RX_DESC_FLAG_BCAST = (1 << 16),
|
||||
RTL818X_RX_DESC_FLAG_PAM = (1 << 17),
|
||||
RTL818X_RX_DESC_FLAG_MCAST = (1 << 18),
|
||||
RTL818X_RX_DESC_FLAG_QOS = (1 << 19), /* RTL8187(B) only */
|
||||
RTL818X_RX_DESC_FLAG_TRSW = (1 << 24), /* RTL8187(B) only */
|
||||
RTL818X_RX_DESC_FLAG_SPLCP = (1 << 25),
|
||||
RTL818X_RX_DESC_FLAG_FOF = (1 << 26),
|
||||
RTL818X_RX_DESC_FLAG_DMA_FAIL = (1 << 27),
|
||||
RTL818X_RX_DESC_FLAG_LS = (1 << 28),
|
||||
RTL818X_RX_DESC_FLAG_FS = (1 << 29),
|
||||
RTL818X_RX_DESC_FLAG_EOR = (1 << 30),
|
||||
RTL818X_RX_DESC_FLAG_OWN = (1 << 31)
|
||||
};
|
||||
|
||||
#endif /* RTL818X_H */
|
Fai riferimento in un nuovo problema
Block a user