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 static inline const struct fw_img * 50 iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) 51 { 52 if (ucode_type >= IWL_UCODE_TYPE_MAX) 53 return NULL; 54 55 return &priv->fw->img[ucode_type]; 56 } 57 58 /* 59 * Calibration 60 */ 61 static int iwl_set_Xtal_calib(struct iwl_priv *priv) 62 { 63 struct iwl_calib_xtal_freq_cmd cmd; 64 __le16 *xtal_calib = priv->nvm_data->xtal_calib; 65 66 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); 67 cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); 68 cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); 69 return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); 70 } 71 72 static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) 73 { 74 struct iwl_calib_temperature_offset_cmd cmd; 75 76 memset(&cmd, 0, sizeof(cmd)); 77 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); 78 cmd.radio_sensor_offset = priv->nvm_data->raw_temperature; 79 if (!(cmd.radio_sensor_offset)) 80 cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; 81 82 IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", 83 le16_to_cpu(cmd.radio_sensor_offset)); 84 return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); 85 } 86 87 static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) 88 { 89 struct iwl_calib_temperature_offset_v2_cmd cmd; 90 91 memset(&cmd, 0, sizeof(cmd)); 92 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); 93 cmd.radio_sensor_offset_high = priv->nvm_data->kelvin_temperature; 94 cmd.radio_sensor_offset_low = priv->nvm_data->raw_temperature; 95 if (!cmd.radio_sensor_offset_low) { 96 IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); 97 cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; 98 cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; 99 } 100 cmd.burntVoltageRef = priv->nvm_data->calib_voltage; 101 102 IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", 103 le16_to_cpu(cmd.radio_sensor_offset_high)); 104 IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n", 105 le16_to_cpu(cmd.radio_sensor_offset_low)); 106 IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n", 107 le16_to_cpu(cmd.burntVoltageRef)); 108 109 return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); 110 } 111 112 static int iwl_send_calib_cfg(struct iwl_priv *priv) 113 { 114 struct iwl_calib_cfg_cmd calib_cfg_cmd; 115 struct iwl_host_cmd cmd = { 116 .id = CALIBRATION_CFG_CMD, 117 .len = { sizeof(struct iwl_calib_cfg_cmd), }, 118 .data = { &calib_cfg_cmd, }, 119 }; 120 121 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); 122 calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL; 123 calib_cfg_cmd.ucd_calib_cfg.once.start = IWL_CALIB_INIT_CFG_ALL; 124 calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL; 125 calib_cfg_cmd.ucd_calib_cfg.flags = 126 IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; 127 128 return iwl_dvm_send_cmd(priv, &cmd); 129 } 130 131 int iwl_init_alive_start(struct iwl_priv *priv) 132 { 133 int ret; 134 135 if (priv->lib->bt_params && 136 priv->lib->bt_params->advanced_bt_coexist) { 137 /* 138 * Tell uCode we are ready to perform calibration 139 * need to perform this before any calibration 140 * no need to close the envlope since we are going 141 * to load the runtime uCode later. 142 */ 143 ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, 144 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); 145 if (ret) 146 return ret; 147 148 } 149 150 ret = iwl_send_calib_cfg(priv); 151 if (ret) 152 return ret; 153 154 /** 155 * temperature offset calibration is only needed for runtime ucode, 156 * so prepare the value now. 157 */ 158 if (priv->lib->need_temp_offset_calib) { 159 if (priv->lib->temp_offset_v2) 160 return iwl_set_temperature_offset_calib_v2(priv); 161 else 162 return iwl_set_temperature_offset_calib(priv); 163 } 164 165 return 0; 166 } 167 168 static int iwl_send_wimax_coex(struct iwl_priv *priv) 169 { 170 struct iwl_wimax_coex_cmd coex_cmd; 171 172 /* coexistence is disabled */ 173 memset(&coex_cmd, 0, sizeof(coex_cmd)); 174 175 return iwl_dvm_send_cmd_pdu(priv, 176 COEX_PRIORITY_TABLE_CMD, 0, 177 sizeof(coex_cmd), &coex_cmd); 178 } 179 180 static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { 181 ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 182 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 183 ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 184 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 185 ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 186 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 187 ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 188 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 189 ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 190 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 191 ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 192 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 193 ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 194 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 195 ((BT_COEX_PRIO_TBL_PRIO_COEX_OFF << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 196 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 197 ((BT_COEX_PRIO_TBL_PRIO_COEX_ON << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | 198 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), 199 0, 0, 0, 0, 0, 0, 0 200 }; 201 202 void iwl_send_prio_tbl(struct iwl_priv *priv) 203 { 204 struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; 205 206 memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, 207 sizeof(iwl_bt_prio_tbl)); 208 if (iwl_dvm_send_cmd_pdu(priv, 209 REPLY_BT_COEX_PRIO_TABLE, 0, 210 sizeof(prio_tbl_cmd), &prio_tbl_cmd)) 211 IWL_ERR(priv, "failed to send BT prio tbl command\n"); 212 } 213 214 int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) 215 { 216 struct iwl_bt_coex_prot_env_cmd env_cmd; 217 int ret; 218 219 env_cmd.action = action; 220 env_cmd.type = type; 221 ret = iwl_dvm_send_cmd_pdu(priv, 222 REPLY_BT_COEX_PROT_ENV, 0, 223 sizeof(env_cmd), &env_cmd); 224 if (ret) 225 IWL_ERR(priv, "failed to send BT env command\n"); 226 return ret; 227 } 228 229 static const u8 iwlagn_default_queue_to_tx_fifo[] = { 230 IWL_TX_FIFO_VO, 231 IWL_TX_FIFO_VI, 232 IWL_TX_FIFO_BE, 233 IWL_TX_FIFO_BK, 234 }; 235 236 static const u8 iwlagn_ipan_queue_to_tx_fifo[] = { 237 IWL_TX_FIFO_VO, 238 IWL_TX_FIFO_VI, 239 IWL_TX_FIFO_BE, 240 IWL_TX_FIFO_BK, 241 IWL_TX_FIFO_BK_IPAN, 242 IWL_TX_FIFO_BE_IPAN, 243 IWL_TX_FIFO_VI_IPAN, 244 IWL_TX_FIFO_VO_IPAN, 245 IWL_TX_FIFO_BE_IPAN, 246 IWL_TX_FIFO_UNUSED, 247 IWL_TX_FIFO_AUX, 248 }; 249 250 static int iwl_alive_notify(struct iwl_priv *priv) 251 { 252 const u8 *queue_to_txf; 253 u8 n_queues; 254 int ret; 255 int i; 256 257 iwl_trans_fw_alive(priv->trans, 0); 258 259 if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN && 260 priv->nvm_data->sku_cap_ipan_enable) { 261 n_queues = ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo); 262 queue_to_txf = iwlagn_ipan_queue_to_tx_fifo; 263 } else { 264 n_queues = ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); 265 queue_to_txf = iwlagn_default_queue_to_tx_fifo; 266 } 267 268 for (i = 0; i < n_queues; i++) 269 if (queue_to_txf[i] != IWL_TX_FIFO_UNUSED) 270 iwl_trans_ac_txq_enable(priv->trans, i, 271 queue_to_txf[i], 0); 272 273 priv->passive_no_rx = false; 274 priv->transport_queue_stop = 0; 275 276 ret = iwl_send_wimax_coex(priv); 277 if (ret) 278 return ret; 279 280 if (!priv->lib->no_xtal_calib) { 281 ret = iwl_set_Xtal_calib(priv); 282 if (ret) 283 return ret; 284 } 285 286 return iwl_send_calib_results(priv); 287 } 288 289 struct iwl_alive_data { 290 bool valid; 291 u8 subtype; 292 }; 293 294 static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, 295 struct iwl_rx_packet *pkt, void *data) 296 { 297 struct iwl_priv *priv = 298 container_of(notif_wait, struct iwl_priv, notif_wait); 299 struct iwl_alive_data *alive_data = data; 300 struct iwl_alive_resp *palive; 301 302 palive = (void *)pkt->data; 303 304 IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision " 305 "0x%01X 0x%01X\n", 306 palive->is_valid, palive->ver_type, 307 palive->ver_subtype); 308 309 priv->device_pointers.error_event_table = 310 le32_to_cpu(palive->error_event_table_ptr); 311 priv->device_pointers.log_event_table = 312 le32_to_cpu(palive->log_event_table_ptr); 313 314 alive_data->subtype = palive->ver_subtype; 315 alive_data->valid = palive->is_valid == UCODE_VALID_OK; 316 317 return true; 318 } 319 320 #define UCODE_ALIVE_TIMEOUT HZ 321 #define UCODE_CALIB_TIMEOUT (2*HZ) 322 323 int iwl_load_ucode_wait_alive(struct iwl_priv *priv, 324 enum iwl_ucode_type ucode_type) 325 { 326 struct iwl_notification_wait alive_wait; 327 struct iwl_alive_data alive_data; 328 const struct fw_img *fw; 329 int ret; 330 enum iwl_ucode_type old_type; 331 static const u16 alive_cmd[] = { REPLY_ALIVE }; 332 333 fw = iwl_get_ucode_image(priv, ucode_type); 334 if (WARN_ON(!fw)) 335 return -EINVAL; 336 337 old_type = priv->cur_ucode; 338 priv->cur_ucode = ucode_type; 339 priv->ucode_loaded = false; 340 341 iwl_init_notification_wait(&priv->notif_wait, &alive_wait, 342 alive_cmd, ARRAY_SIZE(alive_cmd), 343 iwl_alive_fn, &alive_data); 344 345 ret = iwl_trans_start_fw(priv->trans, fw, false); 346 if (ret) { 347 priv->cur_ucode = old_type; 348 iwl_remove_notification(&priv->notif_wait, &alive_wait); 349 return ret; 350 } 351 352 /* 353 * Some things may run in the background now, but we 354 * just wait for the ALIVE notification here. 355 */ 356 ret = iwl_wait_notification(&priv->notif_wait, &alive_wait, 357 UCODE_ALIVE_TIMEOUT); 358 if (ret) { 359 priv->cur_ucode = old_type; 360 return ret; 361 } 362 363 if (!alive_data.valid) { 364 IWL_ERR(priv, "Loaded ucode is not valid!\n"); 365 priv->cur_ucode = old_type; 366 return -EIO; 367 } 368 369 priv->ucode_loaded = true; 370 371 if (ucode_type != IWL_UCODE_WOWLAN) { 372 /* delay a bit to give rfkill time to run */ 373 msleep(5); 374 } 375 376 ret = iwl_alive_notify(priv); 377 if (ret) { 378 IWL_WARN(priv, 379 "Could not complete ALIVE transition: %d\n", ret); 380 priv->cur_ucode = old_type; 381 return ret; 382 } 383 384 return 0; 385 } 386 387 static bool iwlagn_wait_calib(struct iwl_notif_wait_data *notif_wait, 388 struct iwl_rx_packet *pkt, void *data) 389 { 390 struct iwl_priv *priv = data; 391 struct iwl_calib_hdr *hdr; 392 393 if (pkt->hdr.cmd != CALIBRATION_RES_NOTIFICATION) { 394 WARN_ON(pkt->hdr.cmd != CALIBRATION_COMPLETE_NOTIFICATION); 395 return true; 396 } 397 398 hdr = (struct iwl_calib_hdr *)pkt->data; 399 400 if (iwl_calib_set(priv, hdr, iwl_rx_packet_payload_len(pkt))) 401 IWL_ERR(priv, "Failed to record calibration data %d\n", 402 hdr->op_code); 403 404 return false; 405 } 406 407 int iwl_run_init_ucode(struct iwl_priv *priv) 408 { 409 struct iwl_notification_wait calib_wait; 410 static const u16 calib_complete[] = { 411 CALIBRATION_RES_NOTIFICATION, 412 CALIBRATION_COMPLETE_NOTIFICATION 413 }; 414 int ret; 415 416 lockdep_assert_held(&priv->mutex); 417 418 /* No init ucode required? Curious, but maybe ok */ 419 if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len) 420 return 0; 421 422 iwl_init_notification_wait(&priv->notif_wait, &calib_wait, 423 calib_complete, ARRAY_SIZE(calib_complete), 424 iwlagn_wait_calib, priv); 425 426 /* Will also start the device */ 427 ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); 428 if (ret) 429 goto error; 430 431 ret = iwl_init_alive_start(priv); 432 if (ret) 433 goto error; 434 435 /* 436 * Some things may run in the background now, but we 437 * just wait for the calibration complete notification. 438 */ 439 ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 440 UCODE_CALIB_TIMEOUT); 441 442 goto out; 443 444 error: 445 iwl_remove_notification(&priv->notif_wait, &calib_wait); 446 out: 447 /* Whatever happened, stop the device */ 448 iwl_trans_stop_device(priv->trans); 449 priv->ucode_loaded = false; 450 451 return ret; 452 } 453