Skip to content

Commit

Permalink
cfg80211/mac80211: report signal strength for mgmt frames
Browse files Browse the repository at this point in the history
Add the signal strength (in dBm only for now) to
frames that are received via nl80211's various
frame APIs.

Signed-off-by: Johannes Berg <[email protected]>
Acked-by: Kalle Valo <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
  • Loading branch information
jmberg-intel authored and linvjw committed Mar 6, 2012
1 parent 769009b commit 804483e
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 13 deletions.
6 changes: 4 additions & 2 deletions drivers/net/wireless/ath/ath6kl/wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,8 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len,
dlen, freq, vif->probe_req_report);

if (vif->probe_req_report || vif->nw_type == AP_NETWORK)
cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC);
cfg80211_rx_mgmt(vif->ndev, freq, 0,
ev->data, dlen, GFP_ATOMIC);

return 0;
}
Expand Down Expand Up @@ -595,7 +596,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len,
return -EINVAL;
}
ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC);
cfg80211_rx_mgmt(vif->ndev, freq, 0,
ev->data, dlen, GFP_ATOMIC);

return 0;
}
Expand Down
6 changes: 6 additions & 0 deletions include/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,10 @@ enum nl80211_commands {
* the list. This needs to be used when the driver advertises the
* capability to timeout the stations.
*
* @NL80211_ATTR_RX_SIGNAL_DBM: signal strength in dBm (as a 32-bit int);
* this attribute is (depending on the driver capabilities) added to
* received frames indicated with %NL80211_CMD_FRAME.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -1450,6 +1454,8 @@ enum nl80211_attrs {

NL80211_ATTR_INACTIVITY_TIMEOUT,

NL80211_ATTR_RX_SIGNAL_DBM,

/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
Expand Down
8 changes: 5 additions & 3 deletions include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -3189,6 +3189,7 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp);
* cfg80211_rx_mgmt - notification of received, unprocessed management frame
* @dev: network device
* @freq: Frequency on which the frame was received in MHz
* @sig_dbm: signal strength in mBm, or 0 if unknown
* @buf: Management frame (header + body)
* @len: length of the frame data
* @gfp: context flags
Expand All @@ -3201,8 +3202,8 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp);
* This function is called whenever an Action frame is received for a station
* mode interface, but is not processed in kernel.
*/
bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
size_t len, gfp_t gfp);
bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_dbm,
const u8 *buf, size_t len, gfp_t gfp);

/**
* cfg80211_mgmt_tx_status - notification of TX status for management frame
Expand Down Expand Up @@ -3315,6 +3316,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
* @frame: the frame
* @len: length of the frame
* @freq: frequency the frame was received on
* @sig_dbm: signal strength in mBm, or 0 if unknown
* @gfp: allocation flags
*
* Use this function to report to userspace when a beacon was
Expand All @@ -3323,7 +3325,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
*/
void cfg80211_report_obss_beacon(struct wiphy *wiphy,
const u8 *frame, size_t len,
int freq, gfp_t gfp);
int freq, int sig_dbm, gfp_t gfp);

/*
* cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used
Expand Down
13 changes: 11 additions & 2 deletions net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2188,9 +2188,14 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
ieee80211_is_beacon(mgmt->frame_control) &&
!(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
int sig = 0;

if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
sig = status->signal;

cfg80211_report_obss_beacon(rx->local->hw.wiphy,
rx->skb->data, rx->skb->len,
status->freq, GFP_ATOMIC);
status->freq, sig, GFP_ATOMIC);
rx->flags |= IEEE80211_RX_BEACON_REPORTED;
}

Expand Down Expand Up @@ -2414,6 +2419,7 @@ static ieee80211_rx_result debug_noinline
ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
{
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
int sig = 0;

/* skip known-bad action frames and return them in the next handler */
if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM)
Expand All @@ -2426,7 +2432,10 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
* it transmitted were processed or returned.
*/

if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq,
if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
sig = status->signal;

if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, sig,
rx->skb->data, rx->skb->len,
GFP_ATOMIC)) {
if (rx->sta)
Expand Down
7 changes: 4 additions & 3 deletions net/wireless/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -814,8 +814,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
cookie);
}

bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
size_t len, gfp_t gfp)
bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_mbm,
const u8 *buf, size_t len, gfp_t gfp)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
Expand Down Expand Up @@ -854,7 +854,8 @@ bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
/* found match! */

/* Indicate the received Action frame to user space */
if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq,
if (nl80211_send_mgmt(rdev, dev, reg->nlpid,
freq, sig_mbm,
buf, len, gfp))
continue;

Expand Down
9 changes: 7 additions & 2 deletions net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -7686,7 +7686,8 @@ bool nl80211_unexpected_4addr_frame(struct net_device *dev,

int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 nlpid,
int freq, const u8 *buf, size_t len, gfp_t gfp)
int freq, int sig_dbm,
const u8 *buf, size_t len, gfp_t gfp)
{
struct sk_buff *msg;
void *hdr;
Expand All @@ -7704,6 +7705,8 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
if (sig_dbm)
NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm);
NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);

genlmsg_end(msg, hdr);
Expand Down Expand Up @@ -7965,7 +7968,7 @@ EXPORT_SYMBOL(cfg80211_probe_status);

void cfg80211_report_obss_beacon(struct wiphy *wiphy,
const u8 *frame, size_t len,
int freq, gfp_t gfp)
int freq, int sig_dbm, gfp_t gfp)
{
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
struct sk_buff *msg;
Expand All @@ -7988,6 +7991,8 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
if (freq)
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
if (sig_dbm)
NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm);
NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame);

genlmsg_end(msg, hdr);
Expand Down
3 changes: 2 additions & 1 deletion net/wireless/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
gfp_t gfp);

int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 nlpid, int freq,
struct net_device *netdev, u32 nlpid,
int freq, int sig_dbm,
const u8 *buf, size_t len, gfp_t gfp);
void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u64 cookie,
Expand Down

0 comments on commit 804483e

Please sign in to comment.