aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-ucode.c
diff options
context:
space:
mode:
authorDon Fry <donald.h.fry@intel.com>2012-01-25 19:18:52 -0500
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2012-02-02 17:38:22 -0500
commitedf38334061cb87c68cfc7fdc192c850b7e02320 (patch)
tree679b5d7f6da3c52644a3d418d9a2e1e51def8931 /drivers/net/wireless/iwlwifi/iwl-ucode.c
parent87272af74e98225672c9165a20b0604a7db758cf (diff)
iwlwifi: move all ucode routines to iwl-ucode.c
The routines dealing with the ucode are spread through several files. Move them all to the same file and create a iwl-ucode.h file with the ucode file definitions. Signed-off-by: Don Fry <donald.h.fry@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-ucode.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-ucode.c610
1 files changed, 609 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c
index 87ce587d7d57..11b659ab261d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c
@@ -32,7 +32,9 @@
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/dma-mapping.h> 34#include <linux/dma-mapping.h>
35#include <linux/firmware.h>
35 36
37#include "iwl-ucode.h"
36#include "iwl-wifi.h" 38#include "iwl-wifi.h"
37#include "iwl-dev.h" 39#include "iwl-dev.h"
38#include "iwl-core.h" 40#include "iwl-core.h"
@@ -102,7 +104,7 @@ void iwl_dealloc_ucode(struct iwl_trans *trans)
102 iwl_free_fw_img(trans, &trans->ucode_wowlan); 104 iwl_free_fw_img(trans, &trans->ucode_wowlan);
103} 105}
104 106
105int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, 107static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc,
106 const void *data, size_t len) 108 const void *data, size_t len)
107{ 109{
108 if (!len) { 110 if (!len) {
@@ -680,3 +682,609 @@ int iwl_run_init_ucode(struct iwl_trans *trans)
680 iwl_trans_stop_device(trans); 682 iwl_trans_stop_device(trans);
681 return ret; 683 return ret;
682} 684}
685
686static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
687
688#define UCODE_EXPERIMENTAL_INDEX 100
689#define UCODE_EXPERIMENTAL_TAG "exp"
690
691int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
692{
693 const char *name_pre = cfg(priv)->fw_name_pre;
694 char tag[8];
695
696 if (first) {
697#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
698 priv->fw_index = UCODE_EXPERIMENTAL_INDEX;
699 strcpy(tag, UCODE_EXPERIMENTAL_TAG);
700 } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) {
701#endif
702 priv->fw_index = cfg(priv)->ucode_api_max;
703 sprintf(tag, "%d", priv->fw_index);
704 } else {
705 priv->fw_index--;
706 sprintf(tag, "%d", priv->fw_index);
707 }
708
709 if (priv->fw_index < cfg(priv)->ucode_api_min) {
710 IWL_ERR(priv, "no suitable firmware found!\n");
711 return -ENOENT;
712 }
713
714 sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
715
716 IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n",
717 (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
718 ? "EXPERIMENTAL " : "",
719 priv->firmware_name);
720
721 return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
722 trans(priv)->dev,
723 GFP_KERNEL, priv, iwl_ucode_callback);
724}
725
726struct iwlagn_firmware_pieces {
727 const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data;
728 size_t inst_size, data_size, init_size, init_data_size,
729 wowlan_inst_size, wowlan_data_size;
730
731 u32 build;
732
733 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
734 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
735};
736
737static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
738 const struct firmware *ucode_raw,
739 struct iwlagn_firmware_pieces *pieces)
740{
741 struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
742 u32 api_ver, hdr_size;
743 const u8 *src;
744
745 priv->ucode_ver = le32_to_cpu(ucode->ver);
746 api_ver = IWL_UCODE_API(priv->ucode_ver);
747
748 switch (api_ver) {
749 default:
750 hdr_size = 28;
751 if (ucode_raw->size < hdr_size) {
752 IWL_ERR(priv, "File size too small!\n");
753 return -EINVAL;
754 }
755 pieces->build = le32_to_cpu(ucode->u.v2.build);
756 pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
757 pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
758 pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
759 pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
760 src = ucode->u.v2.data;
761 break;
762 case 0:
763 case 1:
764 case 2:
765 hdr_size = 24;
766 if (ucode_raw->size < hdr_size) {
767 IWL_ERR(priv, "File size too small!\n");
768 return -EINVAL;
769 }
770 pieces->build = 0;
771 pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size);
772 pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
773 pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
774 pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
775 src = ucode->u.v1.data;
776 break;
777 }
778
779 /* Verify size of file vs. image size info in file's header */
780 if (ucode_raw->size != hdr_size + pieces->inst_size +
781 pieces->data_size + pieces->init_size +
782 pieces->init_data_size) {
783
784 IWL_ERR(priv,
785 "uCode file size %d does not match expected size\n",
786 (int)ucode_raw->size);
787 return -EINVAL;
788 }
789
790 pieces->inst = src;
791 src += pieces->inst_size;
792 pieces->data = src;
793 src += pieces->data_size;
794 pieces->init = src;
795 src += pieces->init_size;
796 pieces->init_data = src;
797 src += pieces->init_data_size;
798
799 return 0;
800}
801
802static int iwlagn_load_firmware(struct iwl_priv *priv,
803 const struct firmware *ucode_raw,
804 struct iwlagn_firmware_pieces *pieces,
805 struct iwlagn_ucode_capabilities *capa)
806{
807 struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
808 struct iwl_ucode_tlv *tlv;
809 size_t len = ucode_raw->size;
810 const u8 *data;
811 int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative;
812 int tmp;
813 u64 alternatives;
814 u32 tlv_len;
815 enum iwl_ucode_tlv_type tlv_type;
816 const u8 *tlv_data;
817
818 if (len < sizeof(*ucode)) {
819 IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
820 return -EINVAL;
821 }
822
823 if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
824 IWL_ERR(priv, "invalid uCode magic: 0X%x\n",
825 le32_to_cpu(ucode->magic));
826 return -EINVAL;
827 }
828
829 /*
830 * Check which alternatives are present, and "downgrade"
831 * when the chosen alternative is not present, warning
832 * the user when that happens. Some files may not have
833 * any alternatives, so don't warn in that case.
834 */
835 alternatives = le64_to_cpu(ucode->alternatives);
836 tmp = wanted_alternative;
837 if (wanted_alternative > 63)
838 wanted_alternative = 63;
839 while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
840 wanted_alternative--;
841 if (wanted_alternative && wanted_alternative != tmp)
842 IWL_WARN(priv,
843 "uCode alternative %d not available, choosing %d\n",
844 tmp, wanted_alternative);
845
846 priv->ucode_ver = le32_to_cpu(ucode->ver);
847 pieces->build = le32_to_cpu(ucode->build);
848 data = ucode->data;
849
850 len -= sizeof(*ucode);
851
852 while (len >= sizeof(*tlv)) {
853 u16 tlv_alt;
854
855 len -= sizeof(*tlv);
856 tlv = (void *)data;
857
858 tlv_len = le32_to_cpu(tlv->length);
859 tlv_type = le16_to_cpu(tlv->type);
860 tlv_alt = le16_to_cpu(tlv->alternative);
861 tlv_data = tlv->data;
862
863 if (len < tlv_len) {
864 IWL_ERR(priv, "invalid TLV len: %zd/%u\n",
865 len, tlv_len);
866 return -EINVAL;
867 }
868 len -= ALIGN(tlv_len, 4);
869 data += sizeof(*tlv) + ALIGN(tlv_len, 4);
870
871 /*
872 * Alternative 0 is always valid.
873 *
874 * Skip alternative TLVs that are not selected.
875 */
876 if (tlv_alt != 0 && tlv_alt != wanted_alternative)
877 continue;
878
879 switch (tlv_type) {
880 case IWL_UCODE_TLV_INST:
881 pieces->inst = tlv_data;
882 pieces->inst_size = tlv_len;
883 break;
884 case IWL_UCODE_TLV_DATA:
885 pieces->data = tlv_data;
886 pieces->data_size = tlv_len;
887 break;
888 case IWL_UCODE_TLV_INIT:
889 pieces->init = tlv_data;
890 pieces->init_size = tlv_len;
891 break;
892 case IWL_UCODE_TLV_INIT_DATA:
893 pieces->init_data = tlv_data;
894 pieces->init_data_size = tlv_len;
895 break;
896 case IWL_UCODE_TLV_BOOT:
897 IWL_ERR(priv, "Found unexpected BOOT ucode\n");
898 break;
899 case IWL_UCODE_TLV_PROBE_MAX_LEN:
900 if (tlv_len != sizeof(u32))
901 goto invalid_tlv_len;
902 capa->max_probe_length =
903 le32_to_cpup((__le32 *)tlv_data);
904 break;
905 case IWL_UCODE_TLV_PAN:
906 if (tlv_len)
907 goto invalid_tlv_len;
908 capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
909 break;
910 case IWL_UCODE_TLV_FLAGS:
911 /* must be at least one u32 */
912 if (tlv_len < sizeof(u32))
913 goto invalid_tlv_len;
914 /* and a proper number of u32s */
915 if (tlv_len % sizeof(u32))
916 goto invalid_tlv_len;
917 /*
918 * This driver only reads the first u32 as
919 * right now no more features are defined,
920 * if that changes then either the driver
921 * will not work with the new firmware, or
922 * it'll not take advantage of new features.
923 */
924 capa->flags = le32_to_cpup((__le32 *)tlv_data);
925 break;
926 case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
927 if (tlv_len != sizeof(u32))
928 goto invalid_tlv_len;
929 pieces->init_evtlog_ptr =
930 le32_to_cpup((__le32 *)tlv_data);
931 break;
932 case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
933 if (tlv_len != sizeof(u32))
934 goto invalid_tlv_len;
935 pieces->init_evtlog_size =
936 le32_to_cpup((__le32 *)tlv_data);
937 break;
938 case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
939 if (tlv_len != sizeof(u32))
940 goto invalid_tlv_len;
941 pieces->init_errlog_ptr =
942 le32_to_cpup((__le32 *)tlv_data);
943 break;
944 case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
945 if (tlv_len != sizeof(u32))
946 goto invalid_tlv_len;
947 pieces->inst_evtlog_ptr =
948 le32_to_cpup((__le32 *)tlv_data);
949 break;
950 case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
951 if (tlv_len != sizeof(u32))
952 goto invalid_tlv_len;
953 pieces->inst_evtlog_size =
954 le32_to_cpup((__le32 *)tlv_data);
955 break;
956 case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
957 if (tlv_len != sizeof(u32))
958 goto invalid_tlv_len;
959 pieces->inst_errlog_ptr =
960 le32_to_cpup((__le32 *)tlv_data);
961 break;
962 case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
963 if (tlv_len)
964 goto invalid_tlv_len;
965 priv->enhance_sensitivity_table = true;
966 break;
967 case IWL_UCODE_TLV_WOWLAN_INST:
968 pieces->wowlan_inst = tlv_data;
969 pieces->wowlan_inst_size = tlv_len;
970 break;
971 case IWL_UCODE_TLV_WOWLAN_DATA:
972 pieces->wowlan_data = tlv_data;
973 pieces->wowlan_data_size = tlv_len;
974 break;
975 case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
976 if (tlv_len != sizeof(u32))
977 goto invalid_tlv_len;
978 capa->standard_phy_calibration_size =
979 le32_to_cpup((__le32 *)tlv_data);
980 break;
981 default:
982 IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type);
983 break;
984 }
985 }
986
987 if (len) {
988 IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
989 iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
990 return -EINVAL;
991 }
992
993 return 0;
994
995 invalid_tlv_len:
996 IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
997 iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len);
998
999 return -EINVAL;
1000}
1001
1002/**
1003 * iwl_ucode_callback - callback when firmware was loaded
1004 *
1005 * If loaded successfully, copies the firmware into buffers
1006 * for the card to fetch (via DMA).
1007 */
1008static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1009{
1010 struct iwl_priv *priv = context;
1011 struct iwl_ucode_header *ucode;
1012 int err;
1013 struct iwlagn_firmware_pieces pieces;
1014 const unsigned int api_max = cfg(priv)->ucode_api_max;
1015 unsigned int api_ok = cfg(priv)->ucode_api_ok;
1016 const unsigned int api_min = cfg(priv)->ucode_api_min;
1017 u32 api_ver;
1018 char buildstr[25];
1019 u32 build;
1020 struct iwlagn_ucode_capabilities ucode_capa = {
1021 .max_probe_length = 200,
1022 .standard_phy_calibration_size =
1023 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE,
1024 };
1025
1026 if (!api_ok)
1027 api_ok = api_max;
1028
1029 memset(&pieces, 0, sizeof(pieces));
1030
1031 if (!ucode_raw) {
1032 if (priv->fw_index <= api_ok)
1033 IWL_ERR(priv,
1034 "request for firmware file '%s' failed.\n",
1035 priv->firmware_name);
1036 goto try_again;
1037 }
1038
1039 IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
1040 priv->firmware_name, ucode_raw->size);
1041
1042 /* Make sure that we got at least the API version number */
1043 if (ucode_raw->size < 4) {
1044 IWL_ERR(priv, "File size way too small!\n");
1045 goto try_again;
1046 }
1047
1048 /* Data from ucode file: header followed by uCode images */
1049 ucode = (struct iwl_ucode_header *)ucode_raw->data;
1050
1051 if (ucode->ver)
1052 err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces);
1053 else
1054 err = iwlagn_load_firmware(priv, ucode_raw, &pieces,
1055 &ucode_capa);
1056
1057 if (err)
1058 goto try_again;
1059
1060 api_ver = IWL_UCODE_API(priv->ucode_ver);
1061 build = pieces.build;
1062
1063 /*
1064 * api_ver should match the api version forming part of the
1065 * firmware filename ... but we don't check for that and only rely
1066 * on the API version read from firmware header from here on forward
1067 */
1068 /* no api version check required for experimental uCode */
1069 if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) {
1070 if (api_ver < api_min || api_ver > api_max) {
1071 IWL_ERR(priv,
1072 "Driver unable to support your firmware API. "
1073 "Driver supports v%u, firmware is v%u.\n",
1074 api_max, api_ver);
1075 goto try_again;
1076 }
1077
1078 if (api_ver < api_ok) {
1079 if (api_ok != api_max)
1080 IWL_ERR(priv, "Firmware has old API version, "
1081 "expected v%u through v%u, got v%u.\n",
1082 api_ok, api_max, api_ver);
1083 else
1084 IWL_ERR(priv, "Firmware has old API version, "
1085 "expected v%u, got v%u.\n",
1086 api_max, api_ver);
1087 IWL_ERR(priv, "New firmware can be obtained from "
1088 "http://www.intellinuxwireless.org/.\n");
1089 }
1090 }
1091
1092 if (build)
1093 sprintf(buildstr, " build %u%s", build,
1094 (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
1095 ? " (EXP)" : "");
1096 else
1097 buildstr[0] = '\0';
1098
1099 IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n",
1100 IWL_UCODE_MAJOR(priv->ucode_ver),
1101 IWL_UCODE_MINOR(priv->ucode_ver),
1102 IWL_UCODE_API(priv->ucode_ver),
1103 IWL_UCODE_SERIAL(priv->ucode_ver),
1104 buildstr);
1105
1106 snprintf(priv->hw->wiphy->fw_version,
1107 sizeof(priv->hw->wiphy->fw_version),
1108 "%u.%u.%u.%u%s",
1109 IWL_UCODE_MAJOR(priv->ucode_ver),
1110 IWL_UCODE_MINOR(priv->ucode_ver),
1111 IWL_UCODE_API(priv->ucode_ver),
1112 IWL_UCODE_SERIAL(priv->ucode_ver),
1113 buildstr);
1114
1115 /*
1116 * For any of the failures below (before allocating pci memory)
1117 * we will try to load a version with a smaller API -- maybe the
1118 * user just got a corrupted version of the latest API.
1119 */
1120
1121 IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
1122 priv->ucode_ver);
1123 IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n",
1124 pieces.inst_size);
1125 IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n",
1126 pieces.data_size);
1127 IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n",
1128 pieces.init_size);
1129 IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
1130 pieces.init_data_size);
1131
1132 /* Verify that uCode images will fit in card's SRAM */
1133 if (pieces.inst_size > hw_params(priv).max_inst_size) {
1134 IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n",
1135 pieces.inst_size);
1136 goto try_again;
1137 }
1138
1139 if (pieces.data_size > hw_params(priv).max_data_size) {
1140 IWL_ERR(priv, "uCode data len %Zd too large to fit in\n",
1141 pieces.data_size);
1142 goto try_again;
1143 }
1144
1145 if (pieces.init_size > hw_params(priv).max_inst_size) {
1146 IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n",
1147 pieces.init_size);
1148 goto try_again;
1149 }
1150
1151 if (pieces.init_data_size > hw_params(priv).max_data_size) {
1152 IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n",
1153 pieces.init_data_size);
1154 goto try_again;
1155 }
1156
1157 /* Allocate ucode buffers for card's bus-master loading ... */
1158
1159 /* Runtime instructions and 2 copies of data:
1160 * 1) unmodified from disk
1161 * 2) backup cache for save/restore during power-downs */
1162 if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.code,
1163 pieces.inst, pieces.inst_size))
1164 goto err_pci_alloc;
1165 if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.data,
1166 pieces.data, pieces.data_size))
1167 goto err_pci_alloc;
1168
1169 /* Initialization instructions and data */
1170 if (pieces.init_size && pieces.init_data_size) {
1171 if (iwl_alloc_fw_desc(trans(priv),
1172 &trans(priv)->ucode_init.code,
1173 pieces.init, pieces.init_size))
1174 goto err_pci_alloc;
1175 if (iwl_alloc_fw_desc(trans(priv),
1176 &trans(priv)->ucode_init.data,
1177 pieces.init_data, pieces.init_data_size))
1178 goto err_pci_alloc;
1179 }
1180
1181 /* WoWLAN instructions and data */
1182 if (pieces.wowlan_inst_size && pieces.wowlan_data_size) {
1183 if (iwl_alloc_fw_desc(trans(priv),
1184 &trans(priv)->ucode_wowlan.code,
1185 pieces.wowlan_inst,
1186 pieces.wowlan_inst_size))
1187 goto err_pci_alloc;
1188 if (iwl_alloc_fw_desc(trans(priv),
1189 &trans(priv)->ucode_wowlan.data,
1190 pieces.wowlan_data,
1191 pieces.wowlan_data_size))
1192 goto err_pci_alloc;
1193 }
1194
1195 /* Now that we can no longer fail, copy information */
1196
1197 /*
1198 * The (size - 16) / 12 formula is based on the information recorded
1199 * for each event, which is of mode 1 (including timestamp) for all
1200 * new microcodes that include this information.
1201 */
1202 priv->init_evtlog_ptr = pieces.init_evtlog_ptr;
1203 if (pieces.init_evtlog_size)
1204 priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
1205 else
1206 priv->init_evtlog_size =
1207 cfg(priv)->base_params->max_event_log_size;
1208 priv->init_errlog_ptr = pieces.init_errlog_ptr;
1209 priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
1210 if (pieces.inst_evtlog_size)
1211 priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
1212 else
1213 priv->inst_evtlog_size =
1214 cfg(priv)->base_params->max_event_log_size;
1215 priv->inst_errlog_ptr = pieces.inst_errlog_ptr;
1216#ifndef CONFIG_IWLWIFI_P2P
1217 ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
1218#endif
1219
1220 priv->new_scan_threshold_behaviour =
1221 !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
1222
1223 if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE))
1224 ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
1225
1226 /*
1227 * if not PAN, then don't support P2P -- might be a uCode
1228 * packaging bug or due to the eeprom check above
1229 */
1230 if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN))
1231 ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
1232
1233 if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
1234 priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
1235 priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
1236 } else {
1237 priv->sta_key_max_num = STA_KEY_MAX_NUM;
1238 priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
1239 }
1240 /*
1241 * figure out the offset of chain noise reset and gain commands
1242 * base on the size of standard phy calibration commands table size
1243 */
1244 if (ucode_capa.standard_phy_calibration_size >
1245 IWL_MAX_PHY_CALIBRATE_TBL_SIZE)
1246 ucode_capa.standard_phy_calibration_size =
1247 IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
1248
1249 priv->phy_calib_chain_noise_reset_cmd =
1250 ucode_capa.standard_phy_calibration_size;
1251 priv->phy_calib_chain_noise_gain_cmd =
1252 ucode_capa.standard_phy_calibration_size + 1;
1253
1254 /* initialize all valid contexts */
1255 iwl_init_context(priv, ucode_capa.flags);
1256
1257 /**************************************************
1258 * This is still part of probe() in a sense...
1259 *
1260 * 9. Setup and register with mac80211 and debugfs
1261 **************************************************/
1262 err = iwlagn_mac_setup_register(priv, &ucode_capa);
1263 if (err)
1264 goto out_unbind;
1265
1266 err = iwl_dbgfs_register(priv, DRV_NAME);
1267 if (err)
1268 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
1269
1270 /* We have our copies now, allow OS release its copies */
1271 release_firmware(ucode_raw);
1272 complete(&priv->firmware_loading_complete);
1273 return;
1274
1275 try_again:
1276 /* try next, if any */
1277 if (iwl_request_firmware(priv, false))
1278 goto out_unbind;
1279 release_firmware(ucode_raw);
1280 return;
1281
1282 err_pci_alloc:
1283 IWL_ERR(priv, "failed to allocate pci memory\n");
1284 iwl_dealloc_ucode(trans(priv));
1285 out_unbind:
1286 complete(&priv->firmware_loading_complete);
1287 device_release_driver(trans(priv)->dev);
1288 release_firmware(ucode_raw);
1289}
1290