1 /* 2 * Copyright (c) 2011,2017-2021 The Linux Foundation. All rights reserved. 3 * 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <osdep.h> 21 #include <wlan_tgt_def_config.h> 22 #include <hif.h> 23 #include <hif_hw_version.h> 24 #include <wmi_unified_api.h> 25 #include <target_if_spectral.h> 26 #include <wlan_lmac_if_def.h> 27 #include <wlan_osif_priv.h> 28 #include <reg_services_public_struct.h> 29 30 extern int spectral_debug_level; 31 32 #ifdef OPTIMIZED_SAMP_MESSAGE 33 QDF_STATUS 34 target_if_spectral_fill_samp_msg(struct target_if_spectral *spectral, 35 struct target_if_samp_msg_params *params) 36 { 37 struct spectral_samp_msg *spec_samp_msg; 38 struct per_session_det_map *det_map; 39 enum spectral_msg_type msg_type; 40 QDF_STATUS ret; 41 uint16_t dest_det_idx; 42 enum spectral_scan_mode spectral_mode; 43 44 if (!spectral) { 45 spectral_err_rl("Spectral LMAC object is null"); 46 return QDF_STATUS_E_NULL_VALUE; 47 } 48 49 if (!params) { 50 spectral_err_rl("SAMP msg params structure is null"); 51 return QDF_STATUS_E_NULL_VALUE; 52 } 53 54 if (params->hw_detector_id >= SPECTRAL_DETECTOR_ID_MAX) { 55 spectral_err_rl("Invalid detector ID"); 56 return QDF_STATUS_E_FAILURE; 57 } 58 59 spectral_mode = 60 spectral->rparams.detid_mode_table[params->hw_detector_id]; 61 if (spectral_mode >= SPECTRAL_SCAN_MODE_MAX) { 62 spectral_err_rl("No valid Spectral mode for detector id %u", 63 params->hw_detector_id); 64 return QDF_STATUS_E_FAILURE; 65 } 66 67 ret = target_if_get_spectral_msg_type(spectral_mode, 68 &msg_type); 69 if (QDF_IS_STATUS_ERROR(ret)) { 70 spectral_err_rl("Invalid spectral msg type"); 71 return QDF_STATUS_E_FAILURE; 72 } 73 74 qdf_spin_lock_bh(&spectral->session_det_map_lock); 75 76 if (!spectral->det_map[params->hw_detector_id].det_map_valid) { 77 qdf_spin_unlock_bh(&spectral->session_det_map_lock); 78 spectral_info("Detector Map not valid for det id = %d", 79 params->hw_detector_id); 80 return QDF_STATUS_E_FAILURE; 81 } 82 83 det_map = &spectral->det_map[params->hw_detector_id]; 84 85 spec_samp_msg = spectral->nl_cb.get_sbuff(spectral->pdev_obj, 86 msg_type, 87 det_map->buf_type); 88 if (!spec_samp_msg) { 89 qdf_spin_unlock_bh(&spectral->session_det_map_lock); 90 spectral_err_rl("Spectral SAMP message is NULL"); 91 return QDF_STATUS_E_FAILURE; 92 } 93 94 for (dest_det_idx = 0; dest_det_idx < det_map->num_dest_det_info; 95 dest_det_idx++) { 96 struct per_session_dest_det_info *map_det_info; 97 struct spectral_fft_bin_len_adj_swar *swar; 98 struct samp_freq_span_info *span_info; 99 struct samp_detector_info *detector_info; 100 uint8_t dest_detector_id; 101 uint8_t span_id; 102 struct samp_edge_extra_bin_info *lb_edge_bins; 103 struct samp_edge_extra_bin_info *rb_edge_bins; 104 uint8_t *bin_pwr_data; 105 uint32_t *binptr_32; 106 uint16_t *binptr_16; 107 uint16_t pwr_16; 108 size_t pwr_count; 109 uint16_t num_edge_bins; 110 uint16_t idx; 111 uint16_t start_bin_index; 112 113 swar = &spectral->len_adj_swar; 114 115 map_det_info = &det_map->dest_det_info[dest_det_idx]; 116 span_id = map_det_info->freq_span_id; 117 span_info = &spec_samp_msg->freq_span_info[span_id]; 118 span_info->num_detectors++; 119 120 dest_detector_id = map_det_info->det_id; 121 detector_info = &span_info->detector_info[dest_detector_id]; 122 lb_edge_bins = &detector_info->left_edge_bins; 123 rb_edge_bins = &detector_info->right_edge_bins; 124 125 detector_info->start_frequency = map_det_info->start_freq; 126 detector_info->end_frequency = map_det_info->end_freq; 127 detector_info->start_bin_idx = map_det_info->dest_start_bin_idx; 128 detector_info->end_bin_idx = map_det_info->dest_end_bin_idx; 129 lb_edge_bins->start_bin_idx = 130 map_det_info->lb_extrabins_start_idx; 131 lb_edge_bins->num_bins = map_det_info->lb_extrabins_num; 132 rb_edge_bins->start_bin_idx = 133 map_det_info->rb_extrabins_start_idx; 134 rb_edge_bins->num_bins = map_det_info->rb_extrabins_num; 135 start_bin_index = detector_info->start_bin_idx; 136 137 detector_info->rssi = params->rssi; 138 139 detector_info->last_raw_timestamp = params->last_raw_timestamp; 140 detector_info->reset_delay = params->reset_delay; 141 detector_info->raw_timestamp = params->raw_timestamp; 142 detector_info->timestamp = params->timestamp; 143 detector_info->timestamp_war_offset = spectral->timestamp_war. 144 timestamp_war_offset[spectral_mode]; 145 146 detector_info->max_magnitude = params->max_mag; 147 detector_info->max_index = params->max_index; 148 149 detector_info->noise_floor = params->noise_floor; 150 detector_info->agc_total_gain = params->agc_total_gain; 151 detector_info->gainchange = params->gainchange; 152 detector_info->is_sec80 = map_det_info->is_sec80; 153 /* In 165MHz, Pri80 indication to be set for Span ID 0 only */ 154 if (span_id == SPECTRAL_FREQ_SPAN_ID_0) 155 detector_info->pri80ind = params->pri80ind; 156 157 bin_pwr_data = ¶ms->bin_pwr_data 158 [map_det_info->src_start_bin_idx]; 159 pwr_count = detector_info->end_bin_idx - 160 detector_info->start_bin_idx + 1; 161 num_edge_bins = lb_edge_bins->num_bins + 162 rb_edge_bins->num_bins; 163 /* 164 * To check whether FFT bin values exceed 8 bits, we add a 165 * check before copying values to samp_data->bin_pwr. 166 * If it crosses 8 bits, we cap the values to maximum value 167 * supported by 8 bits ie. 255. This needs to be done as the 168 * destination array in SAMP message is 8 bits. This is a 169 * temporary solution till an array of 16 bits is used for 170 * SAMP message. 171 */ 172 if (swar->fftbin_size_war == 173 SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE) { 174 binptr_32 = (uint32_t *)bin_pwr_data; 175 if (lb_edge_bins->num_bins > 0) { 176 for (idx = 0; idx < lb_edge_bins->num_bins; 177 idx++) { 178 /* Read only the first 2 bytes of the DWORD */ 179 pwr_16 = *((uint16_t *)binptr_32++); 180 if (qdf_unlikely(pwr_16 > 181 MAX_FFTBIN_VALUE)) 182 pwr_16 = MAX_FFTBIN_VALUE; 183 spec_samp_msg->bin_pwr 184 [lb_edge_bins->start_bin_idx + idx] 185 = pwr_16; 186 } 187 } 188 for (idx = 0; idx < pwr_count; idx++) { 189 /* Read only the first 2 bytes of the DWORD */ 190 pwr_16 = *((uint16_t *)binptr_32++); 191 if (qdf_unlikely(pwr_16 > MAX_FFTBIN_VALUE)) 192 pwr_16 = MAX_FFTBIN_VALUE; 193 spec_samp_msg->bin_pwr[start_bin_index + idx] 194 = pwr_16; 195 } 196 if (rb_edge_bins->num_bins > 0) { 197 for (idx = 0; idx < rb_edge_bins->num_bins; 198 idx++) { 199 /* Read only the first 2 bytes of the DWORD */ 200 pwr_16 = *((uint16_t *)binptr_32++); 201 if (qdf_unlikely(pwr_16 > 202 MAX_FFTBIN_VALUE)) 203 pwr_16 = MAX_FFTBIN_VALUE; 204 spec_samp_msg->bin_pwr 205 [rb_edge_bins->start_bin_idx + idx] 206 = pwr_16; 207 } 208 } 209 } else if (swar->fftbin_size_war == 210 SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE) { 211 binptr_16 = (uint16_t *)bin_pwr_data; 212 if (lb_edge_bins->num_bins > 0) { 213 for (idx = 0; idx < lb_edge_bins->num_bins; 214 idx++) { 215 pwr_16 = *(binptr_16++); 216 if (qdf_unlikely(pwr_16 > 217 MAX_FFTBIN_VALUE)) 218 pwr_16 = MAX_FFTBIN_VALUE; 219 spec_samp_msg->bin_pwr 220 [lb_edge_bins->start_bin_idx + idx] 221 = pwr_16; 222 } 223 } 224 for (idx = 0; idx < pwr_count; idx++) { 225 pwr_16 = *(binptr_16++); 226 if (qdf_unlikely(pwr_16 > MAX_FFTBIN_VALUE)) 227 pwr_16 = MAX_FFTBIN_VALUE; 228 spec_samp_msg->bin_pwr[start_bin_index + idx] 229 = pwr_16; 230 } 231 if (rb_edge_bins->num_bins > 0) { 232 for (idx = 0; idx < rb_edge_bins->num_bins; 233 idx++) { 234 pwr_16 = *(binptr_16++); 235 if (qdf_unlikely(pwr_16 > 236 MAX_FFTBIN_VALUE)) 237 pwr_16 = MAX_FFTBIN_VALUE; 238 spec_samp_msg->bin_pwr 239 [rb_edge_bins->start_bin_idx + idx] 240 = pwr_16; 241 } 242 } 243 } else { 244 if (lb_edge_bins->num_bins > 0) 245 qdf_mem_copy(&spec_samp_msg->bin_pwr 246 [lb_edge_bins->start_bin_idx], 247 &bin_pwr_data[0], 248 lb_edge_bins->num_bins); 249 qdf_mem_copy(&spec_samp_msg->bin_pwr[start_bin_index], 250 &bin_pwr_data[lb_edge_bins->num_bins], 251 pwr_count); 252 if (rb_edge_bins->num_bins > 0) 253 qdf_mem_copy(&spec_samp_msg->bin_pwr 254 [rb_edge_bins->start_bin_idx], 255 &bin_pwr_data[pwr_count + 256 lb_edge_bins->num_bins], 257 rb_edge_bins->num_bins); 258 } 259 spec_samp_msg->bin_pwr_count += (pwr_count + num_edge_bins); 260 } 261 262 if (det_map->send_to_upper_layers) { 263 /* Fill per-report information */ 264 struct per_session_report_info *rpt_info; 265 struct target_if_spectral_ops *p_sops; 266 267 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 268 269 qdf_spin_lock_bh(&spectral->session_report_info_lock); 270 271 rpt_info = &spectral->report_info[spectral_mode]; 272 spec_samp_msg->signature = SPECTRAL_SIGNATURE; 273 p_sops->get_mac_address(spectral, spec_samp_msg->macaddr); 274 spec_samp_msg->spectral_mode = spectral_mode; 275 spec_samp_msg->target_reset_count = 276 spectral->timestamp_war.target_reset_count; 277 spec_samp_msg->operating_bw = rpt_info->operating_bw; 278 spec_samp_msg->pri20_freq = rpt_info->pri20_freq; 279 spec_samp_msg->cfreq1 = rpt_info->cfreq1; 280 spec_samp_msg->cfreq2 = rpt_info->cfreq2; 281 spec_samp_msg->sscan_cfreq1 = rpt_info->sscan_cfreq1; 282 spec_samp_msg->sscan_cfreq2 = rpt_info->sscan_cfreq2; 283 spec_samp_msg->sscan_bw = rpt_info->sscan_bw; 284 spec_samp_msg->fft_width = FFT_BIN_SIZE_1BYTE; 285 spec_samp_msg->num_freq_spans = rpt_info->num_spans; 286 287 qdf_spin_unlock_bh(&spectral->session_report_info_lock); 288 289 spec_samp_msg->spectral_upper_rssi = params->upper_rssi; 290 spec_samp_msg->spectral_lower_rssi = params->lower_rssi; 291 qdf_mem_copy(spec_samp_msg->spectral_chain_ctl_rssi, 292 params->chain_ctl_rssi, 293 sizeof(params->chain_ctl_rssi)); 294 qdf_mem_copy(spec_samp_msg->spectral_chain_ext_rssi, 295 params->chain_ext_rssi, 296 sizeof(params->chain_ext_rssi)); 297 298 if (spectral_debug_level & DEBUG_SPECTRAL4) 299 target_if_dbg_print_samp_msg(spec_samp_msg); 300 301 if (spectral->send_phy_data(spectral->pdev_obj, 302 msg_type) == 0) 303 spectral->spectral_sent_msg++; 304 if (spectral->spectral_gen == SPECTRAL_GEN3) 305 reset_160mhz_delivery_state_machine(spectral, 306 spectral_mode); 307 } 308 qdf_spin_unlock_bh(&spectral->session_det_map_lock); 309 310 return QDF_STATUS_SUCCESS; 311 } 312 #endif /* OPTIMIZED_SAMP_MESSAGE */ 313 314 #ifndef OPTIMIZED_SAMP_MESSAGE 315 void 316 target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, 317 struct target_if_samp_msg_params *params) 318 { 319 /* 320 * XXX : Non-Rentrant. Will be an issue with dual concurrent 321 * operation on multi-processor system 322 */ 323 324 struct spectral_samp_msg *spec_samp_msg = NULL; 325 326 uint8_t *bin_pwr_data = NULL; 327 struct spectral_classifier_params *cp = NULL; 328 struct spectral_classifier_params *pcp = NULL; 329 struct target_if_spectral_ops *p_sops = NULL; 330 uint32_t *binptr_32 = NULL; 331 uint16_t *binptr_16 = NULL; 332 uint16_t pwr_16; 333 int idx = 0; 334 struct spectral_samp_data *samp_data; 335 static int samp_msg_index; 336 size_t pwr_count = 0; 337 size_t pwr_count_sec80 = 0; 338 size_t pwr_count_5mhz = 0; 339 enum spectral_msg_type msg_type; 340 QDF_STATUS ret; 341 struct spectral_fft_bin_len_adj_swar *swar = &spectral->len_adj_swar; 342 343 ret = target_if_get_spectral_msg_type(params->smode, &msg_type); 344 if (QDF_IS_STATUS_ERROR(ret)) 345 return; 346 347 if (is_primaryseg_rx_inprog(spectral, params->smode)) { 348 spec_samp_msg = (struct spectral_samp_msg *) 349 spectral->nl_cb.get_sbuff(spectral->pdev_obj, 350 msg_type, 351 SPECTRAL_MSG_BUF_NEW); 352 353 if (!spec_samp_msg) 354 return; 355 356 samp_data = &spec_samp_msg->samp_data; 357 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 358 bin_pwr_data = params->bin_pwr_data; 359 360 spec_samp_msg->signature = SPECTRAL_SIGNATURE; 361 spec_samp_msg->freq = params->freq; 362 spec_samp_msg->agile_freq1 = params->agile_freq1; 363 spec_samp_msg->agile_freq2 = params->agile_freq2; 364 spec_samp_msg->freq_loading = params->freq_loading; 365 spec_samp_msg->vhtop_ch_freq_seg1 = params->vhtop_ch_freq_seg1; 366 spec_samp_msg->vhtop_ch_freq_seg2 = params->vhtop_ch_freq_seg2; 367 samp_data->spectral_mode = params->smode; 368 samp_data->spectral_data_len = params->datalen; 369 samp_data->spectral_rssi = params->rssi; 370 samp_data->ch_width = 371 spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL]; 372 samp_data->agile_ch_width = 373 spectral->ch_width[SPECTRAL_SCAN_MODE_AGILE]; 374 samp_data->spectral_agc_total_gain = params->agc_total_gain; 375 samp_data->spectral_gainchange = params->gainchange; 376 samp_data->spectral_pri80ind = params->pri80ind; 377 samp_data->last_raw_timestamp = params->last_raw_timestamp; 378 samp_data->timestamp_war_offset = params->timestamp_war_offset; 379 samp_data->raw_timestamp = params->raw_timestamp; 380 samp_data->reset_delay = params->reset_delay; 381 samp_data->target_reset_count = params->target_reset_count; 382 383 samp_data->spectral_combined_rssi = 384 (uint8_t)params->rssi; 385 samp_data->spectral_upper_rssi = params->upper_rssi; 386 samp_data->spectral_lower_rssi = params->lower_rssi; 387 388 qdf_mem_copy(samp_data->spectral_chain_ctl_rssi, 389 params->chain_ctl_rssi, 390 sizeof(params->chain_ctl_rssi)); 391 qdf_mem_copy(samp_data->spectral_chain_ext_rssi, 392 params->chain_ext_rssi, 393 sizeof(params->chain_ext_rssi)); 394 395 samp_data->spectral_bwinfo = params->bwinfo; 396 samp_data->spectral_tstamp = params->tstamp; 397 samp_data->spectral_max_index = params->max_index; 398 399 /* Classifier in user space needs access to these */ 400 samp_data->spectral_lower_max_index = 401 params->max_lower_index; 402 samp_data->spectral_upper_max_index = 403 params->max_upper_index; 404 samp_data->spectral_nb_lower = params->nb_lower; 405 samp_data->spectral_nb_upper = params->nb_upper; 406 samp_data->spectral_last_tstamp = params->last_tstamp; 407 samp_data->spectral_max_mag = params->max_mag; 408 409 /* 410 * Currently, we compute pwr_count considering the size of the 411 * samp_data->bin_pwr array rather than the number of elements 412 * in this array. The reasons are that 413 * SPECTRAL_MESSAGE_COPY_CHAR_ARRAY() where pwr_count will be 414 * used maps directly to OS_MEMCPY() on little endian platforms, 415 * and that samp_data->bin_pwr is an array of u_int8_t elements 416 * due to which the number of elements in the array == the size 417 * of the array. In case FFT bin size is increased from 8 bits 418 * in the future, this code would have to be changed along with 419 * rest of framework on which it depends. 420 */ 421 pwr_count = qdf_min((size_t)params->pwr_count, 422 sizeof(samp_data->bin_pwr)); 423 424 samp_data->bin_pwr_count = pwr_count; 425 samp_data->lb_edge_extrabins = 426 spectral->lb_edge_extrabins; 427 samp_data->rb_edge_extrabins = 428 spectral->rb_edge_extrabins; 429 samp_data->spectral_combined_rssi = params->rssi; 430 samp_data->spectral_max_scale = params->max_exp; 431 432 samp_data->noise_floor = params->noise_floor; 433 434 /* Classifier in user space needs access to these */ 435 cp = &samp_data->classifier_params; 436 pcp = ¶ms->classifier_params; 437 438 qdf_mem_copy(cp, pcp, 439 sizeof(struct spectral_classifier_params)); 440 441 /* 442 * To check whether FFT bin values exceed 8 bits, we add a 443 * check before copying values to samp_data->bin_pwr. 444 * If it crosses 8 bits, we cap the values to maximum value 445 * supported by 8 bits ie. 255. This needs to be done as the 446 * destination array in SAMP message is 8 bits. This is a 447 * temporary solution till an array of 16 bits is used for 448 * SAMP message. 449 */ 450 if (swar->fftbin_size_war == 451 SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE) { 452 binptr_32 = (uint32_t *)bin_pwr_data; 453 for (idx = 0; idx < pwr_count; idx++) { 454 /* Read only the first 2 bytes of the DWORD */ 455 pwr_16 = *((uint16_t *)binptr_32++); 456 if (qdf_unlikely(pwr_16 > MAX_FFTBIN_VALUE)) 457 pwr_16 = MAX_FFTBIN_VALUE; 458 samp_data->bin_pwr[idx] = pwr_16; 459 } 460 } else if (swar->fftbin_size_war == 461 SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE) { 462 binptr_16 = (uint16_t *)bin_pwr_data; 463 for (idx = 0; idx < pwr_count; idx++) { 464 pwr_16 = *(binptr_16++); 465 if (qdf_unlikely(pwr_16 > MAX_FFTBIN_VALUE)) 466 pwr_16 = MAX_FFTBIN_VALUE; 467 samp_data->bin_pwr[idx] = pwr_16; 468 } 469 } else { 470 SPECTRAL_MESSAGE_COPY_CHAR_ARRAY( 471 &samp_data->bin_pwr[0], bin_pwr_data, 472 pwr_count); 473 } 474 475 p_sops->get_mac_address(spectral, spec_samp_msg->macaddr); 476 } 477 478 if (is_secondaryseg_rx_inprog(spectral, params->smode)) { 479 spec_samp_msg = (struct spectral_samp_msg *) 480 spectral->nl_cb.get_sbuff(spectral->pdev_obj, 481 msg_type, 482 SPECTRAL_MSG_BUF_SAVED); 483 484 if (!spec_samp_msg) { 485 spectral_err("Spectral SAMP message is NULL"); 486 return; 487 } 488 489 samp_data = &spec_samp_msg->samp_data; 490 samp_data->spectral_rssi_sec80 = 491 params->rssi_sec80; 492 samp_data->noise_floor_sec80 = 493 params->noise_floor_sec80; 494 spec_samp_msg->samp_data.spectral_agc_total_gain_sec80 = 495 params->agc_total_gain_sec80; 496 spec_samp_msg->samp_data.spectral_gainchange_sec80 = 497 params->gainchange_sec80; 498 spec_samp_msg->samp_data.spectral_pri80ind_sec80 = 499 params->pri80ind_sec80; 500 501 samp_data->spectral_data_len_sec80 = 502 params->datalen_sec80; 503 samp_data->spectral_max_index_sec80 = 504 params->max_index_sec80; 505 samp_data->spectral_max_mag_sec80 = 506 params->max_mag_sec80; 507 508 samp_data->raw_timestamp_sec80 = params->raw_timestamp_sec80; 509 510 /* 511 * Currently, we compute pwr_count_sec80 considering the size of 512 * the samp_data->bin_pwr_sec80 array rather than the number of 513 * elements in this array. The reasons are that 514 * SPECTRAL_MESSAGE_COPY_CHAR_ARRAY() where pwr_count_sec80 will 515 * be used maps directly to OS_MEMCPY() on little endian 516 * platforms, and that samp_data->bin_pwr_sec80 is an array of 517 * u_int8_t elements due to which the number of elements in the 518 * array == the size of the array. In case FFT bin size is 519 * increased from 8 bits in the future, this code would have to 520 * be changed along with rest of framework on which it depends. 521 */ 522 pwr_count_sec80 = qdf_min((size_t)params->pwr_count_sec80, 523 sizeof(samp_data->bin_pwr_sec80)); 524 pwr_count_5mhz = qdf_min((size_t)params->pwr_count_5mhz, 525 sizeof(samp_data->bin_pwr_5mhz)); 526 527 samp_data->bin_pwr_count_sec80 = pwr_count_sec80; 528 samp_data->bin_pwr_count_5mhz = pwr_count_5mhz; 529 530 bin_pwr_data = params->bin_pwr_data_sec80; 531 532 /* 533 * To check whether FFT bin values exceed 8 bits, we add a 534 * check before copying values to samp_data->bin_pwr_sec80. 535 * If it crosses 8 bits, we cap the values to maximum value 536 * supported by 8 bits ie. 255. This needs to be done as the 537 * destination array in SAMP message is 8 bits. This is a 538 * temporary solution till an array of 16 bits is used for 539 * SAMP message. 540 */ 541 if (swar->fftbin_size_war == 542 SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE) { 543 binptr_32 = (uint32_t *)bin_pwr_data; 544 for (idx = 0; idx < pwr_count_sec80; idx++) { 545 /* Read only the first 2 bytes of the DWORD */ 546 pwr_16 = *((uint16_t *)binptr_32++); 547 if (qdf_unlikely(pwr_16 > MAX_FFTBIN_VALUE)) 548 pwr_16 = MAX_FFTBIN_VALUE; 549 samp_data->bin_pwr_sec80[idx] = pwr_16; 550 } 551 } else if (swar->fftbin_size_war == 552 SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE) { 553 binptr_16 = (uint16_t *)bin_pwr_data; 554 for (idx = 0; idx < pwr_count_sec80; idx++) { 555 pwr_16 = *(binptr_16++); 556 if (qdf_unlikely(pwr_16 > MAX_FFTBIN_VALUE)) 557 pwr_16 = MAX_FFTBIN_VALUE; 558 samp_data->bin_pwr_sec80[idx] = pwr_16; 559 } 560 561 binptr_16 = (uint16_t *)params->bin_pwr_data_5mhz; 562 for (idx = 0; idx < pwr_count_5mhz; idx++) { 563 pwr_16 = *(binptr_16++); 564 if (qdf_unlikely(pwr_16 > MAX_FFTBIN_VALUE)) 565 pwr_16 = MAX_FFTBIN_VALUE; 566 samp_data->bin_pwr_5mhz[idx] = pwr_16; 567 } 568 } else { 569 SPECTRAL_MESSAGE_COPY_CHAR_ARRAY( 570 &samp_data->bin_pwr_sec80[0], 571 params->bin_pwr_data_sec80, 572 pwr_count_sec80); 573 } 574 } 575 576 if (!is_ch_width_160_or_80p80(spectral->ch_width[params->smode]) || 577 is_secondaryseg_rx_inprog(spectral, params->smode)) { 578 if (spectral->send_phy_data(spectral->pdev_obj, 579 msg_type) == 0) 580 spectral->spectral_sent_msg++; 581 samp_msg_index++; 582 } 583 584 /* Take care of state transitions for 160MHz/ 80p80 */ 585 if (spectral->spectral_gen == SPECTRAL_GEN3 && 586 is_ch_width_160_or_80p80(spectral->ch_width[params->smode]) && 587 spectral->rparams.fragmentation_160[params->smode]) 588 target_if_160mhz_delivery_state_change( 589 spectral, params->smode, 590 SPECTRAL_DETECTOR_ID_INVALID); 591 } 592 #endif 593