aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h7
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.c11
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c36
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_radio.c2
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_radio.h16
5 files changed, 58 insertions, 14 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 8286678513b9..3a064def162e 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -352,6 +352,10 @@
352#define BCM43xx_UCODEFLAG_UNKPACTRL 0x0040 352#define BCM43xx_UCODEFLAG_UNKPACTRL 0x0040
353#define BCM43xx_UCODEFLAG_JAPAN 0x0080 353#define BCM43xx_UCODEFLAG_JAPAN 0x0080
354 354
355/* Hardware Radio Enable masks */
356#define BCM43xx_MMIO_RADIO_HWENABLED_HI_MASK (1 << 16)
357#define BCM43xx_MMIO_RADIO_HWENABLED_LO_MASK (1 << 4)
358
355/* Generic-Interrupt reasons. */ 359/* Generic-Interrupt reasons. */
356#define BCM43xx_IRQ_READY (1 << 0) 360#define BCM43xx_IRQ_READY (1 << 0)
357#define BCM43xx_IRQ_BEACON (1 << 1) 361#define BCM43xx_IRQ_BEACON (1 << 1)
@@ -758,7 +762,8 @@ struct bcm43xx_private {
758 bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */ 762 bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */
759 reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */ 763 reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */
760 short_preamble:1, /* TRUE, if short preamble is enabled. */ 764 short_preamble:1, /* TRUE, if short preamble is enabled. */
761 firmware_norelease:1; /* Do not release the firmware. Used on suspend. */ 765 firmware_norelease:1, /* Do not release the firmware. Used on suspend. */
766 radio_hw_enable:1; /* TRUE if radio is hardware enabled */
762 767
763 struct bcm43xx_stats stats; 768 struct bcm43xx_stats stats;
764 769
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
index 7d383a27b927..8f198befba39 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
@@ -26,6 +26,7 @@
26*/ 26*/
27 27
28#include "bcm43xx_leds.h" 28#include "bcm43xx_leds.h"
29#include "bcm43xx_radio.h"
29#include "bcm43xx.h" 30#include "bcm43xx.h"
30 31
31#include <asm/bitops.h> 32#include <asm/bitops.h>
@@ -108,6 +109,7 @@ static void bcm43xx_led_init_hardcoded(struct bcm43xx_private *bcm,
108 switch (led_index) { 109 switch (led_index) {
109 case 0: 110 case 0:
110 led->behaviour = BCM43xx_LED_ACTIVITY; 111 led->behaviour = BCM43xx_LED_ACTIVITY;
112 led->activelow = 1;
111 if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ) 113 if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ)
112 led->behaviour = BCM43xx_LED_RADIO_ALL; 114 led->behaviour = BCM43xx_LED_RADIO_ALL;
113 break; 115 break;
@@ -199,20 +201,21 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
199 turn_on = activity; 201 turn_on = activity;
200 break; 202 break;
201 case BCM43xx_LED_RADIO_ALL: 203 case BCM43xx_LED_RADIO_ALL:
202 turn_on = radio->enabled; 204 turn_on = radio->enabled && bcm43xx_is_hw_radio_enabled(bcm);
203 break; 205 break;
204 case BCM43xx_LED_RADIO_A: 206 case BCM43xx_LED_RADIO_A:
205 case BCM43xx_LED_BCM4303_2: 207 case BCM43xx_LED_BCM4303_2:
206 turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A); 208 turn_on = (radio->enabled && bcm43xx_is_hw_radio_enabled(bcm) &&
209 phy->type == BCM43xx_PHYTYPE_A);
207 break; 210 break;
208 case BCM43xx_LED_RADIO_B: 211 case BCM43xx_LED_RADIO_B:
209 case BCM43xx_LED_BCM4303_1: 212 case BCM43xx_LED_BCM4303_1:
210 turn_on = (radio->enabled && 213 turn_on = (radio->enabled && bcm43xx_is_hw_radio_enabled(bcm) &&
211 (phy->type == BCM43xx_PHYTYPE_B || 214 (phy->type == BCM43xx_PHYTYPE_B ||
212 phy->type == BCM43xx_PHYTYPE_G)); 215 phy->type == BCM43xx_PHYTYPE_G));
213 break; 216 break;
214 case BCM43xx_LED_MODE_BG: 217 case BCM43xx_LED_MODE_BG:
215 if (phy->type == BCM43xx_PHYTYPE_G && 218 if (phy->type == BCM43xx_PHYTYPE_G && bcm43xx_is_hw_radio_enabled(bcm) &&
216 1/*FIXME: using G rates.*/) 219 1/*FIXME: using G rates.*/)
217 turn_on = 1; 220 turn_on = 1;
218 break; 221 break;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 91b752e3d07e..23aaf1ed8541 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -2441,6 +2441,9 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2441 if (err) 2441 if (err)
2442 goto err_gpio_cleanup; 2442 goto err_gpio_cleanup;
2443 bcm43xx_radio_turn_on(bcm); 2443 bcm43xx_radio_turn_on(bcm);
2444 bcm->radio_hw_enable = bcm43xx_is_hw_radio_enabled(bcm);
2445 dprintk(KERN_INFO PFX "Radio %s by hardware\n",
2446 (bcm->radio_hw_enable == 0) ? "disabled" : "enabled");
2444 2447
2445 bcm43xx_write16(bcm, 0x03E6, 0x0000); 2448 bcm43xx_write16(bcm, 0x03E6, 0x0000);
2446 err = bcm43xx_phy_init(bcm); 2449 err = bcm43xx_phy_init(bcm);
@@ -3175,9 +3178,24 @@ static void bcm43xx_periodic_every30sec(struct bcm43xx_private *bcm)
3175 3178
3176static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm) 3179static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
3177{ 3180{
3181 bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning?
3182 //TODO for APHY (temperature?)
3183}
3184
3185static void bcm43xx_periodic_every1sec(struct bcm43xx_private *bcm)
3186{
3178 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 3187 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3179 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); 3188 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
3189 int radio_hw_enable;
3180 3190
3191 /* check if radio hardware enabled status changed */
3192 radio_hw_enable = bcm43xx_is_hw_radio_enabled(bcm);
3193 if (unlikely(bcm->radio_hw_enable != radio_hw_enable)) {
3194 bcm->radio_hw_enable = radio_hw_enable;
3195 dprintk(KERN_INFO PFX "Radio hardware status changed to %s\n",
3196 (radio_hw_enable == 0) ? "disabled" : "enabled");
3197 bcm43xx_leds_update(bcm, 0);
3198 }
3181 if (phy->type == BCM43xx_PHYTYPE_G) { 3199 if (phy->type == BCM43xx_PHYTYPE_G) {
3182 //TODO: update_aci_moving_average 3200 //TODO: update_aci_moving_average
3183 if (radio->aci_enable && radio->aci_wlan_automatic) { 3201 if (radio->aci_enable && radio->aci_wlan_automatic) {
@@ -3201,21 +3219,21 @@ static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
3201 //TODO: implement rev1 workaround 3219 //TODO: implement rev1 workaround
3202 } 3220 }
3203 } 3221 }
3204 bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning?
3205 //TODO for APHY (temperature?)
3206} 3222}
3207 3223
3208static void do_periodic_work(struct bcm43xx_private *bcm) 3224static void do_periodic_work(struct bcm43xx_private *bcm)
3209{ 3225{
3210 if (bcm->periodic_state % 8 == 0) 3226 if (bcm->periodic_state % 120 == 0)
3211 bcm43xx_periodic_every120sec(bcm); 3227 bcm43xx_periodic_every120sec(bcm);
3212 if (bcm->periodic_state % 4 == 0) 3228 if (bcm->periodic_state % 60 == 0)
3213 bcm43xx_periodic_every60sec(bcm); 3229 bcm43xx_periodic_every60sec(bcm);
3214 if (bcm->periodic_state % 2 == 0) 3230 if (bcm->periodic_state % 30 == 0)
3215 bcm43xx_periodic_every30sec(bcm); 3231 bcm43xx_periodic_every30sec(bcm);
3216 bcm43xx_periodic_every15sec(bcm); 3232 if (bcm->periodic_state % 15 == 0)
3233 bcm43xx_periodic_every15sec(bcm);
3234 bcm43xx_periodic_every1sec(bcm);
3217 3235
3218 schedule_delayed_work(&bcm->periodic_work, HZ * 15); 3236 schedule_delayed_work(&bcm->periodic_work, HZ);
3219} 3237}
3220 3238
3221static void bcm43xx_periodic_work_handler(struct work_struct *work) 3239static void bcm43xx_periodic_work_handler(struct work_struct *work)
@@ -3228,7 +3246,7 @@ static void bcm43xx_periodic_work_handler(struct work_struct *work)
3228 unsigned long orig_trans_start = 0; 3246 unsigned long orig_trans_start = 0;
3229 3247
3230 mutex_lock(&bcm->mutex); 3248 mutex_lock(&bcm->mutex);
3231 if (unlikely(bcm->periodic_state % 4 == 0)) { 3249 if (unlikely(bcm->periodic_state % 60 == 0)) {
3232 /* Periodic work will take a long time, so we want it to 3250 /* Periodic work will take a long time, so we want it to
3233 * be preemtible. 3251 * be preemtible.
3234 */ 3252 */
@@ -3260,7 +3278,7 @@ static void bcm43xx_periodic_work_handler(struct work_struct *work)
3260 3278
3261 do_periodic_work(bcm); 3279 do_periodic_work(bcm);
3262 3280
3263 if (unlikely(bcm->periodic_state % 4 == 0)) { 3281 if (unlikely(bcm->periodic_state % 60 == 0)) {
3264 spin_lock_irqsave(&bcm->irq_lock, flags); 3282 spin_lock_irqsave(&bcm->irq_lock, flags);
3265 tasklet_enable(&bcm->isr_tasklet); 3283 tasklet_enable(&bcm->isr_tasklet);
3266 bcm43xx_interrupt_enable(bcm, savedirqs); 3284 bcm43xx_interrupt_enable(bcm, savedirqs);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
index bb9c484d7e19..af19a07032a3 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
@@ -1981,6 +1981,7 @@ void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm)
1981 } 1981 }
1982 radio->enabled = 1; 1982 radio->enabled = 1;
1983 dprintk(KERN_INFO PFX "Radio turned on\n"); 1983 dprintk(KERN_INFO PFX "Radio turned on\n");
1984 bcm43xx_leds_update(bcm, 0);
1984} 1985}
1985 1986
1986void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm) 1987void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm)
@@ -2001,6 +2002,7 @@ void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm)
2001 bcm43xx_phy_write(bcm, 0x0015, 0xAA00); 2002 bcm43xx_phy_write(bcm, 0x0015, 0xAA00);
2002 radio->enabled = 0; 2003 radio->enabled = 0;
2003 dprintk(KERN_INFO PFX "Radio turned off\n"); 2004 dprintk(KERN_INFO PFX "Radio turned off\n");
2005 bcm43xx_leds_update(bcm, 0);
2004} 2006}
2005 2007
2006void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm) 2008void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.h b/drivers/net/wireless/bcm43xx/bcm43xx_radio.h
index 9ed18039fa3e..77a98a53a2e2 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.h
@@ -65,6 +65,22 @@ void bcm43xx_radio_init2060(struct bcm43xx_private *bcm);
65void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm); 65void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm);
66void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm); 66void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm);
67 67
68static inline
69int bcm43xx_is_hw_radio_enabled(struct bcm43xx_private *bcm)
70{
71 /* function to return state of hardware enable of radio
72 * returns 0 if radio disabled, 1 if radio enabled
73 */
74 if (bcm->current_core->rev >= 3)
75 return ((bcm43xx_read32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI)
76 & BCM43xx_MMIO_RADIO_HWENABLED_HI_MASK)
77 == 0) ? 1 : 0;
78 else
79 return ((bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO)
80 & BCM43xx_MMIO_RADIO_HWENABLED_LO_MASK)
81 == 0) ? 0 : 1;
82}
83
68int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm, u8 channel, 84int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm, u8 channel,
69 int synthetic_pu_workaround); 85 int synthetic_pu_workaround);
70 86