diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/pcie/trans.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 188 |
1 files changed, 109 insertions, 79 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index d60a467a983c..5a854c609477 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c | |||
@@ -1021,82 +1021,6 @@ static int iwl_pcie_load_given_ucode_8000(struct iwl_trans *trans, | |||
1021 | &first_ucode_section); | 1021 | &first_ucode_section); |
1022 | } | 1022 | } |
1023 | 1023 | ||
1024 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | ||
1025 | const struct fw_img *fw, bool run_in_rfkill) | ||
1026 | { | ||
1027 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1028 | bool hw_rfkill; | ||
1029 | int ret; | ||
1030 | |||
1031 | mutex_lock(&trans_pcie->mutex); | ||
1032 | |||
1033 | /* Someone called stop_device, don't try to start_fw */ | ||
1034 | if (trans_pcie->is_down) { | ||
1035 | IWL_WARN(trans, | ||
1036 | "Can't start_fw since the HW hasn't been started\n"); | ||
1037 | ret = EIO; | ||
1038 | goto out; | ||
1039 | } | ||
1040 | |||
1041 | /* This may fail if AMT took ownership of the device */ | ||
1042 | if (iwl_pcie_prepare_card_hw(trans)) { | ||
1043 | IWL_WARN(trans, "Exit HW not ready\n"); | ||
1044 | ret = -EIO; | ||
1045 | goto out; | ||
1046 | } | ||
1047 | |||
1048 | iwl_enable_rfkill_int(trans); | ||
1049 | |||
1050 | /* If platform's RF_KILL switch is NOT set to KILL */ | ||
1051 | hw_rfkill = iwl_is_rfkill_set(trans); | ||
1052 | if (hw_rfkill) | ||
1053 | set_bit(STATUS_RFKILL, &trans->status); | ||
1054 | else | ||
1055 | clear_bit(STATUS_RFKILL, &trans->status); | ||
1056 | iwl_trans_pcie_rf_kill(trans, hw_rfkill); | ||
1057 | if (hw_rfkill && !run_in_rfkill) { | ||
1058 | ret = -ERFKILL; | ||
1059 | goto out; | ||
1060 | } | ||
1061 | |||
1062 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); | ||
1063 | |||
1064 | ret = iwl_pcie_nic_init(trans); | ||
1065 | if (ret) { | ||
1066 | IWL_ERR(trans, "Unable to init nic\n"); | ||
1067 | goto out; | ||
1068 | } | ||
1069 | |||
1070 | /* make sure rfkill handshake bits are cleared */ | ||
1071 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
1072 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, | ||
1073 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | ||
1074 | |||
1075 | /* clear (again), then enable host interrupts */ | ||
1076 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); | ||
1077 | iwl_enable_interrupts(trans); | ||
1078 | |||
1079 | /* really make sure rfkill handshake bits are cleared */ | ||
1080 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
1081 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
1082 | |||
1083 | /* Load the given image to the HW */ | ||
1084 | if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) | ||
1085 | ret = iwl_pcie_load_given_ucode_8000(trans, fw); | ||
1086 | else | ||
1087 | ret = iwl_pcie_load_given_ucode(trans, fw); | ||
1088 | |||
1089 | out: | ||
1090 | mutex_unlock(&trans_pcie->mutex); | ||
1091 | return ret; | ||
1092 | } | ||
1093 | |||
1094 | static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr) | ||
1095 | { | ||
1096 | iwl_pcie_reset_ict(trans); | ||
1097 | iwl_pcie_tx_start(trans, scd_addr); | ||
1098 | } | ||
1099 | |||
1100 | static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) | 1024 | static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) |
1101 | { | 1025 | { |
1102 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1026 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -1127,7 +1051,8 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) | |||
1127 | * already dead. | 1051 | * already dead. |
1128 | */ | 1052 | */ |
1129 | if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) { | 1053 | if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) { |
1130 | IWL_DEBUG_INFO(trans, "DEVICE_ENABLED bit was set and is now cleared\n"); | 1054 | IWL_DEBUG_INFO(trans, |
1055 | "DEVICE_ENABLED bit was set and is now cleared\n"); | ||
1131 | iwl_pcie_tx_stop(trans); | 1056 | iwl_pcie_tx_stop(trans); |
1132 | iwl_pcie_rx_stop(trans); | 1057 | iwl_pcie_rx_stop(trans); |
1133 | 1058 | ||
@@ -1161,7 +1086,6 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) | |||
1161 | iwl_disable_interrupts(trans); | 1086 | iwl_disable_interrupts(trans); |
1162 | spin_unlock(&trans_pcie->irq_lock); | 1087 | spin_unlock(&trans_pcie->irq_lock); |
1163 | 1088 | ||
1164 | |||
1165 | /* clear all status bits */ | 1089 | /* clear all status bits */ |
1166 | clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); | 1090 | clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); |
1167 | clear_bit(STATUS_INT_ENABLED, &trans->status); | 1091 | clear_bit(STATUS_INT_ENABLED, &trans->status); |
@@ -1194,10 +1118,116 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) | |||
1194 | if (hw_rfkill != was_hw_rfkill) | 1118 | if (hw_rfkill != was_hw_rfkill) |
1195 | iwl_trans_pcie_rf_kill(trans, hw_rfkill); | 1119 | iwl_trans_pcie_rf_kill(trans, hw_rfkill); |
1196 | 1120 | ||
1197 | /* re-take ownership to prevent other users from stealing the deivce */ | 1121 | /* re-take ownership to prevent other users from stealing the device */ |
1198 | iwl_pcie_prepare_card_hw(trans); | 1122 | iwl_pcie_prepare_card_hw(trans); |
1199 | } | 1123 | } |
1200 | 1124 | ||
1125 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | ||
1126 | const struct fw_img *fw, bool run_in_rfkill) | ||
1127 | { | ||
1128 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1129 | bool hw_rfkill; | ||
1130 | int ret; | ||
1131 | |||
1132 | /* This may fail if AMT took ownership of the device */ | ||
1133 | if (iwl_pcie_prepare_card_hw(trans)) { | ||
1134 | IWL_WARN(trans, "Exit HW not ready\n"); | ||
1135 | ret = -EIO; | ||
1136 | goto out; | ||
1137 | } | ||
1138 | |||
1139 | iwl_enable_rfkill_int(trans); | ||
1140 | |||
1141 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); | ||
1142 | |||
1143 | /* | ||
1144 | * We enabled the RF-Kill interrupt and the handler may very | ||
1145 | * well be running. Disable the interrupts to make sure no other | ||
1146 | * interrupt can be fired. | ||
1147 | */ | ||
1148 | iwl_disable_interrupts(trans); | ||
1149 | |||
1150 | /* Make sure it finished running */ | ||
1151 | synchronize_irq(trans_pcie->pci_dev->irq); | ||
1152 | |||
1153 | mutex_lock(&trans_pcie->mutex); | ||
1154 | |||
1155 | /* If platform's RF_KILL switch is NOT set to KILL */ | ||
1156 | hw_rfkill = iwl_is_rfkill_set(trans); | ||
1157 | if (hw_rfkill) | ||
1158 | set_bit(STATUS_RFKILL, &trans->status); | ||
1159 | else | ||
1160 | clear_bit(STATUS_RFKILL, &trans->status); | ||
1161 | iwl_trans_pcie_rf_kill(trans, hw_rfkill); | ||
1162 | if (hw_rfkill && !run_in_rfkill) { | ||
1163 | ret = -ERFKILL; | ||
1164 | goto out; | ||
1165 | } | ||
1166 | |||
1167 | /* Someone called stop_device, don't try to start_fw */ | ||
1168 | if (trans_pcie->is_down) { | ||
1169 | IWL_WARN(trans, | ||
1170 | "Can't start_fw since the HW hasn't been started\n"); | ||
1171 | ret = -EIO; | ||
1172 | goto out; | ||
1173 | } | ||
1174 | |||
1175 | /* make sure rfkill handshake bits are cleared */ | ||
1176 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
1177 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, | ||
1178 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | ||
1179 | |||
1180 | /* clear (again), then enable host interrupts */ | ||
1181 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); | ||
1182 | |||
1183 | ret = iwl_pcie_nic_init(trans); | ||
1184 | if (ret) { | ||
1185 | IWL_ERR(trans, "Unable to init nic\n"); | ||
1186 | goto out; | ||
1187 | } | ||
1188 | |||
1189 | /* | ||
1190 | * Now, we load the firmware and don't want to be interrupted, even | ||
1191 | * by the RF-Kill interrupt (hence mask all the interrupt besides the | ||
1192 | * FH_TX interrupt which is needed to load the firmware). If the | ||
1193 | * RF-Kill switch is toggled, we will find out after having loaded | ||
1194 | * the firmware and return the proper value to the caller. | ||
1195 | */ | ||
1196 | iwl_enable_fw_load_int(trans); | ||
1197 | |||
1198 | /* really make sure rfkill handshake bits are cleared */ | ||
1199 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
1200 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
1201 | |||
1202 | /* Load the given image to the HW */ | ||
1203 | if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) | ||
1204 | ret = iwl_pcie_load_given_ucode_8000(trans, fw); | ||
1205 | else | ||
1206 | ret = iwl_pcie_load_given_ucode(trans, fw); | ||
1207 | iwl_enable_interrupts(trans); | ||
1208 | |||
1209 | /* re-check RF-Kill state since we may have missed the interrupt */ | ||
1210 | hw_rfkill = iwl_is_rfkill_set(trans); | ||
1211 | if (hw_rfkill) | ||
1212 | set_bit(STATUS_RFKILL, &trans->status); | ||
1213 | else | ||
1214 | clear_bit(STATUS_RFKILL, &trans->status); | ||
1215 | |||
1216 | iwl_trans_pcie_rf_kill(trans, hw_rfkill); | ||
1217 | if (hw_rfkill && !run_in_rfkill) | ||
1218 | ret = -ERFKILL; | ||
1219 | |||
1220 | out: | ||
1221 | mutex_unlock(&trans_pcie->mutex); | ||
1222 | return ret; | ||
1223 | } | ||
1224 | |||
1225 | static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr) | ||
1226 | { | ||
1227 | iwl_pcie_reset_ict(trans); | ||
1228 | iwl_pcie_tx_start(trans, scd_addr); | ||
1229 | } | ||
1230 | |||
1201 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) | 1231 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) |
1202 | { | 1232 | { |
1203 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1233 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |