qcacld-3.0: Send mgmt frame with NULL channel

It won't send mgmt frame with NULL channel information currently,
which is different to other branches. Add this change because up layer
pass NULL channel information when tx mgmt frame in some platform.

Change-Id: I689d64789187fe0df03ed57ef0ff10c5157aeeb6
CRs-Fixed: 2459485
diff --git a/components/p2p/core/src/wlan_p2p_off_chan_tx.c b/components/p2p/core/src/wlan_p2p_off_chan_tx.c
index f0bea5c..aa2cb76 100644
--- a/components/p2p/core/src/wlan_p2p_off_chan_tx.c
+++ b/components/p2p/core/src/wlan_p2p_off_chan_tx.c
@@ -166,6 +166,52 @@
 #endif /* SUPPORT_P2P_BY_ONE_INTF_WLAN */
 
 /**
+ * p2p_check_and_update_channel() - check and update tx channel
+ * @tx_ctx:         tx context
+ *
+ * This function checks and updates tx channel if channel is 0 in tx context.
+ * It will update channel to current roc channel if vdev mode is
+ * P2P DEVICE/CLIENT/GO.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+static QDF_STATUS p2p_check_and_update_channel(struct tx_action_context *tx_ctx)
+{
+	enum QDF_OPMODE mode;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_psoc *psoc;
+	struct p2p_soc_priv_obj *p2p_soc_obj;
+	struct p2p_roc_context *curr_roc_ctx;
+
+	if (!tx_ctx || tx_ctx->chan) {
+		p2p_err("NULL tx ctx or channel valid");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	p2p_soc_obj = tx_ctx->p2p_soc_obj;
+	psoc = p2p_soc_obj->soc;
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+			psoc, tx_ctx->vdev_id, WLAN_P2P_ID);
+	if (!vdev) {
+		p2p_err("null vdev object");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mode = wlan_vdev_mlme_get_opmode(vdev);
+	curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj);
+
+	if (curr_roc_ctx &&
+	    (mode == QDF_P2P_DEVICE_MODE ||
+	     mode == QDF_P2P_CLIENT_MODE ||
+	     mode == QDF_P2P_GO_MODE))
+		tx_ctx->chan = curr_roc_ctx->chan;
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
  * p2p_get_p2pie_ptr() - get the pointer to p2p ie
  * @ie:      source ie
  * @ie_len:  source ie length
@@ -948,13 +994,16 @@
 	void *mac_addr;
 	uint8_t pdev_id;
 	struct wlan_objmgr_vdev *vdev;
+	uint16_t chanfreq = 0;
 
 	psoc = tx_ctx->p2p_soc_obj->soc;
 	mgmt_param.tx_frame = packet;
 	mgmt_param.frm_len = buf_len;
 	mgmt_param.vdev_id = tx_ctx->vdev_id;
 	mgmt_param.pdata = frame;
-	mgmt_param.chanfreq = wlan_chan_to_freq(tx_ctx->chan);
+	if (tx_ctx->chan)
+		chanfreq = (uint16_t)wlan_chan_to_freq(tx_ctx->chan);
+	mgmt_param.chanfreq = chanfreq;
 
 	mgmt_param.qdf_ctx = wlan_psoc_get_qdf_dev(psoc);
 	if (!(mgmt_param.qdf_ctx)) {
@@ -2786,7 +2835,9 @@
 		tx_ctx->no_ack = 1;
 	}
 
-	if (!tx_ctx->off_chan) {
+	if (!tx_ctx->off_chan || !tx_ctx->chan) {
+		if (!tx_ctx->chan)
+			p2p_check_and_update_channel(tx_ctx);
 		status = p2p_execute_tx_action_frame(tx_ctx);
 		if (status != QDF_STATUS_SUCCESS) {
 			p2p_err("execute tx fail");
diff --git a/os_if/p2p/src/wlan_cfg80211_p2p.c b/os_if/p2p/src/wlan_cfg80211_p2p.c
index 009b3e8..652a128 100644
--- a/os_if/p2p/src/wlan_cfg80211_p2p.c
+++ b/os_if/p2p/src/wlan_cfg80211_p2p.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -425,16 +425,17 @@
 	struct p2p_mgmt_tx mgmt_tx = {0};
 	struct wlan_objmgr_psoc *psoc;
 	uint8_t vdev_id;
+	uint32_t channel = 0;
 
 	if (!vdev) {
 		cfg80211_err("invalid vdev object");
 		return -EINVAL;
 	}
 
-	if (!chan) {
-		cfg80211_err("invalid channel");
-		return -EINVAL;
-	}
+	if (chan)
+		channel = (uint32_t)wlan_freq_to_chan(chan->center_freq);
+	else
+		cfg80211_debug("NULL chan, set channel to 0");
 
 	psoc = wlan_vdev_get_psoc(vdev);
 	vdev_id = wlan_vdev_get_id(vdev);
@@ -450,7 +451,6 @@
 	if (wait > MAX_OFFCHAN_TIME_FOR_DNBS) {
 		int ret;
 		bool ok;
-		uint32_t channel = wlan_freq_to_chan(chan->center_freq);
 
 		ret = policy_mgr_is_chan_ok_for_dnbs(psoc, channel, &ok);
 		if (QDF_IS_STATUS_ERROR(ret)) {
@@ -466,7 +466,7 @@
 	}
 
 	mgmt_tx.vdev_id = (uint32_t)vdev_id;
-	mgmt_tx.chan = (uint32_t)wlan_freq_to_chan(chan->center_freq);
+	mgmt_tx.chan = channel;
 	mgmt_tx.wait = wait;
 	mgmt_tx.len = len;
 	mgmt_tx.no_cck = (uint32_t)no_cck;