diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 51 |
1 files changed, 17 insertions, 34 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 127c842fea55..2205b6035207 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |||
@@ -542,8 +542,6 @@ int iwlagn_alive_notify(struct iwl_priv *priv) | |||
542 | static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) | 542 | static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) |
543 | { | 543 | { |
544 | u32 val; | 544 | u32 val; |
545 | int ret = 0; | ||
546 | u32 errcnt = 0; | ||
547 | u32 i; | 545 | u32 i; |
548 | 546 | ||
549 | IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); | 547 | IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); |
@@ -555,56 +553,39 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 | |||
555 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, | 553 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, |
556 | i + IWLAGN_RTC_INST_LOWER_BOUND); | 554 | i + IWLAGN_RTC_INST_LOWER_BOUND); |
557 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 555 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
558 | if (val != le32_to_cpu(*image)) { | 556 | if (val != le32_to_cpu(*image)) |
559 | ret = -EIO; | 557 | return -EIO; |
560 | errcnt++; | ||
561 | if (errcnt >= 3) | ||
562 | break; | ||
563 | } | ||
564 | } | 558 | } |
565 | 559 | ||
566 | return ret; | 560 | return 0; |
567 | } | 561 | } |
568 | 562 | ||
569 | /** | 563 | static void iwl_print_mismatch_inst(struct iwl_priv *priv, |
570 | * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host, | 564 | __le32 *image, u32 len) |
571 | * looking at all data. | ||
572 | */ | ||
573 | static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image, | ||
574 | u32 len) | ||
575 | { | 565 | { |
576 | u32 val; | 566 | u32 val; |
577 | u32 save_len = len; | 567 | u32 offs; |
578 | int ret = 0; | 568 | int errors = 0; |
579 | u32 errcnt; | ||
580 | 569 | ||
581 | IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); | 570 | IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); |
582 | 571 | ||
583 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, | 572 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, |
584 | IWLAGN_RTC_INST_LOWER_BOUND); | 573 | IWLAGN_RTC_INST_LOWER_BOUND); |
585 | 574 | ||
586 | errcnt = 0; | 575 | for (offs = 0; |
587 | for (; len > 0; len -= sizeof(u32), image++) { | 576 | offs < len && errors < 20; |
577 | offs += sizeof(u32), image++) { | ||
588 | /* read data comes through single port, auto-incr addr */ | 578 | /* read data comes through single port, auto-incr addr */ |
589 | /* NOTE: Use the debugless read so we don't flood kernel log | 579 | /* NOTE: Use the debugless read so we don't flood kernel log |
590 | * if IWL_DL_IO is set */ | 580 | * if IWL_DL_IO is set */ |
591 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 581 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
592 | if (val != le32_to_cpu(*image)) { | 582 | if (val != le32_to_cpu(*image)) { |
593 | IWL_ERR(priv, "uCode INST section is invalid at " | 583 | IWL_ERR(priv, "uCode INST section at " |
594 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | 584 | "offset 0x%x, is 0x%x, s/b 0x%x\n", |
595 | save_len - len, val, le32_to_cpu(*image)); | 585 | offs, val, le32_to_cpu(*image)); |
596 | ret = -EIO; | 586 | errors++; |
597 | errcnt++; | ||
598 | if (errcnt >= 20) | ||
599 | break; | ||
600 | } | 587 | } |
601 | } | 588 | } |
602 | |||
603 | if (!errcnt) | ||
604 | IWL_DEBUG_INFO(priv, | ||
605 | "ucode image in INSTRUCTION memory is good\n"); | ||
606 | |||
607 | return ret; | ||
608 | } | 589 | } |
609 | 590 | ||
610 | /** | 591 | /** |
@@ -651,5 +632,7 @@ int iwl_verify_ucode(struct iwl_priv *priv) | |||
651 | * Selection of bootstrap image (vs. other images) is arbitrary. */ | 632 | * Selection of bootstrap image (vs. other images) is arbitrary. */ |
652 | image = (__le32 *)priv->ucode_boot.v_addr; | 633 | image = (__le32 *)priv->ucode_boot.v_addr; |
653 | len = priv->ucode_boot.len; | 634 | len = priv->ucode_boot.len; |
654 | return iwl_verify_inst_full(priv, image, len); | 635 | iwl_print_mismatch_inst(priv, image, len); |
636 | |||
637 | return -EIO; | ||
655 | } | 638 | } |