Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 256433
b: refs/heads/master
c: 615f7b9
h: refs/heads/master
i:
  256431: 933cff0
v: v3
  • Loading branch information
Meenakshi Venkataraman authored and John W. Linville committed Jul 11, 2011
1 parent 2782e54 commit eaaad1a
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0a49b2c2a6bf2f774675e472afe68951900596fb
refs/heads/master: 615f7b9bb1f8e0e3188470245cec44f175189084
20 changes: 20 additions & 0 deletions trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,17 @@ enum ieee80211_bss_change {
*/
#define IEEE80211_BSS_ARP_ADDR_LIST_LEN 4

/**
* enum ieee80211_rssi_event - RSSI threshold event
* An indicator for when RSSI goes below/above a certain threshold.
* @RSSI_EVENT_HIGH: AP's rssi crossed the high threshold set by the driver.
* @RSSI_EVENT_LOW: AP's rssi crossed the low threshold set by the driver.
*/
enum ieee80211_rssi_event {
RSSI_EVENT_HIGH,
RSSI_EVENT_LOW,
};

/**
* struct ieee80211_bss_conf - holds the BSS's changing parameters
*
Expand Down Expand Up @@ -1867,6 +1878,8 @@ enum ieee80211_ampdu_mlme_action {
* @set_bitrate_mask: Set a mask of rates to be used for rate control selection
* when transmitting a frame. Currently only legacy rates are handled.
* The callback can sleep.
* @rssi_callback: Notify driver when the average RSSI goes above/below
* thresholds that were registered previously. The callback can sleep.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
Expand Down Expand Up @@ -1975,6 +1988,8 @@ struct ieee80211_ops {
bool (*tx_frames_pending)(struct ieee80211_hw *hw);
int (*set_bitrate_mask)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask);
void (*rssi_callback)(struct ieee80211_hw *hw,
enum ieee80211_rssi_event rssi_event);
};

/**
Expand Down Expand Up @@ -3316,4 +3331,9 @@ ieee80211_vif_type_p2p(struct ieee80211_vif *vif)
return ieee80211_iftype_p2p(vif->type, vif->p2p);
}

void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
int rssi_min_thold,
int rssi_max_thold);

void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif);
#endif /* MAC80211_H */
8 changes: 8 additions & 0 deletions trunk/net/mac80211/driver-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -657,4 +657,12 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local,
trace_drv_return_void(local);
}

static inline void drv_rssi_callback(struct ieee80211_local *local,
const enum ieee80211_rssi_event event)
{
trace_drv_rssi_callback(local, event);
if (local->ops->rssi_callback)
local->ops->rssi_callback(&local->hw, event);
trace_drv_return_void(local);
}
#endif /* __MAC80211_DRIVER_OPS */
46 changes: 46 additions & 0 deletions trunk/net/mac80211/driver-trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,28 @@ TRACE_EVENT(drv_set_rekey_data,
LOCAL_PR_ARG, VIF_PR_ARG)
);

TRACE_EVENT(drv_rssi_callback,
TP_PROTO(struct ieee80211_local *local,
enum ieee80211_rssi_event rssi_event),

TP_ARGS(local, rssi_event),

TP_STRUCT__entry(
LOCAL_ENTRY
__field(u32, rssi_event)
),

TP_fast_assign(
LOCAL_ASSIGN;
__entry->rssi_event = rssi_event;
),

TP_printk(
LOCAL_PR_FMT " rssi_event:%d",
LOCAL_PR_ARG, __entry->rssi_event
)
);

/*
* Tracing for API calls that drivers call.
*/
Expand Down Expand Up @@ -1342,6 +1364,30 @@ TRACE_EVENT(api_gtk_rekey_notify,
TP_printk(VIF_PR_FMT, VIF_PR_ARG)
);

