00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <unistd.h>
00024 #include <gpxe/pci.h>
00025 #include <gpxe/net80211.h>
00026
00027 #include "rtl818x.h"
00028
00029 FILE_LICENCE(GPL2_ONLY);
00030
00031 #define SA2400_ANTENNA 0x91
00032 #define SA2400_DIG_ANAPARAM_PWR1_ON 0x8
00033 #define SA2400_ANA_ANAPARAM_PWR1_ON 0x28
00034 #define SA2400_ANAPARAM_PWR0_ON 0x3
00035
00036
00037 #define SA2400_MAX_SENS 85
00038
00039 #define SA2400_REG4_FIRDAC_SHIFT 7
00040
00041 static const u32 sa2400_chan[] = {
00042 0x00096c,
00043 0x080970,
00044 0x100974,
00045 0x180978,
00046 0x000980,
00047 0x080984,
00048 0x100988,
00049 0x18098c,
00050 0x000994,
00051 0x080998,
00052 0x10099c,
00053 0x1809a0,
00054 0x0009a8,
00055 0x0009b4,
00056 };
00057
00058 static void write_sa2400(struct net80211_device *dev, u8 addr, u32 data)
00059 {
00060 struct rtl818x_priv *priv = dev->priv;
00061 u32 phy_config;
00062
00063
00064 phy_config = 0xb0000000;
00065
00066 phy_config |= ((u32)(addr & 0xf)) << 24;
00067 phy_config |= data & 0xffffff;
00068
00069
00070
00071 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, phy_config & 0xffff);
00072 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, phy_config >> 16);
00073
00074 mdelay(3);
00075 }
00076
00077 static void sa2400_write_phy_antenna(struct net80211_device *dev, short chan)
00078 {
00079 struct rtl818x_priv *priv = dev->priv;
00080 u8 ant = SA2400_ANTENNA;
00081
00082 if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
00083 ant |= BB_ANTENNA_B;
00084
00085 if (chan == 14)
00086 ant |= BB_ANTATTEN_CHAN14;
00087
00088 rtl818x_write_phy(dev, 0x10, ant);
00089
00090 }
00091
00092 static void sa2400_rf_set_channel(struct net80211_device *dev,
00093 struct net80211_channel *channelp)
00094 {
00095 struct rtl818x_priv *priv = dev->priv;
00096 int channel = channelp->channel_nr;
00097 u32 txpw = priv->txpower[channel - 1] & 0xFF;
00098 u32 chan = sa2400_chan[channel - 1];
00099
00100 write_sa2400(dev, 7, txpw);
00101
00102 sa2400_write_phy_antenna(dev, channel);
00103
00104 write_sa2400(dev, 0, chan);
00105 write_sa2400(dev, 1, 0xbb50);
00106 write_sa2400(dev, 2, 0x80);
00107 write_sa2400(dev, 3, 0);
00108 }
00109
00110 static void sa2400_rf_stop(struct net80211_device *dev)
00111 {
00112 write_sa2400(dev, 4, 0);
00113 }
00114
00115 static void sa2400_rf_init(struct net80211_device *dev)
00116 {
00117 struct rtl818x_priv *priv = dev->priv;
00118 u32 anaparam, txconf;
00119 u8 firdac;
00120 int analogphy = priv->rfparam & RF_PARAM_ANALOGPHY;
00121
00122 anaparam = priv->anaparam;
00123 anaparam &= ~(1 << ANAPARAM_TXDACOFF_SHIFT);
00124 anaparam &= ~ANAPARAM_PWR1_MASK;
00125 anaparam &= ~ANAPARAM_PWR0_MASK;
00126
00127 if (analogphy) {
00128 anaparam |= SA2400_ANA_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT;
00129 firdac = 0;
00130 } else {
00131 anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT);
00132 anaparam |= (SA2400_ANAPARAM_PWR0_ON << ANAPARAM_PWR0_SHIFT);
00133 firdac = 1 << SA2400_REG4_FIRDAC_SHIFT;
00134 }
00135
00136 rtl818x_set_anaparam(priv, anaparam);
00137
00138 write_sa2400(dev, 0, sa2400_chan[0]);
00139 write_sa2400(dev, 1, 0xbb50);
00140 write_sa2400(dev, 2, 0x80);
00141 write_sa2400(dev, 3, 0);
00142 write_sa2400(dev, 4, 0x19340 | firdac);
00143 write_sa2400(dev, 5, 0x1dfb | (SA2400_MAX_SENS - 54) << 15);
00144 write_sa2400(dev, 4, 0x19348 | firdac);
00145
00146 if (!analogphy)
00147 write_sa2400(dev, 4, 0x1938c);
00148
00149 write_sa2400(dev, 4, 0x19340 | firdac);
00150
00151 write_sa2400(dev, 0, sa2400_chan[0]);
00152 write_sa2400(dev, 1, 0xbb50);
00153 write_sa2400(dev, 2, 0x80);
00154 write_sa2400(dev, 3, 0);
00155 write_sa2400(dev, 4, 0x19344 | firdac);
00156
00157
00158 write_sa2400(dev, 6, 0x13ff | (1 << 23));
00159 write_sa2400(dev, 8, 0);
00160
00161 if (analogphy) {
00162 rtl818x_set_anaparam(priv, anaparam |
00163 (1 << ANAPARAM_TXDACOFF_SHIFT));
00164
00165 txconf = rtl818x_ioread32(priv, &priv->map->TX_CONF);
00166 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
00167 txconf | RTL818X_TX_CONF_LOOPBACK_CONT);
00168
00169 write_sa2400(dev, 4, 0x19341);
00170
00171
00172
00173
00174 write_sa2400(dev, 4, 0x19345);
00175
00176
00177
00178
00179 rtl818x_iowrite32(priv, &priv->map->TX_CONF, txconf);
00180
00181 rtl818x_set_anaparam(priv, anaparam);
00182 }
00183
00184
00185 write_sa2400(dev, 4, 0x19341 | firdac);
00186
00187
00188 rtl818x_write_phy(dev, 0, 0x98);
00189 rtl818x_write_phy(dev, 3, 0x38);
00190 rtl818x_write_phy(dev, 4, 0xe0);
00191 rtl818x_write_phy(dev, 5, 0x90);
00192 rtl818x_write_phy(dev, 6, 0x1a);
00193 rtl818x_write_phy(dev, 7, 0x64);
00194
00195 sa2400_write_phy_antenna(dev, 1);
00196
00197 rtl818x_write_phy(dev, 0x11, 0x80);
00198
00199 if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
00200 RTL818X_CONFIG2_ANTENNA_DIV)
00201 rtl818x_write_phy(dev, 0x12, 0xc7);
00202 else
00203 rtl818x_write_phy(dev, 0x12, 0x47);
00204
00205 rtl818x_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
00206
00207 rtl818x_write_phy(dev, 0x19, 0x0);
00208 rtl818x_write_phy(dev, 0x1a, 0xa0);
00209 }
00210
00211 struct rtl818x_rf_ops sa2400_rf_ops __rtl818x_rf_driver = {
00212 .name = "Philips SA2400",
00213 .id = 3,
00214 .init = sa2400_rf_init,
00215 .stop = sa2400_rf_stop,
00216 .set_chan = sa2400_rf_set_channel
00217 };