wlan: add support for vendor specific event
Add support for vendor specific event and use it to provide
interfering frequency information to userspace. Userspace should
stop P2P-GO, in case P2P-GO is operating on interfering frequency
and restart P2P-GO by avoiding interfering frequency range(s). User
space may decide to continue operation on interfering frequency,
but in such case, there might be impact on performance.
CRs-Fixed: 531882
Change-Id: Ife3650d6ccb3c55aea38b5d9ba1e0b8b6c7fbca3
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 131ab42..0666ba1 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -535,6 +535,65 @@
};
#endif /* WLAN_NL80211_TESTMODE */
+#ifdef FEATURE_WLAN_CH_AVOID
+/*
+ * FUNCTION: wlan_hdd_send_avoid_freq_event
+ * This is called when wlan driver needs to send vendor specific
+ * avoid frequency range event to userspace
+ */
+int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
+ tHddAvoidFreqList *pAvoidFreqList)
+{
+ struct sk_buff *vendor_event;
+
+ ENTER();
+
+ if (!pHddCtx)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is null", __func__);
+ return -1;
+ }
+
+ if (!pAvoidFreqList)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: pAvoidFreqList is null", __func__);
+ return -1;
+ }
+
+ vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
+ sizeof(tHddAvoidFreqList),
+ QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
+ GFP_KERNEL);
+ if (!vendor_event)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: cfg80211_vendor_event_alloc failed", __func__);
+ return -1;
+ }
+
+ memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
+ (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
+
+ cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+
+ EXIT();
+ return 0;
+}
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+/* vendor specific events */
+static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
+{
+#ifdef FEATURE_WLAN_CH_AVOID
+ {
+ .vendor_id = QCOM_NL80211_VENDOR_ID,
+ .subcmd = QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
+ },
+#endif /* FEATURE_WLAN_CH_AVOID */
+};
+
/*
* FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
* This function is called by hdd_wlan_startup()
@@ -792,6 +851,10 @@
wiphy->max_remain_on_channel_duration = 1000;
#endif
+ wiphy->n_vendor_commands = 0;
+ wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
+ wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
+
EXIT();
return 0;
}