diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/iface.c | 242 |
2 files changed, 121 insertions, 122 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f834a005e1c5..341d77d472d2 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1284,7 +1284,6 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
1284 | enum nl80211_iftype type); | 1284 | enum nl80211_iftype type); |
1285 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); | 1285 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); |
1286 | void ieee80211_remove_interfaces(struct ieee80211_local *local); | 1286 | void ieee80211_remove_interfaces(struct ieee80211_local *local); |
1287 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local); | ||
1288 | void ieee80211_recalc_idle(struct ieee80211_local *local); | 1287 | void ieee80211_recalc_idle(struct ieee80211_local *local); |
1289 | void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, | 1288 | void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, |
1290 | const int offset); | 1289 | const int offset); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 58c2ab3d483a..0a6b4e1043cb 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -43,6 +43,127 @@ | |||
43 | */ | 43 | */ |
44 | 44 | ||
45 | 45 | ||
46 | static u32 ieee80211_idle_off(struct ieee80211_local *local, | ||
47 | const char *reason) | ||
48 | { | ||
49 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) | ||
50 | return 0; | ||
51 | |||
52 | local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; | ||
53 | return IEEE80211_CONF_CHANGE_IDLE; | ||
54 | } | ||
55 | |||
56 | static u32 ieee80211_idle_on(struct ieee80211_local *local) | ||
57 | { | ||
58 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) | ||
59 | return 0; | ||
60 | |||
61 | drv_flush(local, false); | ||
62 | |||
63 | local->hw.conf.flags |= IEEE80211_CONF_IDLE; | ||
64 | return IEEE80211_CONF_CHANGE_IDLE; | ||
65 | } | ||
66 | |||
67 | static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | ||
68 | { | ||
69 | struct ieee80211_sub_if_data *sdata; | ||
70 | int count = 0; | ||
71 | bool working = false, scanning = false; | ||
72 | unsigned int led_trig_start = 0, led_trig_stop = 0; | ||
73 | struct ieee80211_roc_work *roc; | ||
74 | |||
75 | #ifdef CONFIG_PROVE_LOCKING | ||
76 | WARN_ON(debug_locks && !lockdep_rtnl_is_held() && | ||
77 | !lockdep_is_held(&local->iflist_mtx)); | ||
78 | #endif | ||
79 | lockdep_assert_held(&local->mtx); | ||
80 | |||
81 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
82 | if (!ieee80211_sdata_running(sdata)) { | ||
83 | sdata->vif.bss_conf.idle = true; | ||
84 | continue; | ||
85 | } | ||
86 | |||
87 | sdata->old_idle = sdata->vif.bss_conf.idle; | ||
88 | |||
89 | /* do not count disabled managed interfaces */ | ||
90 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
91 | !sdata->u.mgd.associated && | ||
92 | !sdata->u.mgd.auth_data && | ||
93 | !sdata->u.mgd.assoc_data) { | ||
94 | sdata->vif.bss_conf.idle = true; | ||
95 | continue; | ||
96 | } | ||
97 | /* do not count unused IBSS interfaces */ | ||
98 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
99 | !sdata->u.ibss.ssid_len) { | ||
100 | sdata->vif.bss_conf.idle = true; | ||
101 | continue; | ||
102 | } | ||
103 | /* count everything else */ | ||
104 | sdata->vif.bss_conf.idle = false; | ||
105 | count++; | ||
106 | } | ||
107 | |||
108 | if (!local->ops->remain_on_channel) { | ||
109 | list_for_each_entry(roc, &local->roc_list, list) { | ||
110 | working = true; | ||
111 | roc->sdata->vif.bss_conf.idle = false; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | if (local->scan_sdata && | ||
116 | !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { | ||
117 | scanning = true; | ||
118 | local->scan_sdata->vif.bss_conf.idle = false; | ||
119 | } | ||
120 | |||
121 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
122 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || | ||
123 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
124 | continue; | ||
125 | if (sdata->old_idle == sdata->vif.bss_conf.idle) | ||
126 | continue; | ||
127 | if (!ieee80211_sdata_running(sdata)) | ||
128 | continue; | ||
129 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); | ||
130 | } | ||
131 | |||
132 | if (working || scanning) | ||
133 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; | ||
134 | else | ||
135 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; | ||
136 | |||
137 | if (count) | ||
138 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | ||
139 | else | ||
140 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | ||
141 | |||
142 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); | ||
143 | |||
144 | if (working) | ||
145 | return ieee80211_idle_off(local, "working"); | ||
146 | if (scanning) | ||
147 | return ieee80211_idle_off(local, "scanning"); | ||
148 | if (!count) | ||
149 | return ieee80211_idle_on(local); | ||
150 | else | ||
151 | return ieee80211_idle_off(local, "in use"); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | void ieee80211_recalc_idle(struct ieee80211_local *local) | ||
157 | { | ||
158 | u32 chg; | ||
159 | |||
160 | mutex_lock(&local->iflist_mtx); | ||
161 | chg = __ieee80211_recalc_idle(local); | ||
162 | mutex_unlock(&local->iflist_mtx); | ||
163 | if (chg) | ||
164 | ieee80211_hw_config(local, chg); | ||
165 | } | ||
166 | |||
46 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | 167 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) |
47 | { | 168 | { |
48 | int meshhdrlen; | 169 | int meshhdrlen; |
@@ -1403,127 +1524,6 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) | |||
1403 | list_del(&unreg_list); | 1524 | list_del(&unreg_list); |
1404 | } | 1525 | } |
1405 | 1526 | ||
1406 | static u32 ieee80211_idle_off(struct ieee80211_local *local, | ||
1407 | const char *reason) | ||
1408 | { | ||
1409 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) | ||
1410 | return 0; | ||
1411 | |||
1412 | local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; | ||
1413 | return IEEE80211_CONF_CHANGE_IDLE; | ||
1414 | } | ||
1415 | |||
1416 | static u32 ieee80211_idle_on(struct ieee80211_local *local) | ||
1417 | { | ||
1418 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) | ||
1419 | return 0; | ||
1420 | |||
1421 | drv_flush(local, false); | ||
1422 | |||
1423 | local->hw.conf.flags |= IEEE80211_CONF_IDLE; | ||
1424 | return IEEE80211_CONF_CHANGE_IDLE; | ||
1425 | } | ||
1426 | |||
1427 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | ||
1428 | { | ||
1429 | struct ieee80211_sub_if_data *sdata; | ||
1430 | int count = 0; | ||
1431 | bool working = false, scanning = false; | ||
1432 | unsigned int led_trig_start = 0, led_trig_stop = 0; | ||
1433 | struct ieee80211_roc_work *roc; | ||
1434 | |||
1435 | #ifdef CONFIG_PROVE_LOCKING | ||
1436 | WARN_ON(debug_locks && !lockdep_rtnl_is_held() && | ||
1437 | !lockdep_is_held(&local->iflist_mtx)); | ||
1438 | #endif | ||
1439 | lockdep_assert_held(&local->mtx); | ||
1440 | |||
1441 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
1442 | if (!ieee80211_sdata_running(sdata)) { | ||
1443 | sdata->vif.bss_conf.idle = true; | ||
1444 | continue; | ||
1445 | } | ||
1446 | |||
1447 | sdata->old_idle = sdata->vif.bss_conf.idle; | ||
1448 | |||
1449 | /* do not count disabled managed interfaces */ | ||
1450 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
1451 | !sdata->u.mgd.associated && | ||
1452 | !sdata->u.mgd.auth_data && | ||
1453 | !sdata->u.mgd.assoc_data) { | ||
1454 | sdata->vif.bss_conf.idle = true; | ||
1455 | continue; | ||
1456 | } | ||
1457 | /* do not count unused IBSS interfaces */ | ||
1458 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
1459 | !sdata->u.ibss.ssid_len) { | ||
1460 | sdata->vif.bss_conf.idle = true; | ||
1461 | continue; | ||
1462 | } | ||
1463 | /* count everything else */ | ||
1464 | sdata->vif.bss_conf.idle = false; | ||
1465 | count++; | ||
1466 | } | ||
1467 | |||
1468 | if (!local->ops->remain_on_channel) { | ||
1469 | list_for_each_entry(roc, &local->roc_list, list) { | ||
1470 | working = true; | ||
1471 | roc->sdata->vif.bss_conf.idle = false; | ||
1472 | } | ||
1473 | } | ||
1474 | |||
1475 | if (local->scan_sdata && | ||
1476 | !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { | ||
1477 | scanning = true; | ||
1478 | local->scan_sdata->vif.bss_conf.idle = false; | ||
1479 | } | ||
1480 | |||
1481 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
1482 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || | ||
1483 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
1484 | continue; | ||
1485 | if (sdata->old_idle == sdata->vif.bss_conf.idle) | ||
1486 | continue; | ||
1487 | if (!ieee80211_sdata_running(sdata)) | ||
1488 | continue; | ||
1489 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); | ||
1490 | } | ||
1491 | |||
1492 | if (working || scanning) | ||
1493 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; | ||
1494 | else | ||
1495 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; | ||
1496 | |||
1497 | if (count) | ||
1498 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | ||
1499 | else | ||
1500 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | ||
1501 | |||
1502 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); | ||
1503 | |||
1504 | if (working) | ||
1505 | return ieee80211_idle_off(local, "working"); | ||
1506 | if (scanning) | ||
1507 | return ieee80211_idle_off(local, "scanning"); | ||
1508 | if (!count) | ||
1509 | return ieee80211_idle_on(local); | ||
1510 | else | ||
1511 | return ieee80211_idle_off(local, "in use"); | ||
1512 | |||
1513 | return 0; | ||
1514 | } | ||
1515 | |||
1516 | void ieee80211_recalc_idle(struct ieee80211_local *local) | ||
1517 | { | ||
1518 | u32 chg; | ||
1519 | |||
1520 | mutex_lock(&local->iflist_mtx); | ||
1521 | chg = __ieee80211_recalc_idle(local); | ||
1522 | mutex_unlock(&local->iflist_mtx); | ||
1523 | if (chg) | ||
1524 | ieee80211_hw_config(local, chg); | ||
1525 | } | ||
1526 | |||
1527 | static int netdev_notify(struct notifier_block *nb, | 1527 | static int netdev_notify(struct notifier_block *nb, |
1528 | unsigned long state, | 1528 | unsigned long state, |
1529 | void *ndev) | 1529 | void *ndev) |