TRACE_EVENT(api_enable_rssi_reports,
TP_PROTO(struct ieee80211_sub_if_data *sdata,
int rssi_min_thold, int rssi_max_thold),

TP_ARGS(sdata, rssi_min_thold, rssi_max_thold),

TP_STRUCT__entry(
VIF_ENTRY
__field(int, rssi_min_thold)
__field(int, rssi_max_thold)
),

TP_fast_assign(
VIF_ASSIGN;
__entry->rssi_min_thold = rssi_min_thold;
__entry->rssi_max_thold = rssi_max_thold;
),

TP_printk(
VIF_PR_FMT " rssi_min_thold =%d, rssi_max_thold = %d",
VIF_PR_ARG, __entry->rssi_min_thold, __entry->rssi_max_thold
)
);

/*
* Tracing for internal functions
* (which may also be called in response to driver calls)
Expand Down
8 changes: 8 additions & 0 deletions trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,14 @@ struct ieee80211_if_managed {
* generated for the current association.
*/
int last_cqm_event_signal;

/*
* State variables for keeping track of RSSI of the AP currently
* connected to and informing driver when RSSI has gone
* below/above a certain threshold.
*/
int rssi_min_thold, rssi_max_thold;
int last_ave_beacon_signal;
};

struct ieee80211_if_ibss {
Expand Down
23 changes: 23 additions & 0 deletions trunk/net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -1763,13 +1763,36 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
ifmgd->ave_beacon_signal = rx_status->signal * 16;
ifmgd->last_cqm_event_signal = 0;
ifmgd->count_beacon_signal = 1;
ifmgd->last_ave_beacon_signal = 0;
} else {
ifmgd->ave_beacon_signal =
(IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
(16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
ifmgd->ave_beacon_signal) / 16;
ifmgd->count_beacon_signal++;
}

if (ifmgd->rssi_min_thold != ifmgd->rssi_max_thold &&
ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
int sig = ifmgd->ave_beacon_signal;
int last_sig = ifmgd->last_ave_beacon_signal;

/*
* if signal crosses either of the boundaries, invoke callback
* with appropriate parameters
*/
if (sig > ifmgd->rssi_max_thold &&
(last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) {
ifmgd->last_ave_beacon_signal = sig;
drv_rssi_callback(local, RSSI_EVENT_HIGH);
} else if (sig < ifmgd->rssi_min_thold &&
(last_sig >= ifmgd->rssi_max_thold ||
last_sig == 0)) {
ifmgd->last_ave_beacon_signal = sig;
drv_rssi_callback(local, RSSI_EVENT_LOW);
}
}

if (bss_conf->cqm_rssi_thold &&
ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
Expand Down
40 changes: 40 additions & 0 deletions trunk/net/mac80211/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1450,3 +1450,43 @@ size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)

return pos;
}

static void _ieee80211_enable_rssi_reports(struct ieee80211_sub_if_data *sdata,
int rssi_min_thold,
int rssi_max_thold)
{
trace_api_enable_rssi_reports(sdata, rssi_min_thold, rssi_max_thold);

if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
return;

/*
* Scale up threshold values before storing it, as the RSSI averaging
* algorithm uses a scaled up value as well. Change this scaling
* factor if the RSSI averaging algorithm changes.
*/
sdata->u.mgd.rssi_min_thold = rssi_min_thold*16;
sdata->u.mgd.rssi_max_thold = rssi_max_thold*16;
}

void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
int rssi_min_thold,
int rssi_max_thold)
{
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);

WARN_ON(rssi_min_thold == rssi_max_thold ||
rssi_min_thold > rssi_max_thold);

_ieee80211_enable_rssi_reports(sdata, rssi_min_thold,
rssi_max_thold);
}
EXPORT_SYMBOL(ieee80211_enable_rssi_reports);

void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif)
{
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);

_ieee80211_enable_rssi_reports(sdata, 0, 0);
}
EXPORT_SYMBOL(ieee80211_disable_rssi_reports);

0 comments on commit eaaad1a

Please sign in to comment.