.. | .. |
---|
19 | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
20 | 20 | * General Public License for more details. |
---|
21 | 21 | * |
---|
22 | | - * You should have received a copy of the GNU General Public License |
---|
23 | | - * along with this program; if not, write to the Free Software |
---|
24 | | - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, |
---|
25 | | - * USA |
---|
26 | | - * |
---|
27 | 22 | * The full GNU General Public License is included in this distribution |
---|
28 | 23 | * in the file called COPYING. |
---|
29 | 24 | * |
---|
.. | .. |
---|
183 | 178 | } else { |
---|
184 | 179 | IWL_DEBUG_EEPROM(mvm->trans->dev, |
---|
185 | 180 | "NVM access command failed with status %d (device: %s)\n", |
---|
186 | | - ret, mvm->cfg->name); |
---|
187 | | - ret = -EIO; |
---|
| 181 | + ret, mvm->trans->name); |
---|
| 182 | + ret = -ENODATA; |
---|
188 | 183 | } |
---|
189 | 184 | goto exit; |
---|
190 | 185 | } |
---|
.. | .. |
---|
254 | 249 | while (ret == length) { |
---|
255 | 250 | /* Check no memory assumptions fail and cause an overflow */ |
---|
256 | 251 | if ((size_read + offset + length) > |
---|
257 | | - mvm->cfg->base_params->eeprom_size) { |
---|
| 252 | + mvm->trans->trans_cfg->base_params->eeprom_size) { |
---|
258 | 253 | IWL_ERR(mvm, "EEPROM size is too small for NVM\n"); |
---|
259 | 254 | return -ENOBUFS; |
---|
260 | 255 | } |
---|
.. | .. |
---|
282 | 277 | struct iwl_nvm_section *sections = mvm->nvm_sections; |
---|
283 | 278 | const __be16 *hw; |
---|
284 | 279 | const __le16 *sw, *calib, *regulatory, *mac_override, *phy_sku; |
---|
285 | | - bool lar_enabled; |
---|
286 | 280 | int regulatory_type; |
---|
287 | 281 | |
---|
288 | 282 | /* Checking for required sections */ |
---|
.. | .. |
---|
333 | 327 | (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY_SDP].data : |
---|
334 | 328 | (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data; |
---|
335 | 329 | |
---|
336 | | - lar_enabled = !iwlwifi_mod_params.lar_disable && |
---|
337 | | - fw_has_capa(&mvm->fw->ucode_capa, |
---|
338 | | - IWL_UCODE_TLV_CAPA_LAR_SUPPORT); |
---|
339 | | - |
---|
340 | | - return iwl_parse_nvm_data(mvm->trans, mvm->cfg, hw, sw, calib, |
---|
| 330 | + return iwl_parse_nvm_data(mvm->trans, mvm->cfg, mvm->fw, hw, sw, calib, |
---|
341 | 331 | regulatory, mac_override, phy_sku, |
---|
342 | | - mvm->fw->valid_tx_ant, mvm->fw->valid_rx_ant, |
---|
343 | | - lar_enabled); |
---|
| 332 | + mvm->fw->valid_tx_ant, mvm->fw->valid_rx_ant); |
---|
344 | 333 | } |
---|
345 | 334 | |
---|
346 | 335 | /* Loads the NVM data stored in mvm->nvm_sections into the NIC */ |
---|
.. | .. |
---|
378 | 367 | /* Read From FW NVM */ |
---|
379 | 368 | IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n"); |
---|
380 | 369 | |
---|
381 | | - nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, |
---|
| 370 | + nvm_buffer = kmalloc(mvm->trans->trans_cfg->base_params->eeprom_size, |
---|
382 | 371 | GFP_KERNEL); |
---|
383 | 372 | if (!nvm_buffer) |
---|
384 | 373 | return -ENOMEM; |
---|
.. | .. |
---|
386 | 375 | /* we override the constness for initial read */ |
---|
387 | 376 | ret = iwl_nvm_read_section(mvm, section, nvm_buffer, |
---|
388 | 377 | size_read); |
---|
389 | | - if (ret < 0) |
---|
| 378 | + if (ret == -ENODATA) { |
---|
| 379 | + ret = 0; |
---|
390 | 380 | continue; |
---|
| 381 | + } |
---|
| 382 | + if (ret < 0) |
---|
| 383 | + break; |
---|
391 | 384 | size_read += ret; |
---|
392 | 385 | temp = kmemdup(nvm_buffer, ret, GFP_KERNEL); |
---|
393 | 386 | if (!temp) { |
---|
.. | .. |
---|
417 | 410 | case NVM_SECTION_TYPE_PHY_SKU: |
---|
418 | 411 | mvm->nvm_phy_sku_blob.data = temp; |
---|
419 | 412 | mvm->nvm_phy_sku_blob.size = ret; |
---|
| 413 | + break; |
---|
| 414 | + case NVM_SECTION_TYPE_REGULATORY_SDP: |
---|
| 415 | + case NVM_SECTION_TYPE_REGULATORY: |
---|
| 416 | + mvm->nvm_reg_blob.data = temp; |
---|
| 417 | + mvm->nvm_reg_blob.size = ret; |
---|
420 | 418 | break; |
---|
421 | 419 | default: |
---|
422 | 420 | if (section == mvm->cfg->nvm_hw_section_num) { |
---|
.. | .. |
---|
460 | 458 | IWL_DEBUG_EEPROM(mvm->trans->dev, "nvm version = %x\n", |
---|
461 | 459 | mvm->nvm_data->nvm_version); |
---|
462 | 460 | |
---|
463 | | - return 0; |
---|
| 461 | + return ret < 0 ? ret : 0; |
---|
464 | 462 | } |
---|
465 | 463 | |
---|
466 | 464 | struct iwl_mcc_update_resp * |
---|
.. | .. |
---|
483 | 481 | u32 status; |
---|
484 | 482 | int resp_len, n_channels; |
---|
485 | 483 | u16 mcc; |
---|
486 | | - bool resp_v2 = fw_has_capa(&mvm->fw->ucode_capa, |
---|
487 | | - IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2); |
---|
488 | 484 | |
---|
489 | 485 | if (WARN_ON_ONCE(!iwl_mvm_is_lar_supported(mvm))) |
---|
490 | 486 | return ERR_PTR(-EOPNOTSUPP); |
---|
491 | 487 | |
---|
492 | 488 | cmd.len[0] = sizeof(struct iwl_mcc_update_cmd); |
---|
493 | | - if (!resp_v2) |
---|
494 | | - cmd.len[0] = sizeof(struct iwl_mcc_update_cmd_v1); |
---|
495 | 489 | |
---|
496 | 490 | IWL_DEBUG_LAR(mvm, "send MCC update to FW with '%c%c' src = %d\n", |
---|
497 | 491 | alpha2[0], alpha2[1], src_id); |
---|
.. | .. |
---|
503 | 497 | pkt = cmd.resp_pkt; |
---|
504 | 498 | |
---|
505 | 499 | /* Extract MCC response */ |
---|
506 | | - if (resp_v2) { |
---|
| 500 | + if (fw_has_capa(&mvm->fw->ucode_capa, |
---|
| 501 | + IWL_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT)) { |
---|
507 | 502 | struct iwl_mcc_update_resp *mcc_resp = (void *)pkt->data; |
---|
508 | 503 | |
---|
509 | 504 | n_channels = __le32_to_cpu(mcc_resp->n_channels); |
---|
.. | .. |
---|
515 | 510 | goto exit; |
---|
516 | 511 | } |
---|
517 | 512 | } else { |
---|
518 | | - struct iwl_mcc_update_resp_v1 *mcc_resp_v1 = (void *)pkt->data; |
---|
| 513 | + struct iwl_mcc_update_resp_v3 *mcc_resp_v3 = (void *)pkt->data; |
---|
519 | 514 | |
---|
520 | | - n_channels = __le32_to_cpu(mcc_resp_v1->n_channels); |
---|
| 515 | + n_channels = __le32_to_cpu(mcc_resp_v3->n_channels); |
---|
521 | 516 | resp_len = sizeof(struct iwl_mcc_update_resp) + |
---|
522 | 517 | n_channels * sizeof(__le32); |
---|
523 | 518 | resp_cp = kzalloc(resp_len, GFP_KERNEL); |
---|
.. | .. |
---|
526 | 521 | goto exit; |
---|
527 | 522 | } |
---|
528 | 523 | |
---|
529 | | - resp_cp->status = mcc_resp_v1->status; |
---|
530 | | - resp_cp->mcc = mcc_resp_v1->mcc; |
---|
531 | | - resp_cp->cap = mcc_resp_v1->cap; |
---|
532 | | - resp_cp->source_id = mcc_resp_v1->source_id; |
---|
533 | | - resp_cp->n_channels = mcc_resp_v1->n_channels; |
---|
534 | | - memcpy(resp_cp->channels, mcc_resp_v1->channels, |
---|
| 524 | + resp_cp->status = mcc_resp_v3->status; |
---|
| 525 | + resp_cp->mcc = mcc_resp_v3->mcc; |
---|
| 526 | + resp_cp->cap = cpu_to_le16(mcc_resp_v3->cap); |
---|
| 527 | + resp_cp->source_id = mcc_resp_v3->source_id; |
---|
| 528 | + resp_cp->time = mcc_resp_v3->time; |
---|
| 529 | + resp_cp->geo_info = mcc_resp_v3->geo_info; |
---|
| 530 | + resp_cp->n_channels = mcc_resp_v3->n_channels; |
---|
| 531 | + memcpy(resp_cp->channels, mcc_resp_v3->channels, |
---|
535 | 532 | n_channels * sizeof(__le32)); |
---|
536 | 533 | } |
---|
537 | 534 | |
---|
.. | .. |
---|
618 | 615 | enum iwl_mcc_source src; |
---|
619 | 616 | char mcc[3]; |
---|
620 | 617 | struct ieee80211_regdomain *regd; |
---|
| 618 | + int wgds_tbl_idx; |
---|
621 | 619 | |
---|
622 | 620 | lockdep_assert_held(&mvm->mutex); |
---|
623 | 621 | |
---|
.. | .. |
---|
641 | 639 | if (IS_ERR_OR_NULL(regd)) |
---|
642 | 640 | return; |
---|
643 | 641 | |
---|
| 642 | + wgds_tbl_idx = iwl_mvm_get_sar_geo_profile(mvm); |
---|
| 643 | + if (wgds_tbl_idx < 0) |
---|
| 644 | + IWL_DEBUG_INFO(mvm, "SAR WGDS is disabled (%d)\n", |
---|
| 645 | + wgds_tbl_idx); |
---|
| 646 | + else |
---|
| 647 | + IWL_DEBUG_INFO(mvm, "SAR WGDS: geo profile %d is configured\n", |
---|
| 648 | + wgds_tbl_idx); |
---|
| 649 | + |
---|
644 | 650 | regulatory_set_wiphy_regd(mvm->hw->wiphy, regd); |
---|
645 | 651 | kfree(regd); |
---|
646 | 652 | } |
---|