Commit 804483e9 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

cfg80211/mac80211: report signal strength for mgmt frames



Add the signal strength (in dBm only for now) to
frames that are received via nl80211's various
frame APIs.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Acked-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 769009b8
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -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);
		   dlen, freq, vif->probe_req_report);


	if (vif->probe_req_report || vif->nw_type == AP_NETWORK)
	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;
	return 0;
}
}
@@ -595,7 +596,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len,
		return -EINVAL;
		return -EINVAL;
	}
	}
	ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
	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;
	return 0;
}
}
+6 −0
Original line number Original line Diff line number Diff line
@@ -1203,6 +1203,10 @@ enum nl80211_commands {
 *	the list. This needs to be used when the driver advertises the
 *	the list. This needs to be used when the driver advertises the
 *	capability to timeout the stations.
 *	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_MAX: highest attribute number currently defined
 * @__NL80211_ATTR_AFTER_LAST: internal use
 * @__NL80211_ATTR_AFTER_LAST: internal use
 */
 */
@@ -1450,6 +1454,8 @@ enum nl80211_attrs {


	NL80211_ATTR_INACTIVITY_TIMEOUT,
	NL80211_ATTR_INACTIVITY_TIMEOUT,


	NL80211_ATTR_RX_SIGNAL_DBM,

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


	__NL80211_ATTR_AFTER_LAST,
	__NL80211_ATTR_AFTER_LAST,
+5 −3
Original line number Original line Diff line number Diff line
@@ -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
 * cfg80211_rx_mgmt - notification of received, unprocessed management frame
 * @dev: network device
 * @dev: network device
 * @freq: Frequency on which the frame was received in MHz
 * @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)
 * @buf: Management frame (header + body)
 * @len: length of the frame data
 * @len: length of the frame data
 * @gfp: context flags
 * @gfp: context flags
@@ -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
 * This function is called whenever an Action frame is received for a station
 * mode interface, but is not processed in kernel.
 * mode interface, but is not processed in kernel.
 */
 */
bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_dbm,
		      size_t len, gfp_t gfp);
		      const u8 *buf, size_t len, gfp_t gfp);


/**
/**
 * cfg80211_mgmt_tx_status - notification of TX status for management frame
 * cfg80211_mgmt_tx_status - notification of TX status for management frame
@@ -3315,6 +3316,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
 * @frame: the frame
 * @frame: the frame
 * @len: length of the frame
 * @len: length of the frame
 * @freq: frequency the frame was received on
 * @freq: frequency the frame was received on
 * @sig_dbm: signal strength in mBm, or 0 if unknown
 * @gfp: allocation flags
 * @gfp: allocation flags
 *
 *
 * Use this function to report to userspace when a beacon was
 * Use this function to report to userspace when a beacon was
@@ -3323,7 +3325,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
 */
 */
void cfg80211_report_obss_beacon(struct wiphy *wiphy,
void cfg80211_report_obss_beacon(struct wiphy *wiphy,
				 const u8 *frame, size_t len,
				 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
 * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used
+11 −2
Original line number Original line Diff line number Diff line
@@ -2188,9 +2188,14 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
	if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
	if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
	    ieee80211_is_beacon(mgmt->frame_control) &&
	    ieee80211_is_beacon(mgmt->frame_control) &&
	    !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
	    !(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,
		cfg80211_report_obss_beacon(rx->local->hw.wiphy,
					    rx->skb->data, rx->skb->len,
					    rx->skb->data, rx->skb->len,
					    status->freq, GFP_ATOMIC);
					    status->freq, sig, GFP_ATOMIC);
		rx->flags |= IEEE80211_RX_BEACON_REPORTED;
		rx->flags |= IEEE80211_RX_BEACON_REPORTED;
	}
	}


@@ -2414,6 +2419,7 @@ static ieee80211_rx_result debug_noinline
ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
{
{
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
	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 */
	/* skip known-bad action frames and return them in the next handler */
	if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM)
	if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM)
@@ -2426,7 +2432,10 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
	 * it transmitted were processed or returned.
	 * 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,
			     rx->skb->data, rx->skb->len,
			     GFP_ATOMIC)) {
			     GFP_ATOMIC)) {
		if (rx->sta)
		if (rx->sta)
+4 −3
Original line number Original line Diff line number Diff line
@@ -814,8 +814,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
				  cookie);
				  cookie);
}
}


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


		/* Indicate the received Action frame to user space */
		/* 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))
				      buf, len, gfp))
			continue;
			continue;


Loading