Ver Fonte

qcacmn: Add changes to indicate beacon frame to cfg80211 layer

Add changes to indicate beacon frame to cfg80211 layer from scan
module.

Change-Id: Ia36e957bd2324130c8c3175569ce38267cd3cf53
CRs-Fixed: 1095299
Abhishek Singh há 8 anos atrás
pai
commit
9eb058adca

+ 13 - 1
os_if/linux/scan/inc/wlan_cfg80211_scan.h

@@ -30,6 +30,7 @@
 #include <qca_vendor.h>
 #include <qdf_list.h>
 #include <qdf_types.h>
+#include <wlan_scan_ucfg_api.h>
 
 #ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
 /* GPS application requirement */
@@ -94,5 +95,16 @@ int wlan_cfg80211_scan(struct wiphy *wiphy,
 #endif
 		struct cfg80211_scan_request *request);
 
-
+/**
+ * wlan_cfg80211_inform_bss_frame() - API to inform beacon to cfg80211
+ * @pdev: Pointer to pdev
+ * @scan_params: scan entry
+ * @request: Pointer to scan request
+ *
+ * API to inform beacon to cfg80211
+ *
+ * Return: void
+ */
+void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev,
+	struct scan_cache_entry *scan_params);
 #endif

+ 143 - 0
os_if/linux/scan/src/wlan_cfg80211_scan.c

@@ -21,8 +21,11 @@
  */
 
 #include <wlan_cfg80211_scan.h>
+#include <wlan_osif_priv.h>
+#include <wlan_cfg80211.h>
 #include <linux/wireless.h>
 #include <net/cfg80211.h>
