aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/iface.c242
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);
1285void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); 1285void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
1286void ieee80211_remove_interfaces(struct ieee80211_local *local); 1286void ieee80211_remove_interfaces(struct ieee80211_local *local);
1287u32 __ieee80211_recalc_idle(struct ieee80211_local *local);
1288void ieee80211_recalc_idle(struct ieee80211_local *local); 1287void ieee80211_recalc_idle(struct ieee80211_local *local);
1289void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, 1288void 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
46static 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
56static 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
67static 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
156void 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
46static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) 167static 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
1406static 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
1416static 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
1427u32 __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
1516void 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
1527static int netdev_notify(struct notifier_block *nb, 1527static int netdev_notify(struct notifier_block *nb,
1528 unsigned long state, 1528 unsigned long state,
1529 void *ndev) 1529 void *ndev)