aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-11-30 02:59:23 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-12-22 14:33:37 -0500
commit67408c8c7b9daf28b50e33be3541334c07d15789 (patch)
treeac11ea966add7f7187274fcf9e647c5227099108
parente1e5406854378dfada3f33c7192b012083a5b8e0 (diff)
mac80211: selective throughput LED trigger active
The throughput LED trigger was always active when the radio was enabled. In most cases that's likely the desired behaviour, but iwlwifi requires it to be only active when one of the virtual interfaces is actually "connected" in some way. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/net/mac80211.h20
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/iface.c16
-rw-r--r--net/mac80211/led.c39
-rw-r--r--net/mac80211/led.h11
-rw-r--r--net/mac80211/util.c5
6 files changed, 76 insertions, 18 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 40a93d582c79..479c35e160e3 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1863,13 +1863,26 @@ struct ieee80211_tpt_blink {
1863 int blink_time; 1863 int blink_time;
1864}; 1864};
1865 1865
1866/**
1867 * enum ieee80211_tpt_led_trigger_flags - throughput trigger flags
1868 * @IEEE80211_TPT_LEDTRIG_FL_RADIO: enable blinking with radio
1869 * @IEEE80211_TPT_LEDTRIG_FL_WORK: enable blinking when working
1870 * @IEEE80211_TPT_LEDTRIG_FL_CONNECTED: enable blinking when at least one
1871 * interface is connected in some way, including being an AP
1872 */
1873enum ieee80211_tpt_led_trigger_flags {
1874 IEEE80211_TPT_LEDTRIG_FL_RADIO = BIT(0),
1875 IEEE80211_TPT_LEDTRIG_FL_WORK = BIT(1),
1876 IEEE80211_TPT_LEDTRIG_FL_CONNECTED = BIT(2),
1877};
1878
1866#ifdef CONFIG_MAC80211_LEDS 1879#ifdef CONFIG_MAC80211_LEDS
1867extern char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw); 1880extern char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw);
1868extern char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw); 1881extern char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw);
1869extern char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw); 1882extern char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw);
1870extern char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw); 1883extern char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw);
1871extern char *__ieee80211_create_tpt_led_trigger( 1884extern char *__ieee80211_create_tpt_led_trigger(
1872 struct ieee80211_hw *hw, 1885 struct ieee80211_hw *hw, unsigned int flags,
1873 const struct ieee80211_tpt_blink *blink_table, 1886 const struct ieee80211_tpt_blink *blink_table,
1874 unsigned int blink_table_len); 1887 unsigned int blink_table_len);
1875#endif 1888#endif
@@ -1952,6 +1965,7 @@ static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw)
1952/** 1965/**
1953 * ieee80211_create_tpt_led_trigger - create throughput LED trigger 1966 * ieee80211_create_tpt_led_trigger - create throughput LED trigger
1954 * @hw: the hardware to create the trigger for 1967 * @hw: the hardware to create the trigger for
1968 * @flags: trigger flags, see &enum ieee80211_tpt_led_trigger_flags
1955 * @blink_table: the blink table -- needs to be ordered by throughput 1969 * @blink_table: the blink table -- needs to be ordered by throughput
1956 * @blink_table_len: size of the blink table 1970 * @blink_table_len: size of the blink table
1957 * 1971 *
@@ -1960,12 +1974,12 @@ static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw)
1960 * This function must be called before ieee80211_register_hw(). 1974 * This function must be called before ieee80211_register_hw().
1961 */ 1975 */
1962static inline char * 1976static inline char *
1963ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, 1977ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags,
1964 const struct ieee80211_tpt_blink *blink_table, 1978 const struct ieee80211_tpt_blink *blink_table,
1965 unsigned int blink_table_len) 1979 unsigned int blink_table_len)
1966{ 1980{
1967#ifdef CONFIG_MAC80211_LEDS 1981#ifdef CONFIG_MAC80211_LEDS
1968 return __ieee80211_create_tpt_led_trigger(hw, blink_table, 1982 return __ieee80211_create_tpt_led_trigger(hw, flags, blink_table,
1969 blink_table_len); 1983 blink_table_len);
1970#else 1984#else
1971 return NULL; 1985 return NULL;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 523b90be8dc5..3810c72ac062 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -637,9 +637,10 @@ struct tpt_led_trigger {
637 const struct ieee80211_tpt_blink *blink_table; 637 const struct ieee80211_tpt_blink *blink_table;
638 unsigned int blink_table_len; 638 unsigned int blink_table_len;
639 struct timer_list timer; 639 struct timer_list timer;
640 bool running;
641 unsigned long prev_traffic; 640 unsigned long prev_traffic;
642 unsigned long tx_bytes, rx_bytes; 641 unsigned long tx_bytes, rx_bytes;
642 unsigned int active, want;
643 bool running;
643}; 644};
644 645
645/** 646/**
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 989df7065c21..b6db237672ff 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -220,7 +220,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
220 /* we're brought up, everything changes */ 220 /* we're brought up, everything changes */
221 hw_reconf_flags = ~0; 221 hw_reconf_flags = ~0;
222 ieee80211_led_radio(local, true); 222 ieee80211_led_radio(local, true);
223 ieee80211_start_tpt_led_trig(local); 223 ieee80211_mod_tpt_led_trig(local,
224 IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
224 } 225 }
225 226
226 /* 227 /*
@@ -1265,6 +1266,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
1265 int count = 0; 1266 int count = 0;
1266 bool working = false, scanning = false; 1267 bool working = false, scanning = false;
1267 struct ieee80211_work *wk; 1268 struct ieee80211_work *wk;
1269 unsigned int led_trig_start = 0, led_trig_stop = 0;
1268 1270
1269#ifdef CONFIG_PROVE_LOCKING 1271#ifdef CONFIG_PROVE_LOCKING
1270 WARN_ON(debug_locks && !lockdep_rtnl_is_held() && 1272 WARN_ON(debug_locks && !lockdep_rtnl_is_held() &&
@@ -1314,6 +1316,18 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
1314 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); 1316 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
1315 } 1317 }
1316 1318
1319 if (working || scanning)
1320 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK;
1321 else
1322 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK;
1323
1324 if (count)
1325 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
1326 else
1327 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
1328
1329 ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
1330
1317 if (working) 1331 if (working)
1318 return ieee80211_idle_off(local, "working"); 1332 return ieee80211_idle_off(local, "working");
1319 if (scanning) 1333 if (scanning)
diff --git a/net/mac80211/led.c b/net/mac80211/led.c
index 79b13090aed7..4905eb8af572 100644
--- a/net/mac80211/led.c
+++ b/net/mac80211/led.c
@@ -216,7 +216,7 @@ static void tpt_trig_timer(unsigned long data)
216} 216}
217 217
218extern char *__ieee80211_create_tpt_led_trigger( 218extern char *__ieee80211_create_tpt_led_trigger(
219 struct ieee80211_hw *hw, 219 struct ieee80211_hw *hw, unsigned int flags,
220 const struct ieee80211_tpt_blink *blink_table, 220 const struct ieee80211_tpt_blink *blink_table,
221 unsigned int blink_table_len) 221 unsigned int blink_table_len)
222{ 222{
@@ -237,6 +237,7 @@ extern char *__ieee80211_create_tpt_led_trigger(
237 237
238 tpt_trig->blink_table = blink_table; 238 tpt_trig->blink_table = blink_table;
239 tpt_trig->blink_table_len = blink_table_len; 239 tpt_trig->blink_table_len = blink_table_len;
240 tpt_trig->want = flags;
240 241
241 setup_timer(&tpt_trig->timer, tpt_trig_timer, (unsigned long)local); 242 setup_timer(&tpt_trig->timer, tpt_trig_timer, (unsigned long)local);
242 243
@@ -246,11 +247,11 @@ extern char *__ieee80211_create_tpt_led_trigger(
246} 247}
247EXPORT_SYMBOL(__ieee80211_create_tpt_led_trigger); 248EXPORT_SYMBOL(__ieee80211_create_tpt_led_trigger);
248 249
249void ieee80211_start_tpt_led_trig(struct ieee80211_local *local) 250static void ieee80211_start_tpt_led_trig(struct ieee80211_local *local)
250{ 251{
251 struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; 252 struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
252 253
253 if (!tpt_trig) 254 if (tpt_trig->running)
254 return; 255 return;
255 256
256 /* reset traffic */ 257 /* reset traffic */
@@ -261,12 +262,12 @@ void ieee80211_start_tpt_led_trig(struct ieee80211_local *local)
261 mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ)); 262 mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ));
262} 263}
263 264
264void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local) 265static void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local)
265{ 266{
266 struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; 267 struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
267 struct led_classdev *led_cdev; 268 struct led_classdev *led_cdev;
268 269
269 if (!tpt_trig) 270 if (!tpt_trig->running)
270 return; 271 return;
271 272
272 tpt_trig->running = false; 273 tpt_trig->running = false;
@@ -277,3 +278,31 @@ void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local)
277 led_brightness_set(led_cdev, LED_OFF); 278 led_brightness_set(led_cdev, LED_OFF);
278 read_unlock(&tpt_trig->trig.leddev_list_lock); 279 read_unlock(&tpt_trig->trig.leddev_list_lock);
279} 280}
281
282void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
283 unsigned int types_on, unsigned int types_off)
284{
285 struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
286 bool allowed;
287
288 WARN_ON(types_on & types_off);
289
290 if (!tpt_trig)
291 return;
292
293 tpt_trig->active &= ~types_off;
294 tpt_trig->active |= types_on;
295
296 /*
297 * Regardless of wanted state, we shouldn't blink when
298 * the radio is disabled -- this can happen due to some
299 * code ordering issues with __ieee80211_recalc_idle()
300 * being called before the radio is started.
301 */
302 allowed = tpt_trig->active & IEEE80211_TPT_LEDTRIG_FL_RADIO;
303
304 if (!allowed || !(tpt_trig->active & tpt_trig->want))
305 ieee80211_stop_tpt_led_trig(local);
306 else
307 ieee80211_start_tpt_led_trig(local);
308}
diff --git a/net/mac80211/led.h b/net/mac80211/led.h
index 6c215dc0fc96..e0275d9befa8 100644
--- a/net/mac80211/led.h
+++ b/net/mac80211/led.h
@@ -21,8 +21,8 @@ void ieee80211_led_radio(struct ieee80211_local *local,
21void ieee80211_led_names(struct ieee80211_local *local); 21void ieee80211_led_names(struct ieee80211_local *local);
22void ieee80211_led_init(struct ieee80211_local *local); 22void ieee80211_led_init(struct ieee80211_local *local);
23void ieee80211_led_exit(struct ieee80211_local *local); 23void ieee80211_led_exit(struct ieee80211_local *local);
24void ieee80211_start_tpt_led_trig(struct ieee80211_local *local); 24void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
25void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local); 25 unsigned int types_on, unsigned int types_off);
26#else 26#else
27static inline void ieee80211_led_rx(struct ieee80211_local *local) 27static inline void ieee80211_led_rx(struct ieee80211_local *local)
28{ 28{
@@ -47,10 +47,9 @@ static inline void ieee80211_led_init(struct ieee80211_local *local)
47static inline void ieee80211_led_exit(struct ieee80211_local *local) 47static inline void ieee80211_led_exit(struct ieee80211_local *local)
48{ 48{
49} 49}
50static inline void ieee80211_start_tpt_led_trig(struct ieee80211_local *local) 50static inline void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
51{ 51 unsigned int types_on,
52} 52 unsigned int types_off)
53static inline void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local)
54{ 53{
55} 54}
56#endif 55#endif
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 48306415a1cb..cf68700abffa 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1116,7 +1116,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
1116void ieee80211_stop_device(struct ieee80211_local *local) 1116void ieee80211_stop_device(struct ieee80211_local *local)
1117{ 1117{
1118 ieee80211_led_radio(local, false); 1118 ieee80211_led_radio(local, false);
1119 ieee80211_stop_tpt_led_trig(local); 1119 ieee80211_mod_tpt_led_trig(local, 0, IEEE80211_TPT_LEDTRIG_FL_RADIO);
1120 1120
1121 cancel_work_sync(&local->reconfig_filter); 1121 cancel_work_sync(&local->reconfig_filter);
1122 1122
@@ -1151,7 +1151,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1151 } 1151 }
1152 1152
1153 ieee80211_led_radio(local, true); 1153 ieee80211_led_radio(local, true);
1154 ieee80211_start_tpt_led_trig(local); 1154 ieee80211_mod_tpt_led_trig(local,
1155 IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
1155 } 1156 }
1156 1157
1157 /* add interfaces */ 1158 /* add interfaces */