aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h11
-rw-r--r--drivers/net/wireless/b43legacy/main.c16
-rw-r--r--drivers/net/wireless/b43legacy/phy.c14
-rw-r--r--drivers/net/wireless/b43legacy/radio.c39
4 files changed, 61 insertions, 19 deletions
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index 34a6277051a1..746de2ff498c 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -411,7 +411,6 @@ struct b43legacy_phy {
411 u8 calibrated:1; 411 u8 calibrated:1;
412 u8 radio_rev; /* Radio revision */ 412 u8 radio_rev; /* Radio revision */
413 413
414 bool radio_on; /* Radio switched on/off */
415 bool locked; /* Only used in b43legacy_phy_{un}lock() */ 414 bool locked; /* Only used in b43legacy_phy_{un}lock() */
416 bool dyn_tssi_tbl; /* tssi2dbm is kmalloc()ed. */ 415 bool dyn_tssi_tbl; /* tssi2dbm is kmalloc()ed. */
417 416
@@ -420,6 +419,16 @@ struct b43legacy_phy {
420 bool aci_wlan_automatic; 419 bool aci_wlan_automatic;
421 bool aci_hw_rssi; 420 bool aci_hw_rssi;
422 421
422 /* Radio switched on/off */
423 bool radio_on;
424 struct {
425 /* Values saved when turning the radio off.
426 * They are needed when turning it on again. */
427 bool valid;
428 u16 rfover;
429 u16 rfoverval;
430 } radio_off_context;
431
423 u16 minlowsig[2]; 432 u16 minlowsig[2];
424 u16 minlowsigpos[2]; 433 u16 minlowsigpos[2];
425 434
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 61b94218094b..3e935d0d4b80 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2660,6 +2660,22 @@ static int b43legacy_dev_config(struct ieee80211_hw *hw,
2660 b43legacy_set_beacon_int(dev, conf->beacon_int); 2660 b43legacy_set_beacon_int(dev, conf->beacon_int);
2661 2661
2662 2662
2663 if (!!conf->radio_enabled != phy->radio_on) {
2664 if (conf->radio_enabled) {
2665 b43legacy_radio_turn_on(dev);
2666 b43legacyinfo(dev->wl, "Radio turned on by software\n");
2667 if (!dev->radio_hw_enable)
2668 b43legacyinfo(dev->wl, "The hardware RF-kill"
2669 " button still turns the radio"
2670 " physically off. Press the"
2671 " button to turn it on.\n");
2672 } else {
2673 b43legacy_radio_turn_off(dev);
2674 b43legacyinfo(dev->wl, "Radio turned off by"
2675 " software\n");
2676 }
2677 }
2678
2663 spin_lock_irqsave(&wl->irq_lock, flags); 2679 spin_lock_irqsave(&wl->irq_lock, flags);
2664 b43legacy_interrupt_enable(dev, savedirqs); 2680 b43legacy_interrupt_enable(dev, savedirqs);
2665 mmiowb(); 2681 mmiowb();
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index f9edbd5f3009..22a4b3d0186d 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -462,12 +462,7 @@ static void b43legacy_phy_initb2(struct b43legacy_wldev *dev)
462 val -= 0x0202; 462 val -= 0x0202;
463 } 463 }
464 b43legacy_phy_write(dev, 0x03E4, 0x3000); 464 b43legacy_phy_write(dev, 0x03E4, 0x3000);
465 if (phy->channel == 0xFF) 465 b43legacy_radio_selectchannel(dev, phy->channel, 0);
466 b43legacy_radio_selectchannel(dev,
467 B43legacy_RADIO_DEFAULT_CHANNEL_BG,
468 0);
469 else
470 b43legacy_radio_selectchannel(dev, phy->channel, 0);
471 if (phy->radio_ver != 0x2050) { 466 if (phy->radio_ver != 0x2050) {
472 b43legacy_radio_write16(dev, 0x0075, 0x0080); 467 b43legacy_radio_write16(dev, 0x0075, 0x0080);
473 b43legacy_radio_write16(dev, 0x0079, 0x0081); 468 b43legacy_radio_write16(dev, 0x0079, 0x0081);
@@ -516,12 +511,7 @@ static void b43legacy_phy_initb4(struct b43legacy_wldev *dev)
516 val -= 0x0202; 511 val -= 0x0202;
517 } 512 }
518 b43legacy_phy_write(dev, 0x03E4, 0x3000); 513 b43legacy_phy_write(dev, 0x03E4, 0x3000);
519 if (phy->channel == 0xFF) 514 b43legacy_radio_selectchannel(dev, phy->channel, 0);
520 b43legacy_radio_selectchannel(dev,
521 B43legacy_RADIO_DEFAULT_CHANNEL_BG,
522 0);
523 else
524 b43legacy_radio_selectchannel(dev, phy->channel, 0);
525 if (phy->radio_ver != 0x2050) { 515 if (phy->radio_ver != 0x2050) {
526 b43legacy_radio_write16(dev, 0x0075, 0x0080); 516 b43legacy_radio_write16(dev, 0x0075, 0x0080);
527 b43legacy_radio_write16(dev, 0x0079, 0x0081); 517 b43legacy_radio_write16(dev, 0x0079, 0x0081);
diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c
index 2a11ee63f400..54067f082825 100644
--- a/drivers/net/wireless/b43legacy/radio.c
+++ b/drivers/net/wireless/b43legacy/radio.c
@@ -1767,6 +1767,17 @@ int b43legacy_radio_selectchannel(struct b43legacy_wldev *dev,
1767{ 1767{
1768 struct b43legacy_phy *phy = &dev->phy; 1768 struct b43legacy_phy *phy = &dev->phy;
1769 1769
1770 if (channel == 0xFF) {
1771 switch (phy->type) {
1772 case B43legacy_PHYTYPE_B:
1773 case B43legacy_PHYTYPE_G:
1774 channel = B43legacy_RADIO_DEFAULT_CHANNEL_BG;
1775 break;
1776 default:
1777 B43legacy_WARN_ON(1);
1778 }
1779 }
1780
1770/* TODO: Check if channel is valid - return -EINVAL if not */ 1781/* TODO: Check if channel is valid - return -EINVAL if not */
1771 if (synthetic_pu_workaround) 1782 if (synthetic_pu_workaround)
1772 b43legacy_synth_pu_workaround(dev, channel); 1783 b43legacy_synth_pu_workaround(dev, channel);
@@ -2070,6 +2081,7 @@ void b43legacy_radio_turn_on(struct b43legacy_wldev *dev)
2070{ 2081{
2071 struct b43legacy_phy *phy = &dev->phy; 2082 struct b43legacy_phy *phy = &dev->phy;
2072 int err; 2083 int err;
2084 u8 channel;
2073 2085
2074 might_sleep(); 2086 might_sleep();
2075 2087
@@ -2083,15 +2095,24 @@ void b43legacy_radio_turn_on(struct b43legacy_wldev *dev)
2083 b43legacy_phy_write(dev, 0x0015, 0xCC00); 2095 b43legacy_phy_write(dev, 0x0015, 0xCC00);
2084 b43legacy_phy_write(dev, 0x0015, 2096 b43legacy_phy_write(dev, 0x0015,
2085 (phy->gmode ? 0x00C0 : 0x0000)); 2097 (phy->gmode ? 0x00C0 : 0x0000));
2098 if (phy->radio_off_context.valid) {
2099 /* Restore the RFover values. */
2100 b43legacy_phy_write(dev, B43legacy_PHY_RFOVER,
2101 phy->radio_off_context.rfover);
2102 b43legacy_phy_write(dev, B43legacy_PHY_RFOVERVAL,
2103 phy->radio_off_context.rfoverval);
2104 phy->radio_off_context.valid = 0;
2105 }
2106 channel = phy->channel;
2086 err = b43legacy_radio_selectchannel(dev, 2107 err = b43legacy_radio_selectchannel(dev,
2087 B43legacy_RADIO_DEFAULT_CHANNEL_BG, 1); 2108 B43legacy_RADIO_DEFAULT_CHANNEL_BG, 1);
2088 B43legacy_WARN_ON(err != 0); 2109 err |= b43legacy_radio_selectchannel(dev, channel, 0);
2110 B43legacy_WARN_ON(err);
2089 break; 2111 break;
2090 default: 2112 default:
2091 B43legacy_BUG_ON(1); 2113 B43legacy_BUG_ON(1);
2092 } 2114 }
2093 phy->radio_on = 1; 2115 phy->radio_on = 1;
2094 b43legacydbg(dev->wl, "Radio turned on\n");
2095 b43legacy_leds_update(dev, 0); 2116 b43legacy_leds_update(dev, 0);
2096} 2117}
2097 2118
@@ -2100,10 +2121,16 @@ void b43legacy_radio_turn_off(struct b43legacy_wldev *dev)
2100 struct b43legacy_phy *phy = &dev->phy; 2121 struct b43legacy_phy *phy = &dev->phy;
2101 2122
2102 if (phy->type == B43legacy_PHYTYPE_G && dev->dev->id.revision >= 5) { 2123 if (phy->type == B43legacy_PHYTYPE_G && dev->dev->id.revision >= 5) {
2103 b43legacy_phy_write(dev, 0x0811, b43legacy_phy_read(dev, 0x0811) 2124 u16 rfover, rfoverval;
2104 | 0x008C); 2125
2105 b43legacy_phy_write(dev, 0x0812, b43legacy_phy_read(dev, 0x0812) 2126 rfover = b43legacy_phy_read(dev, B43legacy_PHY_RFOVER);
2106 & 0xFF73); 2127 rfoverval = b43legacy_phy_read(dev, B43legacy_PHY_RFOVERVAL);
2128 phy->radio_off_context.rfover = rfover;
2129 phy->radio_off_context.rfoverval = rfoverval;
2130 phy->radio_off_context.valid = 1;
2131 b43legacy_phy_write(dev, B43legacy_PHY_RFOVER, rfover | 0x008C);
2132 b43legacy_phy_write(dev, B43legacy_PHY_RFOVERVAL,
2133 rfoverval & 0xFF73);
2107 } else 2134 } else
2108 b43legacy_phy_write(dev, 0x0015, 0xAA00); 2135 b43legacy_phy_write(dev, 0x0015, 0xAA00);
2109 phy->radio_on = 0; 2136 phy->radio_on = 0;