aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/phy.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2007-09-20 16:14:18 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:52:24 -0400
commitfda9abcf1a5b6b78a4ead25729583541af9876b5 (patch)
treead8029180557a5c4dce3f0a4e7c118bffca25eef /drivers/net/wireless/b43/phy.c
parent6a724d68a38c33ba4c7f7b5f008301ac12c9ced1 (diff)
[B43]: Support for turning the radio off from software.
This adds support for turning the radio off in software. That's useful in environments, where you don't want the RF to radiate any signals, but don't want to bring the interface down. Cc: Larry Finger <larry.finger@lwfinger.net> Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/b43/phy.c')
-rw-r--r--drivers/net/wireless/b43/phy.c48
1 files changed, 36 insertions, 12 deletions
diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c
index 3282893021b0..354d18238752 100644
--- a/drivers/net/wireless/b43/phy.c
+++ b/drivers/net/wireless/b43/phy.c
@@ -1205,10 +1205,7 @@ static void b43_phy_initb2(struct b43_wldev *dev)
1205 val -= 0x0202; 1205 val -= 0x0202;
1206 } 1206 }
1207 b43_phy_write(dev, 0x03E4, 0x3000); 1207 b43_phy_write(dev, 0x03E4, 0x3000);
1208 if (phy->channel == 0xFF) 1208 b43_radio_selectchannel(dev, phy->channel, 0);
1209 b43_radio_selectchannel(dev, B43_DEFAULT_CHANNEL_BG, 0);
1210 else
1211 b43_radio_selectchannel(dev, phy->channel, 0);
1212 if (phy->radio_ver != 0x2050) { 1209 if (phy->radio_ver != 0x2050) {
1213 b43_radio_write16(dev, 0x0075, 0x0080); 1210 b43_radio_write16(dev, 0x0075, 0x0080);
1214 b43_radio_write16(dev, 0x0079, 0x0081); 1211 b43_radio_write16(dev, 0x0079, 0x0081);
@@ -1256,10 +1253,7 @@ static void b43_phy_initb4(struct b43_wldev *dev)
1256 val -= 0x0202; 1253 val -= 0x0202;
1257 } 1254 }
1258 b43_phy_write(dev, 0x03E4, 0x3000); 1255 b43_phy_write(dev, 0x03E4, 0x3000);
1259 if (phy->channel == 0xFF) 1256 b43_radio_selectchannel(dev, phy->channel, 0);
1260 b43_radio_selectchannel(dev, B43_DEFAULT_CHANNEL_BG, 0);
1261 else
1262 b43_radio_selectchannel(dev, phy->channel, 0);
1263 if (phy->radio_ver != 0x2050) { 1257 if (phy->radio_ver != 0x2050) {
1264 b43_radio_write16(dev, 0x0075, 0x0080); 1258 b43_radio_write16(dev, 0x0075, 0x0080);
1265 b43_radio_write16(dev, 0x0079, 0x0081); 1259 b43_radio_write16(dev, 0x0079, 0x0081);
@@ -4110,6 +4104,20 @@ int b43_radio_selectchannel(struct b43_wldev *dev,
4110 u16 freq; 4104 u16 freq;
4111 u16 channelcookie; 4105 u16 channelcookie;
4112 4106
4107 if (channel == 0xFF) {
4108 switch (phy->type) {
4109 case B43_PHYTYPE_A:
4110 channel = B43_DEFAULT_CHANNEL_A;
4111 break;
4112 case B43_PHYTYPE_B:
4113 case B43_PHYTYPE_G:
4114 channel = B43_DEFAULT_CHANNEL_BG;
4115 break;
4116 default:
4117 B43_WARN_ON(1);
4118 }
4119 }
4120
4113 /* First we set the channel radio code to prevent the 4121 /* First we set the channel radio code to prevent the
4114 * firmware from sending ghost packets. 4122 * firmware from sending ghost packets.
4115 */ 4123 */
@@ -4302,6 +4310,7 @@ void b43_radio_turn_on(struct b43_wldev *dev)
4302{ 4310{
4303 struct b43_phy *phy = &dev->phy; 4311 struct b43_phy *phy = &dev->phy;
4304 int err; 4312 int err;
4313 u8 channel;
4305 4314
4306 might_sleep(); 4315 might_sleep();
4307 4316
@@ -4321,14 +4330,23 @@ void b43_radio_turn_on(struct b43_wldev *dev)
4321 b43_phy_write(dev, 0x0015, 0x8000); 4330 b43_phy_write(dev, 0x0015, 0x8000);
4322 b43_phy_write(dev, 0x0015, 0xCC00); 4331 b43_phy_write(dev, 0x0015, 0xCC00);
4323 b43_phy_write(dev, 0x0015, (phy->gmode ? 0x00C0 : 0x0000)); 4332 b43_phy_write(dev, 0x0015, (phy->gmode ? 0x00C0 : 0x0000));
4333 if (phy->radio_off_context.valid) {
4334 /* Restore the RFover values. */
4335 b43_phy_write(dev, B43_PHY_RFOVER,
4336 phy->radio_off_context.rfover);
4337 b43_phy_write(dev, B43_PHY_RFOVERVAL,
4338 phy->radio_off_context.rfoverval);
4339 phy->radio_off_context.valid = 0;
4340 }
4341 channel = phy->channel;
4324 err = b43_radio_selectchannel(dev, B43_DEFAULT_CHANNEL_BG, 1); 4342 err = b43_radio_selectchannel(dev, B43_DEFAULT_CHANNEL_BG, 1);
4343 err |= b43_radio_selectchannel(dev, channel, 0);
4325 B43_WARN_ON(err); 4344 B43_WARN_ON(err);
4326 break; 4345 break;
4327 default: 4346 default:
4328 B43_WARN_ON(1); 4347 B43_WARN_ON(1);
4329 } 4348 }
4330 phy->radio_on = 1; 4349 phy->radio_on = 1;
4331 b43dbg(dev->wl, "Radio turned on\n");
4332} 4350}
4333 4351
4334void b43_radio_turn_off(struct b43_wldev *dev) 4352void b43_radio_turn_off(struct b43_wldev *dev)
@@ -4342,10 +4360,16 @@ void b43_radio_turn_off(struct b43_wldev *dev)
4342 b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008); 4360 b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008);
4343 } 4361 }
4344 if (phy->type == B43_PHYTYPE_G && dev->dev->id.revision >= 5) { 4362 if (phy->type == B43_PHYTYPE_G && dev->dev->id.revision >= 5) {
4345 b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x008C); 4363 u16 rfover, rfoverval;
4346 b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) & 0xFF73); 4364
4365 rfover = b43_phy_read(dev, B43_PHY_RFOVER);
4366 rfoverval = b43_phy_read(dev, B43_PHY_RFOVERVAL);
4367 phy->radio_off_context.rfover = rfover;
4368 phy->radio_off_context.rfoverval = rfoverval;
4369 phy->radio_off_context.valid = 1;
4370 b43_phy_write(dev, B43_PHY_RFOVER, rfover | 0x008C);
4371 b43_phy_write(dev, B43_PHY_RFOVERVAL, rfoverval & 0xFF73);
4347 } else 4372 } else
4348 b43_phy_write(dev, 0x0015, 0xAA00); 4373 b43_phy_write(dev, 0x0015, 0xAA00);
4349 phy->radio_on = 0; 4374 phy->radio_on = 0;
4350 b43dbg(dev->wl, "Radio turned off\n");
4351} 4375}