aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r--net/mac80211/iface.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index f9163b12c7f1..8acba456744e 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -197,11 +197,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
197 sdata->bss = &sdata->u.ap; 197 sdata->bss = &sdata->u.ap;
198 break; 198 break;
199 case NL80211_IFTYPE_MESH_POINT: 199 case NL80211_IFTYPE_MESH_POINT:
200 if (!ieee80211_vif_is_mesh(&sdata->vif))
201 break;
202 /* mesh ifaces must set allmulti to forward mcast traffic */
203 atomic_inc(&local->iff_allmultis);
204 break;
205 case NL80211_IFTYPE_STATION: 200 case NL80211_IFTYPE_STATION:
206 case NL80211_IFTYPE_MONITOR: 201 case NL80211_IFTYPE_MONITOR:
207 case NL80211_IFTYPE_ADHOC: 202 case NL80211_IFTYPE_ADHOC:
@@ -225,6 +220,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
225 /* we're brought up, everything changes */ 220 /* we're brought up, everything changes */
226 hw_reconf_flags = ~0; 221 hw_reconf_flags = ~0;
227 ieee80211_led_radio(local, true); 222 ieee80211_led_radio(local, true);
223 ieee80211_mod_tpt_led_trig(local,
224 IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
228 } 225 }
229 226
230 /* 227 /*
@@ -273,12 +270,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
273 goto err_stop; 270 goto err_stop;
274 } 271 }
275 272
276 if (ieee80211_vif_is_mesh(&sdata->vif)) { 273 if (sdata->vif.type == NL80211_IFTYPE_AP) {
277 local->fif_other_bss++;
278 ieee80211_configure_filter(local);
279
280 ieee80211_start_mesh(sdata);
281 } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
282 local->fif_pspoll++; 274 local->fif_pspoll++;
283 local->fif_probe_req++; 275 local->fif_probe_req++;
284 276
@@ -391,6 +383,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
391 u32 hw_reconf_flags = 0; 383 u32 hw_reconf_flags = 0;
392 int i; 384 int i;
393 385
386 if (local->scan_sdata == sdata)
387 ieee80211_scan_cancel(local);
388
394 clear_bit(SDATA_STATE_RUNNING, &sdata->state); 389 clear_bit(SDATA_STATE_RUNNING, &sdata->state);
395 390
396 /* 391 /*
@@ -500,18 +495,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
500 ieee80211_adjust_monitor_flags(sdata, -1); 495 ieee80211_adjust_monitor_flags(sdata, -1);
501 ieee80211_configure_filter(local); 496 ieee80211_configure_filter(local);
502 break; 497 break;
503 case NL80211_IFTYPE_MESH_POINT:
504 if (ieee80211_vif_is_mesh(&sdata->vif)) {
505 /* other_bss and allmulti are always set on mesh
506 * ifaces */
507 local->fif_other_bss--;
508 atomic_dec(&local->iff_allmultis);
509
510 ieee80211_configure_filter(local);
511
512 ieee80211_stop_mesh(sdata);
513 }
514 /* fall through */
515 default: 498 default:
516 flush_work(&sdata->work); 499 flush_work(&sdata->work);
517 /* 500 /*
@@ -523,9 +506,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
523 synchronize_rcu(); 506 synchronize_rcu();
524 skb_queue_purge(&sdata->skb_queue); 507 skb_queue_purge(&sdata->skb_queue);
525 508
526 if (local->scan_sdata == sdata)
527 ieee80211_scan_cancel(local);
528
529 /* 509 /*
530 * Disable beaconing here for mesh only, AP and IBSS 510 * Disable beaconing here for mesh only, AP and IBSS
531 * are already taken care of. 511 * are already taken care of.
@@ -1204,12 +1184,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1204 if (ret) 1184 if (ret)
1205 goto fail; 1185 goto fail;
1206 1186
1207 if (ieee80211_vif_is_mesh(&sdata->vif) &&
1208 params && params->mesh_id_len)
1209 ieee80211_sdata_set_mesh_id(sdata,
1210 params->mesh_id_len,
1211 params->mesh_id);
1212
1213 mutex_lock(&local->iflist_mtx); 1187 mutex_lock(&local->iflist_mtx);
1214 list_add_tail_rcu(&sdata->list, &local->interfaces); 1188 list_add_tail_rcu(&sdata->list, &local->interfaces);
1215 mutex_unlock(&local->iflist_mtx); 1189 mutex_unlock(&local->iflist_mtx);
@@ -1290,8 +1264,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
1290{ 1264{
1291 struct ieee80211_sub_if_data *sdata; 1265 struct ieee80211_sub_if_data *sdata;
1292 int count = 0; 1266 int count = 0;
1293 bool working = false, scanning = false; 1267 bool working = false, scanning = false, hw_roc = false;
1294 struct ieee80211_work *wk; 1268 struct ieee80211_work *wk;
1269 unsigned int led_trig_start = 0, led_trig_stop = 0;
1295 1270
1296#ifdef CONFIG_PROVE_LOCKING 1271#ifdef CONFIG_PROVE_LOCKING
1297 WARN_ON(debug_locks && !lockdep_rtnl_is_held() && 1272 WARN_ON(debug_locks && !lockdep_rtnl_is_held() &&
@@ -1333,6 +1308,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
1333 local->scan_sdata->vif.bss_conf.idle = false; 1308 local->scan_sdata->vif.bss_conf.idle = false;
1334 } 1309 }
1335 1310
1311 if (local->hw_roc_channel)
1312 hw_roc = true;
1313
1336 list_for_each_entry(sdata, &local->interfaces, list) { 1314 list_for_each_entry(sdata, &local->interfaces, list) {
1337 if (sdata->old_idle == sdata->vif.bss_conf.idle) 1315 if (sdata->old_idle == sdata->vif.bss_conf.idle)
1338 continue; 1316 continue;
@@ -1341,6 +1319,20 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
1341 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); 1319 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
1342 } 1320 }
1343 1321
1322 if (working || scanning || hw_roc)
1323 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK;
1324 else
1325 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK;
1326
1327 if (count)
1328 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
1329 else
1330 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
1331
1332 ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
1333
1334 if (hw_roc)
1335 return ieee80211_idle_off(local, "hw remain-on-channel");
1344 if (working) 1336 if (working)
1345 return ieee80211_idle_off(local, "working"); 1337 return ieee80211_idle_off(local, "working");
1346 if (scanning) 1338 if (scanning)