+#include <wlan_scan_utils_api.h>
 
 int wlan_cfg80211_scan(struct wiphy *wiphy,
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
@@ -32,3 +35,143 @@ int wlan_cfg80211_scan(struct wiphy *wiphy,
 {
 	return 0;
 }
+
+static inline struct ieee80211_channel *
+wlan_get_ieee80211_channel(struct wiphy *wiphy, int chan_no)
+{
+	unsigned int freq;
+	struct ieee80211_channel *chan;
+
+	if (WLAN_CHAN_IS_2GHZ(chan_no) &&
+	   (wiphy->bands[NL80211_BAND_2GHZ] != NULL)) {
+		freq =
+			ieee80211_channel_to_frequency(chan_no,
+			NL80211_BAND_2GHZ);
+	} else if (WLAN_CHAN_IS_5GHZ(chan_no) &&
+	   (wiphy->bands[NL80211_BAND_5GHZ] != NULL)) {
+		freq =
+			ieee80211_channel_to_frequency(chan_no,
+			NL80211_BAND_5GHZ);
+	} else {
+		cfg80211_err("Invalid chan_no %d", chan_no);
+		return NULL;
+	}
+
+	chan = __ieee80211_get_channel(wiphy, freq);
+
+	if (!chan)
+		cfg80211_err("chan is NULL, chan_no: %d freq: %d",
+			chan_no, freq);
+
+	return chan;
+}
+
+#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
+static inline int wlan_get_frame_len(struct scan_cache_entry *scan_params)
+{
+	return util_scan_entry_frame_len(scan_params) + sizeof(qcom_ie_age);
+}
+
+static inline void wlan_add_age_ie(uint8_t *mgmt_frame,
+	struct scan_cache_entry *scan_params)
+{
+	qcom_ie_age *qie_age = NULL;
+
+	/* GPS Requirement: need age ie per entry. Using vendor specific. */
+	/* Assuming this is the last IE, copy at the end */
+	qie_age = (qcom_ie_age *) (mgmt_frame +
+		   util_scan_entry_frame_len(scan_params));
+	qie_age->element_id = QCOM_VENDOR_IE_ID;
+	qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
+	qie_age->oui_1 = QCOM_OUI1;
+	qie_age->oui_2 = QCOM_OUI2;
+	qie_age->oui_3 = QCOM_OUI3;
+	qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
+	/*
+	 * Lowi expects the timestamp of bss in units of 1/10 ms. In driver
+	 * all bss related timestamp is in units of ms. Due to this when scan
+	 * results are sent to lowi the scan age is high.To address this,
+	 * send age in units of 1/10 ms.
+	 */
+	qie_age->age =
+		(uint32_t)(qdf_mc_timer_get_system_time() -
+		  scan_params->scan_entry_time)/10;
+	qie_age->tsf_delta = scan_params->tsf_delta;
+	memcpy(&qie_age->beacon_tsf, scan_params->tsf_info.data,
+		  sizeof(qie_age->beacon_tsf));
+	memcpy(&qie_age->seq_ctrl, &scan_params->seq_num,
+	       sizeof(qie_age->seq_ctrl));
+}
+#else
+static inline int wlan_get_frame_len(struct scan_cache_entry *scan_params)
+{
+	return util_scan_entry_frame_len(scan_params);
+}
+
+static inline void wlan_add_age_ie(uint8_t *mgmt_frame,
+	struct scan_cache_entry *scan_params)
+{
+}
+#endif /* WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS */
+
+void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev,
+		struct scan_cache_entry *scan_params)
+{
+	struct pdev_osif_priv *pdev_ospriv = wlan_pdev_get_ospriv(pdev);
+	struct wiphy *wiphy;
+	int frame_len;
+	struct ieee80211_mgmt *mgmt = NULL;
+	struct ieee80211_channel *chan;
+	int rssi = 0;
+	struct cfg80211_bss *bss_status = NULL;
+
+	if (!pdev_ospriv) {
+		cfg80211_err("os_priv is NULL");
+		return;
+	}
+
+	wiphy = pdev_ospriv->wiphy;
+
+	frame_len = wlan_get_frame_len(scan_params);
+	mgmt = qdf_mem_malloc(frame_len);
+	if (!mgmt) {
+		cfg80211_err("mem alloc failed");
+		return;
+	}
+	qdf_mem_copy(mgmt,
+		 util_scan_entry_frame_ptr(scan_params),
+		 util_scan_entry_frame_len(scan_params));
+	/*
+	 * Android does not want the timestamp from the frame.
+	 * Instead it wants a monotonic increasing value
+	 */
+	mgmt->u.probe_resp.timestamp = qdf_get_monotonic_boottime();
+	wlan_add_age_ie((uint8_t *)mgmt, scan_params);
+	/*
+	 * Based on .ini configuration, raw rssi can be reported for bss.
+	 * Raw rssi is typically used for estimating power.
+	 */
+	rssi = scan_params->rssi_raw;
+
+	chan = wlan_get_ieee80211_channel(wiphy,
+		scan_params->channel.chan_idx);
+	if (!chan) {
+		qdf_mem_free(mgmt);
+		return;
+	}
+
+	/*
+	 * Supplicant takes the signal strength in terms of
+	 * mBm (1 dBm = 100 mBm).
+	 */
+	rssi = QDF_MIN(rssi, 0) * 100;
+
+	cfg80211_info("BSSID: %pM Channel:%d RSSI:%d",
+		mgmt->bssid, chan->center_freq, (int)(rssi / 100));
+
+	bss_status =
+		cfg80211_inform_bss_frame(wiphy, chan, mgmt,
+		frame_len, rssi, GFP_KERNEL);
+	qdf_mem_free(mgmt);
+}
+

+ 18 - 0
os_if/linux/wlan_cfg80211.h

@@ -29,6 +29,24 @@
 #include <net/cfg80211.h>
 #include <qca_vendor.h>
 
+#define cfg80211_log(level, args...) \
+	QDF_TRACE(QDF_MODULE_ID_OS_IF, level, ## args)
+#define cfg80211_logfl(level, format, args...) \
+	cfg80211_log(level, FL(format), ## args)
+
+#define cfg80211_alert(format, args...) \
+	cfg80211_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args)
+#define cfg80211_err(format, args...) \
+	cfg80211_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args)
+#define cfg80211_warn(format, args...) \
+	cfg80211_logfl(QDF_TRACE_LEVEL_WARN, format, ## args)
+#define cfg80211_notice(format, args...) \
+	cfg80211_logfl(QDF_TRACE_LEVEL_INFO, format, ## args)
+#define cfg80211_info(format, args...) \
+	cfg80211_logfl(QDF_TRACE_LEVEL_INFO_HIGH, format, ## args)
+#define cfg80211_debug(format, args...) \
+	cfg80211_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
+
 #define COMMON_VENDOR_COMMANDS						\
 { 									\
 	.info.vendor_id = OUI_QCA,					\