1 /****************************************************************************** 2 * 3 * GPL LICENSE SUMMARY 4 * 5 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 6 * Copyright(c) 2015 Intel Deutschland GmbH 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of version 2 of the GNU General Public License as 10 * published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, 20 * USA 21 * 22 * The full GNU General Public License is included in this distribution 23 * in the file called COPYING. 24 * 25 * Contact Information: 26 * Intel Linux Wireless <linuxwifi@intel.com> 27 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 28 * 29 *****************************************************************************/ 30 31 #include <linux/kernel.h> 32 33 #include "iwl-io.h" 34 #include "iwl-agn-hw.h" 35 #include "iwl-trans.h" 36 #include "iwl-fh.h" 37 #include "iwl-op-mode.h" 38 39 #include "dev.h" 40 #include "agn.h" 41 #include "calib.h" 42 43 /****************************************************************************** 44 * 45 * uCode download functions 46 * 47 ******************************************************************************/ 48 49 /* 50 * Calibration 51 */ 52 static int iwl_set_Xtal_calib(struct iwl_priv *priv) 53 { 54 struct iwl_calib_xtal_freq_cmd cmd; 55 __le16 *xtal_calib = priv->nvm_data->xtal_calib; 56 57 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); 58 cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); 59 cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); 60 return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); 61 } 62 63 static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) 64 { 65 struct iwl_calib_temperature_offset_cmd cmd; 66 67 memset(&cmd, 0, sizeof(cmd)); 68 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); 69 cmd.radio_sensor_offset = priv->nvm_data->raw_temperature; 70 if (!(cmd.radio_sensor_offset)) 71 cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; 72 73 IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", 74 le16_to_cpu(cmd.radio_sensor_offset)); 75 return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); 76 } 77 78 static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) 79 { 80 struct iwl_calib_temperature_offset_v2_cmd cmd; 81 82 memset(&cmd, 0, sizeof(cmd)); 83 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); 84 cmd.radio_sensor_offset_high = priv->nvm_data->kelvin_temperature; 85 cmd.radio_sensor_offset_low = priv->nvm_data->raw_temperature; 86 if (!cmd.radio_sensor_offset_low) { 87 IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); 88 cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; 89 cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; 90 } 91 cmd.burntVoltageRef = priv->nvm_data->calib_voltage; 92 93 IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", 94 le16_to_cpu(cmd.radio_sensor_offset_high)); 95 IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n", 96 le16_to_cpu(cmd.radio_sensor_offset_low)); 97 IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n", 98 le16_to_cpu(cmd.burntVoltageRef)); 99 100 return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); 101 } 102 103 static int iwl_send_calib_cfg(struct iwl_priv *priv) 104 { 105 struct iwl_calib_cfg_cmd calib_cfg_cmd; 106 struct iwl_host_cmd cmd = { 107 .id = CALIBRATION_CFG_CMD, 108 .len = { sizeof(struct iwl_calib_cfg_cmd), }, 109 .data = { &calib_cfg_cmd, }, 110 }; 111 112 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); 113 calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL; 114 calib_cfg_cmd.ucd_calib_cfg.once.start = IWL_CALIB_INIT_CFG_ALL; 115 calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL; 116 calib_cfg_cmd.ucd_calib_cfg.flags = 117 IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; 118 119 return iwl_dvm_send_cmd(priv, &cmd); 120 } 121 122 int iwl_init_alive_start(struct iwl_priv *priv) 123 { 124 int ret; 125 126 if (priv->lib->bt_params && 127 priv->lib->bt_params->advanced_bt_coexist) { 128 /* 129 * Tell uCode we are ready to perform calibration 130 * need to perform this before any calibration 131 * no need to close the envlope since we are going 132 * to load the runtime uCode later. 133 */ 134 ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, 135 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); 136 if (ret) 137 return ret; 138 139 } 140 141 ret = iwl_send_calib_cfg(priv); 142 if (ret) 143 return ret; 144 145 /** 146 * temperature offset calibration is only needed for runtime ucode, 147 * so prepare the value now. 148 */ 149 if (priv->lib->need_temp_offset_calib) { 150 if (priv->lib->temp_offset_v2) 151 return iwl_set_temperature_offset_calib_v2(priv); 152 else 153 return iwl_set_temperature_offset_calib(priv); 154 } 155 156 return 0; 157 } 158 159 static int iwl_send_wimax_coex(struct iwl_priv *priv) 160 { 161 struct iwl_wimax_coex_cmd coex_cmd; 162 163 /* coexistence is disabled */ 164 memset(&coex_cmd, 0, sizeof(coex_cmd)); 165 166 return iwl_dvm_send_cmd_pdu(priv, 167 COEX_PRIORITY_TABLE_CMD, 0, 168 sizeof(coex_cmd), &coex_cmd); 169 } 170 171 static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { 172 ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 173 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 174 ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 175 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 176 ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 177 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 178 ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 179 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 180 ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 181 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 182 ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 183 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 184 ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 185 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 186 ((BT_COEX_PRIO_TBL_PRIO_COEX_OFF << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 187 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 188 ((BT_COEX_PRIO_TBL_PRIO_COEX_ON << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 189 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 190 0, 0, 0, 0, 0, 0, 0 191 }; 192 193 void iwl_send_prio_tbl(struct iwl_priv *priv) 194 { 195 struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; 196 197 memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, 198 sizeof(iwl_bt_prio_tbl)); 199 if (iwl_dvm_send_cmd_pdu(priv, 200 REPLY_BT_COEX_PRIO_TABLE, 0, 201 sizeof(prio_tbl_cmd), &prio_tbl_cmd)) 202 IWL_ERR(priv, "failed to send BT prio tbl command\n"); 203 } 204 205 int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) 206 { 207 struct iwl_bt_coex_prot_env_cmd env_cmd; 208 int ret; 209 210 env_cmd.action = action; 211 env_cmd.type = type; 212 ret = iwl_dvm_send_cmd_pdu(priv, 213 REPLY_BT_COEX_PROT_ENV, 0, 214 sizeof(env_cmd), &env_cmd); 215 if (ret) 216 IWL_ERR(priv, "failed to send BT env command\n"); 217 return ret; 218 } 219 220 static const u8 iwlagn_default_queue_to_tx_fifo[] = { 221 IWL_TX_FIFO_VO, 222 IWL_TX_FIFO_VI, 223 IWL_TX_FIFO_BE, 224 IWL_TX_FIFO_BK, 225 }; 226 227 static const u8 iwlagn_ipan_queue_to_tx_fifo[] = { 228 IWL_TX_FIFO_VO, 229 IWL_TX_FIFO_VI, 230 IWL_TX_FIFO_BE, 231 IWL_TX_FIFO_BK, 232 IWL_TX_FIFO_BK_IPAN, 233 IWL_TX_FIFO_BE_IPAN, 234 IWL_TX_FIFO_VI_IPAN, 235 IWL_TX_FIFO_VO_IPAN, 236 IWL_TX_FIFO_BE_IPAN, 237 IWL_TX_FIFO_UNUSED, 238 IWL_TX_FIFO_AUX, 239 }; 240 241 static int iwl_alive_notify(struct iwl_priv *priv) 242 { 243 const u8 *queue_to_txf; 244 u8 n_queues; 245 int ret; 246 int i; 247 248 iwl_trans_fw_alive(priv->trans, 0); 249 250 if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN && 251 priv->nvm_data->sku_cap_ipan_enable) { 252 n_queues = ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo); 253 queue_to_txf = iwlagn_ipan_queue_to_tx_fifo; 254 } else { 255 n_queues = ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); 256 queue_to_txf = iwlagn_default_queue_to_tx_fifo; 257 } 258 259 for (i = 0; i < n_queues; i++) 260 if (queue_to_txf[i] != IWL_TX_FIFO_UNUSED) 261 iwl_trans_ac_txq_enable(priv->trans, i, 262 queue_to_txf[i], 0); 263 264 priv->passive_no_rx = false; 265 priv->transport_queue_stop = 0; 266 267 ret = iwl_send_wimax_coex(priv); 268 if (ret) 269 return ret; 270 271 if (!priv->lib->no_xtal_calib) { 272 ret = iwl_set_Xtal_calib(priv); 273 if (ret) 274 return ret; 275 } 276 277 return iwl_send_calib_results(priv); 278 } 279 280 struct iwl_alive_data { 281 bool valid; 282 u8 subtype; 283 }; 284 285 static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, 286 struct iwl_rx_packet *pkt, void *data) 287 { 288 struct iwl_priv *priv = 289 container_of(notif_wait, struct iwl_priv, notif_wait); 290 struct iwl_alive_data *alive_data = data; 291 struct iwl_alive_resp *palive; 292 293 palive = (void *)pkt->data; 294 295 IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision " 296 "0x%01X 0x%01X\n", 297 palive->is_valid, palive->ver_type, 298 palive->ver_subtype); 299 300 priv->device_pointers.error_event_table = 301 le32_to_cpu(palive->error_event_table_ptr); 302 priv->device_pointers.log_event_table = 303 le32_to_cpu(palive->log_event_table_ptr); 304 305 alive_data->subtype = palive->ver_subtype; 306 alive_data->valid = palive->is_valid == UCODE_VALID_OK; 307 308 return true; 309 } 310 311 #define UCODE_ALIVE_TIMEOUT HZ 312 #define UCODE_CALIB_TIMEOUT (2*HZ) 313 314 int iwl_load_ucode_wait_alive(struct iwl_priv *priv, 315 enum iwl_ucode_type ucode_type) 316 { 317 struct iwl_notification_wait alive_wait; 318 struct iwl_alive_data alive_data; 319 const struct fw_img *fw; 320 int ret; 321 enum iwl_ucode_type old_type; 322 static const u16 alive_cmd[] = { REPLY_ALIVE }; 323 324 fw = iwl_get_ucode_image(priv->fw, ucode_type); 325 if (WARN_ON(!fw)) 326 return -EINVAL; 327 328 old_type = priv->cur_ucode; 329 priv->cur_ucode = ucode_type; 330 priv->ucode_loaded = false; 331 332 iwl_init_notification_wait(&priv->notif_wait, &alive_wait, 333 alive_cmd, ARRAY_SIZE(alive_cmd), 334 iwl_alive_fn, &alive_data); 335 336 ret = iwl_trans_start_fw(priv->trans, fw, false); 337 if (ret) { 338 priv->cur_ucode = old_type; 339 iwl_remove_notification(&priv->notif_wait, &alive_wait); 340 return ret; 341 } 342 343 /* 344 * Some things may run in the background now, but we 345 * just wait for the ALIVE notification here. 346 */ 347 ret = iwl_wait_notification(&priv->notif_wait, &alive_wait, 348 UCODE_ALIVE_TIMEOUT); 349 if (ret) { 350 priv->cur_ucode = old_type; 351 return ret; 352 } 353 354 if (!alive_data.valid) { 355 IWL_ERR(priv, "Loaded ucode is not valid!\n"); 356 priv->cur_ucode = old_type; 357 return -EIO; 358 } 359 360 priv->ucode_loaded = true; 361 362 if (ucode_type != IWL_UCODE_WOWLAN) { 363 /* delay a bit to give rfkill time to run */ 364 msleep(5); 365 } 366 367 ret = iwl_alive_notify(priv); 368 if (ret) { 369 IWL_WARN(priv, 370 "Could not complete ALIVE transition: %d\n", ret); 371 priv->cur_ucode = old_type; 372 return ret; 373 } 374 375 return 0; 376 } 377 378 static bool iwlagn_wait_calib(struct iwl_notif_wait_data *notif_wait, 379 struct iwl_rx_packet *pkt, void *data) 380 { 381 struct iwl_priv *priv = data; 382 struct iwl_calib_hdr *hdr; 383 384 if (pkt->hdr.cmd != CALIBRATION_RES_NOTIFICATION) { 385 WARN_ON(pkt->hdr.cmd != CALIBRATION_COMPLETE_NOTIFICATION); 386 return true; 387 } 388 389 hdr = (struct iwl_calib_hdr *)pkt->data; 390 391 if (iwl_calib_set(priv, hdr, iwl_rx_packet_payload_len(pkt))) 392 IWL_ERR(priv, "Failed to record calibration data %d\n", 393 hdr->op_code); 394 395 return false; 396 } 397 398 int iwl_run_init_ucode(struct iwl_priv *priv) 399 { 400 struct iwl_notification_wait calib_wait; 401 static const u16 calib_complete[] = { 402 CALIBRATION_RES_NOTIFICATION, 403 CALIBRATION_COMPLETE_NOTIFICATION 404 }; 405 int ret; 406 407 lockdep_assert_held(&priv->mutex); 408 409 /* No init ucode required? Curious, but maybe ok */ 410 if (!priv->fw->img[IWL_UCODE_INIT].num_sec) 411 return 0; 412 413 iwl_init_notification_wait(&priv->notif_wait, &calib_wait, 414 calib_complete, ARRAY_SIZE(calib_complete), 415 iwlagn_wait_calib, priv); 416 417 /* Will also start the device */ 418 ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); 419 if (ret) 420 goto error; 421 422 ret = iwl_init_alive_start(priv); 423 if (ret) 424 goto error; 425 426 /* 427 * Some things may run in the background now, but we 428 * just wait for the calibration complete notification. 429 */ 430 ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 431 UCODE_CALIB_TIMEOUT); 432 433 goto out; 434 435 error: 436 iwl_remove_notification(&priv->notif_wait, &calib_wait); 437 out: 438 /* Whatever happened, stop the device */ 439 iwl_trans_stop_device(priv->trans); 440 priv->ucode_loaded = false; 441 442 return ret; 443 } 444