Forráskód Böngészése

qcacld-3.0: Add support to process freq in driver cmd

Host add support to process frequency if user sends frequency in
place of channel number in driver commands i.e. REASSOC,
SENDACTIONFRAME, FASTREASSOC.

Change-Id: I6e6d15a237d9bb1a973e9f42772c2f02e32fc585
CRs-Fixed: 2760074
Abhishek Ambure 4 éve
szülő
commit
afe7df01d8
1 módosított fájl, 95 hozzáadás és 59 törlés
  1. 95 59
      core/hdd/src/wlan_hdd_ioctl.c

+ 95 - 59
core/hdd/src/wlan_hdd_ioctl.c

@@ -268,17 +268,42 @@ static void hdd_get_band_helper(struct hdd_context *hdd_ctx, int *ui_band)
 	}
 }
 
+/**
+ * hdd_check_and_fill_freq() - to validate chan and convert into freq
+ * @in_chan: input as channel number or freq to be checked
+ * @freq: frequency for input in_chan (output parameter)
+ *
+ * This function checks input "in_chan" is channel number, if yes then fills
+ * appropriate frequency into "freq" out param. If the "in_param" is greater
+ * than WNI_CFG_CURRENT_CHANNEL_STAMAX then checks for valid frequencies.
+ *
+ * Return: true if "in_chan" is valid channel/frequency; false otherwise
+ */
+static bool hdd_check_and_fill_freq(uint32_t in_chan, qdf_freq_t *freq)
+{
+	if (in_chan <= WNI_CFG_CURRENT_CHANNEL_STAMAX)
+		*freq = wlan_chan_to_freq(in_chan);
+	else if (WLAN_REG_IS_24GHZ_CH_FREQ(in_chan) ||
+		 WLAN_REG_IS_5GHZ_CH_FREQ(in_chan) ||
+		 WLAN_REG_IS_6GHZ_CHAN_FREQ(in_chan))
+		*freq = in_chan;
+	else
+		return false;
+
+	return true;
+}
+
 /**
  * _hdd_parse_bssid_and_chan() - helper function to parse bssid and channel
  * @data:            input data
  * @target_ap_bssid: pointer to bssid (output parameter)
- * @channel:         pointer to channel (output parameter)
+ * @freq:         pointer to freq (output parameter)
  *
  * Return: 0 if parsing is successful; -EINVAL otherwise
  */
 static int _hdd_parse_bssid_and_chan(const uint8_t **data,
 				     uint8_t *bssid,
-				     uint8_t *channel)
+				     qdf_freq_t *freq)
 {
 	const uint8_t *in_ptr;
 	int            v = 0;
@@ -343,17 +368,17 @@ static int _hdd_parse_bssid_and_chan(const uint8_t **data,
 	if ('\0' == *in_ptr)
 		goto error;
 
-	/* get the next argument ie the channel number */
+	/* get the next argument ie the channel/freq number */
 	v = sscanf(in_ptr, "%31s ", temp_buf);
 	if (1 != v)
 		goto error;
 
 	v = kstrtos32(temp_buf, 10, &temp_int);
-	if ((v < 0) || (temp_int < 0) ||
-	    (temp_int > WNI_CFG_CURRENT_CHANNEL_STAMAX))
-		return -EINVAL;
+	if (v < 0 || temp_int < 0)
+		goto error;
+	else if (!hdd_check_and_fill_freq(temp_int, freq))
+		goto error;
 
-	*channel = temp_int;
 	*data = in_ptr;
 	return 0;
 error:
@@ -362,7 +387,7 @@ error:
 }
 
 /**
- * hdd_parse_send_action_frame_data() - HDD Parse send action frame data
+ * hdd_parse_send_action_frame_v1_data() - HDD Parse send action frame data
  * @command: Pointer to input data
  * @bssid: Pointer to target Ap bssid
  * @channel: Pointer to the Target AP channel
@@ -372,14 +397,15 @@ error:
  * @buf_len: Pointer to data length
  *
  * This function parses the send action frame data passed in the format
- * SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
+ * SENDACTIONFRAME<space><bssid><space><channel | frequency><space><dwelltime>
+ * <space><data>
  *
  * Return: 0 for success non-zero for failure
  */
 static int
 hdd_parse_send_action_frame_v1_data(const uint8_t *command,
 				    uint8_t *bssid,
-				    uint8_t *channel, uint8_t *dwell_time,
+				    qdf_freq_t *freq, uint8_t *dwell_time,
 				    uint8_t **buf, uint8_t *buf_len)
 {
 	const uint8_t *in_ptr = command;
@@ -391,7 +417,7 @@ hdd_parse_send_action_frame_v1_data(const uint8_t *command,
 	uint8_t temp_buf[32];
 	uint8_t temp_u8 = 0;
 
-	if (_hdd_parse_bssid_and_chan(&in_ptr, bssid, channel))
+	if (_hdd_parse_bssid_and_chan(&in_ptr, bssid, freq))
 		return -EINVAL;
 
 	/* point to the next argument */
@@ -478,20 +504,20 @@ hdd_parse_send_action_frame_v1_data(const uint8_t *command,
  * hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
  * @command: Pointer to input data (its a NULL terminated string)
  * @bssid: Pointer to target Ap bssid
- * @channel: Pointer to the Target AP channel
+ * @freq: Pointer to the Target AP frequency
  *
  * This function parses the reasoc command data passed in the format
- * REASSOC<space><bssid><space><channel>
+ * REASSOC<space><bssid><space><channel/frequency>
  *
  * Return: 0 for success non-zero for failure
  */
 static int hdd_parse_reassoc_command_v1_data(const uint8_t *command,
 					     uint8_t *bssid,
-					     uint8_t *channel)
+					     qdf_freq_t *freq)
 {
 	const uint8_t *in_ptr = command;
 
-	if (_hdd_parse_bssid_and_chan(&in_ptr, bssid, channel))
+	if (_hdd_parse_bssid_and_chan(&in_ptr, bssid, freq))
 		return -EINVAL;
 
 	return 0;
@@ -633,28 +659,28 @@ exit:
  *
  * This function parses the v1 REASSOC command with the format
  *
- *    REASSOC xx:xx:xx:xx:xx:xx CH
+ *    REASSOC xx:xx:xx:xx:xx:xx CH/FREQ
  *
  * Where "xx:xx:xx:xx:xx:xx" is the Hex-ASCII representation of the
- * BSSID and CH is the ASCII representation of the channel.  For
- * example
+ * BSSID and CH/FREQ is the ASCII representation of the channel/frequency.
+ * For example
  *
  *    REASSOC 00:0a:0b:11:22:33 48
+ *    REASSOC 00:0a:0b:11:22:33 2412
  *
  * Return: 0 for success non-zero for failure
  */
 static int hdd_parse_reassoc_v1(struct hdd_adapter *adapter, const char *command)
 {
-	uint8_t channel = 0;
+	qdf_freq_t freq = 0;
 	tSirMacAddr bssid;
 	int ret;
 
-	ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
+	ret = hdd_parse_reassoc_command_v1_data(command, bssid, &freq);
 	if (ret)
 		hdd_err("Failed to parse reassoc command data");
 	else
-		ret = hdd_reassoc(adapter, bssid,
-				  wlan_chan_to_freq(channel), REASSOC);
+		ret = hdd_reassoc(adapter, bssid, freq, REASSOC);
 
 	return ret;
 }
@@ -678,6 +704,7 @@ static int hdd_parse_reassoc_v2(struct hdd_adapter *adapter,
 {
 	struct android_wifi_reassoc_params params;
 	tSirMacAddr bssid;
+	qdf_freq_t freq = 0;
 	int ret;
 
 	if (total_len < sizeof(params) + 8) {
@@ -692,9 +719,18 @@ static int hdd_parse_reassoc_v2(struct hdd_adapter *adapter,
 		hdd_err("MAC address parsing failed");
 		ret = -EINVAL;
 	} else {
-		ret = hdd_reassoc(adapter, bssid,
-				  wlan_chan_to_freq(params.channel), REASSOC);
+		/*
+		 * In Reassoc command, user can send channel number or frequency
+		 * along with BSSID. If params.channel param of REASSOC command
+		 * is less than WNI_CFG_CURRENT_CHANNEL_STAMAX, then host
+		 * consider this as channel number else frequency.
+		 */
+		if (!hdd_check_and_fill_freq(params.channel, &freq))
+			return -EINVAL;
+
+		ret = hdd_reassoc(adapter, bssid, freq, REASSOC);
 	}
+
 	return ret;
 }
 
@@ -720,7 +756,7 @@ static int hdd_parse_reassoc(struct hdd_adapter *adapter, const char *command,
 
 	/* both versions start with "REASSOC "
 	 * v1 has a bssid and channel # as an ASCII string
-	 *    REASSOC xx:xx:xx:xx:xx:xx CH
+	 *    REASSOC xx:xx:xx:xx:xx:xx CH/FREQ
 	 * v2 has a C struct
 	 *    REASSOC <binary c struct>
 	 *
@@ -762,7 +798,7 @@ void hdd_abort_roam_scan(struct hdd_context *hdd_ctx, uint8_t vdev_id)
  * hdd_sendactionframe() - send a userspace-supplied action frame
  * @adapter:	Adapter upon which the command was received
  * @bssid:	BSSID target of the action frame
- * @channel:	Channel upon which to send the frame
+ * @freq:	Frequency upon which to send the frame
  * @dwell_time:	Amount of time to dwell when the frame is sent
  * @payload_len:Length of the payload
  * @payload:	Payload of the frame
@@ -773,11 +809,10 @@ void hdd_abort_roam_scan(struct hdd_context *hdd_ctx, uint8_t vdev_id)
  */
 static int
 hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid,
-		    const uint8_t channel, const uint8_t dwell_time,
+		    const qdf_freq_t freq, const uint8_t dwell_time,
 		    const int payload_len, const uint8_t *payload)
 {
 	struct ieee80211_channel chan;
-	uint8_t conn_info_channel;
 	int frame_len, ret = 0;
 	uint8_t *frame;
 	struct ieee80211_hdr_3addr *hdr;
@@ -823,25 +858,22 @@ hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid,
 		goto exit;
 	}
 
-	chan.center_freq = sme_chn_to_freq(channel);
+	chan.center_freq = freq;
 	/* Check if it is specific action frame */
 	if (vendor->category ==
 	    SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY) {
 		static const uint8_t oui[] = { 0x00, 0x00, 0xf0 };
 
 		if (!qdf_mem_cmp(vendor->Oui, oui, 3)) {
-			conn_info_channel = wlan_reg_freq_to_chan(
-						hdd_ctx->pdev,
-						sta_ctx->conn_info.chan_freq);
 			/*
-			 * if the channel number is different from operating
-			 * channel then no need to send action frame
+			 * if the freq number is different from operating
+			 * freq then no need to send action frame
 			 */
-			if (channel != 0) {
-				if (channel != conn_info_channel) {
-					hdd_warn("channel(%u) is different from operating channel(%u)",
-						 channel,
-						 conn_info_channel);
+			if (freq) {
+				if (freq != sta_ctx->conn_info.chan_freq) {
+					hdd_warn("freq(%u) is different from operating freq(%u)",
+						 freq,
+						 sta_ctx->conn_info.chan_freq);
 					ret = -EINVAL;
 					goto exit;
 				}
@@ -856,7 +888,7 @@ hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid,
 				hdd_abort_roam_scan(hdd_ctx, adapter->vdev_id);
 			} else {
 				/*
-				 * 0 is accepted as current home channel,
+				 * 0 is accepted as current home frequency,
 				 * delayed transmission of action frame is ok.
 				 */
 				chan.center_freq = sta_ctx->conn_info.chan_freq;
@@ -864,7 +896,7 @@ hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid,
 		}
 	}
 	if (chan.center_freq == 0) {
-		hdd_err("Invalid channel number: %d", channel);
+		hdd_nofl_err("Invalid freq : %d", freq);
 		ret = -EINVAL;
 		goto exit;
 	}
@@ -930,20 +962,20 @@ exit:
 static int
 hdd_parse_sendactionframe_v1(struct hdd_adapter *adapter, const char *command)
 {
-	uint8_t channel = 0;
+	qdf_freq_t freq = 0;
 	uint8_t dwell_time = 0;
 	uint8_t payload_len = 0;
 	uint8_t *payload = NULL;
 	tSirMacAddr bssid;
 	int ret;
 
-	ret = hdd_parse_send_action_frame_v1_data(command, bssid, &channel,
+	ret = hdd_parse_send_action_frame_v1_data(command, bssid, &freq,
 						  &dwell_time, &payload,
 						  &payload_len);
 	if (ret) {
-		hdd_err("Failed to parse send action frame data");
+		hdd_nofl_err("Failed to parse send action frame data");
 	} else {
-		ret = hdd_sendactionframe(adapter, bssid, channel,
+		ret = hdd_sendactionframe(adapter, bssid, freq,
 					  dwell_time, payload_len, payload);
 		qdf_mem_free(payload);
 	}
@@ -972,6 +1004,7 @@ hdd_parse_sendactionframe_v2(struct hdd_adapter *adapter,
 	tSirMacAddr bssid;
 	int ret;
 	int len_wo_payload = 0;
+	qdf_freq_t freq = 0;
 
 	/* The params are located after "SENDACTIONFRAME " */
 	total_len -= 16;
@@ -1005,8 +1038,13 @@ hdd_parse_sendactionframe_v2(struct hdd_adapter *adapter,
 		return -EINVAL;
 	}
 
-	ret = hdd_sendactionframe(adapter, bssid, params->channel,
-				params->dwell_time, params->len, params->data);
+	if (!hdd_check_and_fill_freq(params->channel, &freq)) {
+		hdd_err("Invalid channel: %d", params->channel);
+		return -EINVAL;
+	}
+
+	ret = hdd_sendactionframe(adapter, bssid, freq, params->dwell_time,
+				  params->len, params->data);
 
 	return ret;
 }
@@ -4302,8 +4340,7 @@ static int drv_cmd_fast_reassoc(struct hdd_adapter *adapter,
 {
 	int ret = 0;
 	uint8_t *value = command;
-	uint8_t channel = 0;
-	uint32_t ch_freq;
+	qdf_freq_t freq = 0;
 	tSirMacAddr bssid;
 	uint32_t roam_id = INVALID_ROAM_ID;
 	tCsrRoamModifyProfileFields mod_fields;
@@ -4329,7 +4366,7 @@ static int drv_cmd_fast_reassoc(struct hdd_adapter *adapter,
 	}
 
 	ret = hdd_parse_reassoc_command_v1_data(value, bssid,
-						&channel);
+						&freq);
 	if (ret) {
 		hdd_err("Failed to parse reassoc command data");
 		goto exit;
@@ -4344,8 +4381,8 @@ static int drv_cmd_fast_reassoc(struct hdd_adapter *adapter,
 			 QDF_MAC_ADDR_SIZE)) {
 		hdd_warn("Reassoc BSSID is same as currently associated AP bssid");
 		if (roaming_offload_enabled(hdd_ctx)) {
-			ch_freq = sta_ctx->conn_info.chan_freq;
-			hdd_wma_send_fastreassoc_cmd(adapter, bssid, ch_freq);
+			hdd_wma_send_fastreassoc_cmd(
+				adapter, bssid, sta_ctx->conn_info.chan_freq);
 		} else {
 			sme_get_modify_profile_fields(mac_handle,
 				adapter->vdev_id,
@@ -4356,20 +4393,19 @@ static int drv_cmd_fast_reassoc(struct hdd_adapter *adapter,
 		return 0;
 	}
 
-	/* Check channel number is a valid channel number */
-	if (channel && (QDF_STATUS_SUCCESS !=
-		wlan_hdd_validate_operation_channel(adapter, channel))) {
-		hdd_err("Invalid Channel [%d]", channel);
+	/* Check freq number is a valid freq number */
+	if (freq && QDF_STATUS_SUCCESS !=
+		wlan_hdd_validate_operation_channel(adapter, freq)) {
+		hdd_err("Invalid freq [%d]", freq);
 		return -EINVAL;
 	}
 
-	ch_freq = wlan_reg_chan_to_freq(hdd_ctx->pdev, channel);
 	if (roaming_offload_enabled(hdd_ctx)) {
-		hdd_wma_send_fastreassoc_cmd(adapter, bssid, ch_freq);
+		hdd_wma_send_fastreassoc_cmd(adapter, bssid, freq);
 		goto exit;
 	}
 	/* Proceed with reassoc */
-	req.ch_freq = ch_freq;
+	req.ch_freq = freq;
 	req.src = FASTREASSOC;
 	qdf_mem_copy(req.bssid.bytes, bssid, sizeof(tSirMacAddr));
 	sme_handoff_request(mac_handle, adapter->vdev_id, &req);