aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMeenakshi Venkataraman <meenakshi.venkataraman@intel.com>2011-07-08 11:46:22 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-11 15:02:06 -0400
commit615f7b9bb1f8e0e3188470245cec44f175189084 (patch)
tree4c0803460f682c34b11929a1fe22e150839efedb /net
parent0a49b2c2a6bf2f774675e472afe68951900596fb (diff)
mac80211: add driver RSSI threshold events
mac80211 maintains a running average of the RSSI when a STA is associated to an AP. Report threshold events to any driver that has registered callbacks for getting RSSI measurements. Implement callbacks in mac80211 so that driver can set thresholds. Add callbacks in mac80211 which is invoked when an RSSI threshold event occurs. mac80211: add tracing to rssi_reports api and remove extraneous fn argument mac80211: scale up rssi thresholds from driver by 16 before storing Signed-off-by: Meenakshi Venkataraman <meenakshi.venkataraman@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/driver-ops.h8
-rw-r--r--net/mac80211/driver-trace.h46
-rw-r--r--net/mac80211/ieee80211_i.h8
-rw-r--r--net/mac80211/mlme.c23
-rw-r--r--net/mac80211/util.c40
5 files changed, 125 insertions, 0 deletions
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index edd2dd79c9be..b2d6bba44054 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -657,4 +657,12 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local,
657 trace_drv_return_void(local); 657 trace_drv_return_void(local);
658} 658}
659 659
660static inline void drv_rssi_callback(struct ieee80211_local *local,
661 const enum ieee80211_rssi_event event)
662{
663 trace_drv_rssi_callback(local, event);
664 if (local->ops->rssi_callback)
665 local->ops->rssi_callback(&local->hw, event);
666 trace_drv_return_void(local);
667}
660#endif /* __MAC80211_DRIVER_OPS */ 668#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 31a9dfa81f65..4470f6e8b845 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -1052,6 +1052,28 @@ TRACE_EVENT(drv_set_rekey_data,
1052 LOCAL_PR_ARG, VIF_PR_ARG) 1052 LOCAL_PR_ARG, VIF_PR_ARG)
1053); 1053);
1054 1054
1055TRACE_EVENT(drv_rssi_callback,
1056 TP_PROTO(struct ieee80211_local *local,
1057 enum ieee80211_rssi_event rssi_event),
1058
1059 TP_ARGS(local, rssi_event),
1060
1061 TP_STRUCT__entry(
1062 LOCAL_ENTRY
1063 __field(u32, rssi_event)
1064 ),
1065
1066 TP_fast_assign(
1067 LOCAL_ASSIGN;
1068 __entry->rssi_event = rssi_event;
1069 ),
1070
1071 TP_printk(
1072 LOCAL_PR_FMT " rssi_event:%d",
1073 LOCAL_PR_ARG, __entry->rssi_event
1074 )
1075);
1076
1055/* 1077/*
1056 * Tracing for API calls that drivers call. 1078 * Tracing for API calls that drivers call.
1057 */ 1079 */
@@ -1342,6 +1364,30 @@ TRACE_EVENT(api_gtk_rekey_notify,
1342 TP_printk(VIF_PR_FMT, VIF_PR_ARG) 1364 TP_printk(VIF_PR_FMT, VIF_PR_ARG)
1343); 1365);
1344 1366
1367TRACE_EVENT(api_enable_rssi_reports,
1368 TP_PROTO(struct ieee80211_sub_if_data *sdata,
1369 int rssi_min_thold, int rssi_max_thold),
1370
1371 TP_ARGS(sdata, rssi_min_thold, rssi_max_thold),
1372
1373 TP_STRUCT__entry(
1374 VIF_ENTRY
1375 __field(int, rssi_min_thold)
1376 __field(int, rssi_max_thold)
1377 ),
1378
1379 TP_fast_assign(
1380 VIF_ASSIGN;
1381 __entry->rssi_min_thold = rssi_min_thold;
1382 __entry->rssi_max_thold = rssi_max_thold;
1383 ),
1384
1385 TP_printk(
1386 VIF_PR_FMT " rssi_min_thold =%d, rssi_max_thold = %d",
1387 VIF_PR_ARG, __entry->rssi_min_thold, __entry->rssi_max_thold
1388 )
1389);
1390
1345/* 1391/*
1346 * Tracing for internal functions 1392 * Tracing for internal functions
1347 * (which may also be called in response to driver calls) 1393 * (which may also be called in response to driver calls)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4c7a831e7d1e..96600bec44c5 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -432,6 +432,14 @@ struct ieee80211_if_managed {
432 * generated for the current association. 432 * generated for the current association.
433 */ 433 */
434 int last_cqm_event_signal; 434 int last_cqm_event_signal;
435
436 /*
437 * State variables for keeping track of RSSI of the AP currently
438 * connected to and informing driver when RSSI has gone
439 * below/above a certain threshold.
440 */
441 int rssi_min_thold, rssi_max_thold;
442 int last_ave_beacon_signal;
435}; 443};
436 444
437struct ieee80211_if_ibss { 445struct ieee80211_if_ibss {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b6d9bd5f4d3c..4b0460ad8c8f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1763,6 +1763,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1763 ifmgd->ave_beacon_signal = rx_status->signal * 16; 1763 ifmgd->ave_beacon_signal = rx_status->signal * 16;
1764 ifmgd->last_cqm_event_signal = 0; 1764 ifmgd->last_cqm_event_signal = 0;
1765 ifmgd->count_beacon_signal = 1; 1765 ifmgd->count_beacon_signal = 1;
1766 ifmgd->last_ave_beacon_signal = 0;
1766 } else { 1767 } else {
1767 ifmgd->ave_beacon_signal = 1768 ifmgd->ave_beacon_signal =
1768 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + 1769 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
@@ -1770,6 +1771,28 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1770 ifmgd->ave_beacon_signal) / 16; 1771 ifmgd->ave_beacon_signal) / 16;
1771 ifmgd->count_beacon_signal++; 1772 ifmgd->count_beacon_signal++;
1772 } 1773 }
1774
1775 if (ifmgd->rssi_min_thold != ifmgd->rssi_max_thold &&
1776 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
1777 int sig = ifmgd->ave_beacon_signal;
1778 int last_sig = ifmgd->last_ave_beacon_signal;
1779
1780 /*
1781 * if signal crosses either of the boundaries, invoke callback
1782 * with appropriate parameters
1783 */
1784 if (sig > ifmgd->rssi_max_thold &&
1785 (last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) {
1786 ifmgd->last_ave_beacon_signal = sig;
1787 drv_rssi_callback(local, RSSI_EVENT_HIGH);
1788 } else if (sig < ifmgd->rssi_min_thold &&
1789 (last_sig >= ifmgd->rssi_max_thold ||
1790 last_sig == 0)) {
1791 ifmgd->last_ave_beacon_signal = sig;
1792 drv_rssi_callback(local, RSSI_EVENT_LOW);
1793 }
1794 }
1795
1773 if (bss_conf->cqm_rssi_thold && 1796 if (bss_conf->cqm_rssi_thold &&
1774 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT && 1797 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
1775 !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { 1798 !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 652e5695225a..190132063c99 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1450,3 +1450,43 @@ size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
1450 1450
1451 return pos; 1451 return pos;
1452} 1452}
1453
1454static void _ieee80211_enable_rssi_reports(struct ieee80211_sub_if_data *sdata,
1455 int rssi_min_thold,
1456 int rssi_max_thold)
1457{
1458 trace_api_enable_rssi_reports(sdata, rssi_min_thold, rssi_max_thold);
1459
1460 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
1461 return;
1462
1463 /*
1464 * Scale up threshold values before storing it, as the RSSI averaging
1465 * algorithm uses a scaled up value as well. Change this scaling
1466 * factor if the RSSI averaging algorithm changes.
1467 */
1468 sdata->u.mgd.rssi_min_thold = rssi_min_thold*16;
1469 sdata->u.mgd.rssi_max_thold = rssi_max_thold*16;
1470}
1471
1472void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
1473 int rssi_min_thold,
1474 int rssi_max_thold)
1475{
1476 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1477
1478 WARN_ON(rssi_min_thold == rssi_max_thold ||
1479 rssi_min_thold > rssi_max_thold);
1480
1481 _ieee80211_enable_rssi_reports(sdata, rssi_min_thold,
1482 rssi_max_thold);
1483}
1484EXPORT_SYMBOL(ieee80211_enable_rssi_reports);
1485
1486void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif)
1487{
1488 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1489
1490 _ieee80211_enable_rssi_reports(sdata, 0, 0);
1491}
1492EXPORT_SYMBOL(ieee80211_disable_rssi_reports);