diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2008-04-24 14:55:18 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-07 15:02:21 -0400 |
commit | b0692f2ff308f2645a43b415393d934eb939cc6c (patch) | |
tree | 6dfa2676a14d01b675f11cafb3a55a832a0bfeb7 | |
parent | 5b28d3c156472cfb713fafecdf398739d22a0738 (diff) |
iwlwifi: move verify_ucode functions to iwl-core
This patch moves verify_ucode functions to iwl-core.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 134 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 144 |
3 files changed, 137 insertions, 142 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index ca32fb3b9e1b..8c8b51dea57b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -704,3 +704,137 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags) | |||
704 | } | 704 | } |
705 | EXPORT_SYMBOL(iwl_send_statistics_request); | 705 | EXPORT_SYMBOL(iwl_send_statistics_request); |
706 | 706 | ||
707 | /** | ||
708 | * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host, | ||
709 | * using sample data 100 bytes apart. If these sample points are good, | ||
710 | * it's a pretty good bet that everything between them is good, too. | ||
711 | */ | ||
712 | static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) | ||
713 | { | ||
714 | u32 val; | ||
715 | int ret = 0; | ||
716 | u32 errcnt = 0; | ||
717 | u32 i; | ||
718 | |||
719 | IWL_DEBUG_INFO("ucode inst image size is %u\n", len); | ||
720 | |||
721 | ret = iwl_grab_nic_access(priv); | ||
722 | if (ret) | ||
723 | return ret; | ||
724 | |||
725 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | ||
726 | /* read data comes through single port, auto-incr addr */ | ||
727 | /* NOTE: Use the debugless read so we don't flood kernel log | ||
728 | * if IWL_DL_IO is set */ | ||
729 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, | ||
730 | i + RTC_INST_LOWER_BOUND); | ||
731 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
732 | if (val != le32_to_cpu(*image)) { | ||
733 | ret = -EIO; | ||
734 | errcnt++; | ||
735 | if (errcnt >= 3) | ||
736 | break; | ||
737 | } | ||
738 | } | ||
739 | |||
740 | iwl_release_nic_access(priv); | ||
741 | |||
742 | return ret; | ||
743 | } | ||
744 | |||
745 | /** | ||
746 | * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host, | ||
747 | * looking at all data. | ||
748 | */ | ||
749 | static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image, | ||
750 | u32 len) | ||
751 | { | ||
752 | u32 val; | ||
753 | u32 save_len = len; | ||
754 | int ret = 0; | ||
755 | u32 errcnt; | ||
756 | |||
757 | IWL_DEBUG_INFO("ucode inst image size is %u\n", len); | ||
758 | |||
759 | ret = iwl_grab_nic_access(priv); | ||
760 | if (ret) | ||
761 | return ret; | ||
762 | |||
763 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND); | ||
764 | |||
765 | errcnt = 0; | ||
766 | for (; len > 0; len -= sizeof(u32), image++) { | ||
767 | /* read data comes through single port, auto-incr addr */ | ||
768 | /* NOTE: Use the debugless read so we don't flood kernel log | ||
769 | * if IWL_DL_IO is set */ | ||
770 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
771 | if (val != le32_to_cpu(*image)) { | ||
772 | IWL_ERROR("uCode INST section is invalid at " | ||
773 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | ||
774 | save_len - len, val, le32_to_cpu(*image)); | ||
775 | ret = -EIO; | ||
776 | errcnt++; | ||
777 | if (errcnt >= 20) | ||
778 | break; | ||
779 | } | ||
780 | } | ||
781 | |||
782 | iwl_release_nic_access(priv); | ||
783 | |||
784 | if (!errcnt) | ||
785 | IWL_DEBUG_INFO | ||
786 | ("ucode image in INSTRUCTION memory is good\n"); | ||
787 | |||
788 | return ret; | ||
789 | } | ||
790 | |||
791 | /** | ||
792 | * iwl_verify_ucode - determine which instruction image is in SRAM, | ||
793 | * and verify its contents | ||
794 | */ | ||
795 | int iwl_verify_ucode(struct iwl_priv *priv) | ||
796 | { | ||
797 | __le32 *image; | ||
798 | u32 len; | ||
799 | int ret; | ||
800 | |||
801 | /* Try bootstrap */ | ||
802 | image = (__le32 *)priv->ucode_boot.v_addr; | ||
803 | len = priv->ucode_boot.len; | ||
804 | ret = iwlcore_verify_inst_sparse(priv, image, len); | ||
805 | if (!ret) { | ||
806 | IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n"); | ||
807 | return 0; | ||
808 | } | ||
809 | |||
810 | /* Try initialize */ | ||
811 | image = (__le32 *)priv->ucode_init.v_addr; | ||
812 | len = priv->ucode_init.len; | ||
813 | ret = iwlcore_verify_inst_sparse(priv, image, len); | ||
814 | if (!ret) { | ||
815 | IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n"); | ||
816 | return 0; | ||
817 | } | ||
818 | |||
819 | /* Try runtime/protocol */ | ||
820 | image = (__le32 *)priv->ucode_code.v_addr; | ||
821 | len = priv->ucode_code.len; | ||
822 | ret = iwlcore_verify_inst_sparse(priv, image, len); | ||
823 | if (!ret) { | ||
824 | IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n"); | ||
825 | return 0; | ||
826 | } | ||
827 | |||
828 | IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); | ||
829 | |||
830 | /* Since nothing seems to match, show first several data entries in | ||
831 | * instruction SRAM, so maybe visual inspection will give a clue. | ||
832 | * Selection of bootstrap image (vs. other images) is arbitrary. */ | ||
833 | image = (__le32 *)priv->ucode_boot.v_addr; | ||
834 | len = priv->ucode_boot.len; | ||
835 | ret = iwl_verify_inst_full(priv, image, len); | ||
836 | |||
837 | return ret; | ||
838 | } | ||
839 | EXPORT_SYMBOL(iwl_verify_ucode); | ||
840 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e18940dbd13c..8196ef7303af 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -253,6 +253,7 @@ enum iwlcore_card_notify { | |||
253 | int iwlcore_low_level_notify(struct iwl_priv *priv, | 253 | int iwlcore_low_level_notify(struct iwl_priv *priv, |
254 | enum iwlcore_card_notify notify); | 254 | enum iwlcore_card_notify notify); |
255 | extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); | 255 | extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); |
256 | extern int iwl_verify_ucode(struct iwl_priv *priv); | ||
256 | int iwl_send_lq_cmd(struct iwl_priv *priv, | 257 | int iwl_send_lq_cmd(struct iwl_priv *priv, |
257 | struct iwl_link_quality_cmd *lq, u8 flags); | 258 | struct iwl_link_quality_cmd *lq, u8 flags); |
258 | 259 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index e24527313ab6..011f6114c338 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -4512,146 +4512,6 @@ static void iwl4965_dealloc_ucode_pci(struct iwl_priv *priv) | |||
4512 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot); | 4512 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot); |
4513 | } | 4513 | } |
4514 | 4514 | ||
4515 | /** | ||
4516 | * iwl4965_verify_inst_full - verify runtime uCode image in card vs. host, | ||
4517 | * looking at all data. | ||
4518 | */ | ||
4519 | static int iwl4965_verify_inst_full(struct iwl_priv *priv, __le32 *image, | ||
4520 | u32 len) | ||
4521 | { | ||
4522 | u32 val; | ||
4523 | u32 save_len = len; | ||
4524 | int rc = 0; | ||
4525 | u32 errcnt; | ||
4526 | |||
4527 | IWL_DEBUG_INFO("ucode inst image size is %u\n", len); | ||
4528 | |||
4529 | rc = iwl_grab_nic_access(priv); | ||
4530 | if (rc) | ||
4531 | return rc; | ||
4532 | |||
4533 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND); | ||
4534 | |||
4535 | errcnt = 0; | ||
4536 | for (; len > 0; len -= sizeof(u32), image++) { | ||
4537 | /* read data comes through single port, auto-incr addr */ | ||
4538 | /* NOTE: Use the debugless read so we don't flood kernel log | ||
4539 | * if IWL_DL_IO is set */ | ||
4540 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
4541 | if (val != le32_to_cpu(*image)) { | ||
4542 | IWL_ERROR("uCode INST section is invalid at " | ||
4543 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | ||
4544 | save_len - len, val, le32_to_cpu(*image)); | ||
4545 | rc = -EIO; | ||
4546 | errcnt++; | ||
4547 | if (errcnt >= 20) | ||
4548 | break; | ||
4549 | } | ||
4550 | } | ||
4551 | |||
4552 | iwl_release_nic_access(priv); | ||
4553 | |||
4554 | if (!errcnt) | ||
4555 | IWL_DEBUG_INFO | ||
4556 | ("ucode image in INSTRUCTION memory is good\n"); | ||
4557 | |||
4558 | return rc; | ||
4559 | } | ||
4560 | |||
4561 | |||
4562 | /** | ||
4563 | * iwl4965_verify_inst_sparse - verify runtime uCode image in card vs. host, | ||
4564 | * using sample data 100 bytes apart. If these sample points are good, | ||
4565 | * it's a pretty good bet that everything between them is good, too. | ||
4566 | */ | ||
4567 | static int iwl4965_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) | ||
4568 | { | ||
4569 | u32 val; | ||
4570 | int rc = 0; | ||
4571 | u32 errcnt = 0; | ||
4572 | u32 i; | ||
4573 | |||
4574 | IWL_DEBUG_INFO("ucode inst image size is %u\n", len); | ||
4575 | |||
4576 | rc = iwl_grab_nic_access(priv); | ||
4577 | if (rc) | ||
4578 | return rc; | ||
4579 | |||
4580 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | ||
4581 | /* read data comes through single port, auto-incr addr */ | ||
4582 | /* NOTE: Use the debugless read so we don't flood kernel log | ||
4583 | * if IWL_DL_IO is set */ | ||
4584 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, | ||
4585 | i + RTC_INST_LOWER_BOUND); | ||
4586 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
4587 | if (val != le32_to_cpu(*image)) { | ||
4588 | #if 0 /* Enable this if you want to see details */ | ||
4589 | IWL_ERROR("uCode INST section is invalid at " | ||
4590 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | ||
4591 | i, val, *image); | ||
4592 | #endif | ||
4593 | rc = -EIO; | ||
4594 | errcnt++; | ||
4595 | if (errcnt >= 3) | ||
4596 | break; | ||
4597 | } | ||
4598 | } | ||
4599 | |||
4600 | iwl_release_nic_access(priv); | ||
4601 | |||
4602 | return rc; | ||
4603 | } | ||
4604 | |||
4605 | |||
4606 | /** | ||
4607 | * iwl4965_verify_ucode - determine which instruction image is in SRAM, | ||
4608 | * and verify its contents | ||
4609 | */ | ||
4610 | static int iwl4965_verify_ucode(struct iwl_priv *priv) | ||
4611 | { | ||
4612 | __le32 *image; | ||
4613 | u32 len; | ||
4614 | int rc = 0; | ||
4615 | |||
4616 | /* Try bootstrap */ | ||
4617 | image = (__le32 *)priv->ucode_boot.v_addr; | ||
4618 | len = priv->ucode_boot.len; | ||
4619 | rc = iwl4965_verify_inst_sparse(priv, image, len); | ||
4620 | if (rc == 0) { | ||
4621 | IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n"); | ||
4622 | return 0; | ||
4623 | } | ||
4624 | |||
4625 | /* Try initialize */ | ||
4626 | image = (__le32 *)priv->ucode_init.v_addr; | ||
4627 | len = priv->ucode_init.len; | ||
4628 | rc = iwl4965_verify_inst_sparse(priv, image, len); | ||
4629 | if (rc == 0) { | ||
4630 | IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n"); | ||
4631 | return 0; | ||
4632 | } | ||
4633 | |||
4634 | /* Try runtime/protocol */ | ||
4635 | image = (__le32 *)priv->ucode_code.v_addr; | ||
4636 | len = priv->ucode_code.len; | ||
4637 | rc = iwl4965_verify_inst_sparse(priv, image, len); | ||
4638 | if (rc == 0) { | ||
4639 | IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n"); | ||
4640 | return 0; | ||
4641 | } | ||
4642 | |||
4643 | IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); | ||
4644 | |||
4645 | /* Since nothing seems to match, show first several data entries in | ||
4646 | * instruction SRAM, so maybe visual inspection will give a clue. | ||
4647 | * Selection of bootstrap image (vs. other images) is arbitrary. */ | ||
4648 | image = (__le32 *)priv->ucode_boot.v_addr; | ||
4649 | len = priv->ucode_boot.len; | ||
4650 | rc = iwl4965_verify_inst_full(priv, image, len); | ||
4651 | |||
4652 | return rc; | ||
4653 | } | ||
4654 | |||
4655 | static void iwl4965_nic_start(struct iwl_priv *priv) | 4515 | static void iwl4965_nic_start(struct iwl_priv *priv) |
4656 | { | 4516 | { |
4657 | /* Remove all resets to allow NIC to operate */ | 4517 | /* Remove all resets to allow NIC to operate */ |
@@ -4927,7 +4787,7 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv) | |||
4927 | /* Bootstrap uCode has loaded initialize uCode ... verify inst image. | 4787 | /* Bootstrap uCode has loaded initialize uCode ... verify inst image. |
4928 | * This is a paranoid check, because we would not have gotten the | 4788 | * This is a paranoid check, because we would not have gotten the |
4929 | * "initialize" alive if code weren't properly loaded. */ | 4789 | * "initialize" alive if code weren't properly loaded. */ |
4930 | if (iwl4965_verify_ucode(priv)) { | 4790 | if (iwl_verify_ucode(priv)) { |
4931 | /* Runtime instruction load was bad; | 4791 | /* Runtime instruction load was bad; |
4932 | * take it all the way back down so we can try again */ | 4792 | * take it all the way back down so we can try again */ |
4933 | IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n"); | 4793 | IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n"); |
@@ -4975,7 +4835,7 @@ static void iwl4965_alive_start(struct iwl_priv *priv) | |||
4975 | /* Initialize uCode has loaded Runtime uCode ... verify inst image. | 4835 | /* Initialize uCode has loaded Runtime uCode ... verify inst image. |
4976 | * This is a paranoid check, because we would not have gotten the | 4836 | * This is a paranoid check, because we would not have gotten the |
4977 | * "runtime" alive if code weren't properly loaded. */ | 4837 | * "runtime" alive if code weren't properly loaded. */ |
4978 | if (iwl4965_verify_ucode(priv)) { | 4838 | if (iwl_verify_ucode(priv)) { |
4979 | /* Runtime instruction load was bad; | 4839 | /* Runtime instruction load was bad; |
4980 | * take it all the way back down so we can try again */ | 4840 | * take it all the way back down so we can try again */ |
4981 | IWL_DEBUG_INFO("Bad runtime uCode load.\n"); | 4841 | IWL_DEBUG_INFO("Bad runtime uCode load.\n"); |