int iwm_target_reset(struct iwm_priv *iwm) { struct iwm_udma_nonwifi_cmd target_cmd; target_cmd.opcode = UMAC_HDI_OUT_OPCODE_REBOOT; target_cmd.addr = 0; target_cmd.op1_sz = 0; target_cmd.op2 = 0; target_cmd.handle_by_hw = 0; target_cmd.resp = 0; target_cmd.eop = 1; return iwm_hal_send_target_cmd(iwm, &target_cmd, NULL); }
static int iwm_load_firmware_chunk(struct iwm_priv *iwm, const struct firmware *fw, struct iwm_fw_img_desc *img_desc) { struct iwm_udma_nonwifi_cmd target_cmd; u32 chunk_size; const u8 *chunk_ptr; int ret = 0; IWM_DBG_FW(iwm, INFO, "Loading FW chunk: %d bytes @ 0x%x\n", img_desc->length, img_desc->address); target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE; target_cmd.handle_by_hw = 1; target_cmd.op2 = 0; target_cmd.resp = 0; target_cmd.eop = 1; chunk_size = img_desc->length; chunk_ptr = fw->data + img_desc->offset; while (chunk_size > 0) { u32 tmp_chunk_size; tmp_chunk_size = min_t(u32, chunk_size, IWM_MAX_NONWIFI_CMD_BUFF_SIZE); target_cmd.addr = cpu_to_le32(img_desc->address + (chunk_ptr - fw->data - img_desc->offset)); target_cmd.op1_sz = cpu_to_le32(tmp_chunk_size); IWM_DBG_FW(iwm, DBG, "\t%d bytes @ 0x%x\n", tmp_chunk_size, target_cmd.addr); ret = iwm_hal_send_target_cmd(iwm, &target_cmd, chunk_ptr); if (ret < 0) { IWM_ERR(iwm, "Couldn't load FW chunk\n"); break; } chunk_size -= tmp_chunk_size; chunk_ptr += tmp_chunk_size; } return ret; }
static int iwm_target_read(struct iwm_priv *iwm, __le32 address, u8 *response, u32 resp_size) { struct iwm_udma_nonwifi_cmd target_cmd; struct iwm_nonwifi_cmd *cmd; u16 seq_num; int ret = 0; target_cmd.opcode = UMAC_HDI_OUT_OPCODE_READ; target_cmd.addr = address; target_cmd.op1_sz = cpu_to_le32(resp_size); target_cmd.op2 = 0; target_cmd.handle_by_hw = 0; target_cmd.resp = 1; target_cmd.eop = 1; ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL); if (ret < 0) { IWM_ERR(iwm, "Couldn't send READ command\n"); return ret; } /* */ seq_num = ret; ret = wait_event_interruptible_timeout(iwm->nonwifi_queue, (cmd = iwm_get_pending_nonwifi_cmd(iwm, seq_num, UMAC_HDI_OUT_OPCODE_READ)) != NULL, 2 * HZ); if (!ret) { IWM_ERR(iwm, "Didn't receive a target READ answer\n"); return ret; } memcpy(response, cmd->buf.hdr + sizeof(struct iwm_udma_in_hdr), resp_size); kfree(cmd); return 0; }
static int iwm_load_umac(struct iwm_priv *iwm) { struct iwm_udma_nonwifi_cmd target_cmd; int ret; ret = iwm_load_img(iwm, iwm->bus_ops->umac_name); if (ret < 0) return ret; target_cmd.opcode = UMAC_HDI_OUT_OPCODE_JUMP; target_cmd.addr = cpu_to_le32(UMAC_MU_FW_INST_DATA_12_ADDR); target_cmd.op1_sz = 0; target_cmd.op2 = 0; target_cmd.handle_by_hw = 0; target_cmd.resp = 1 ; target_cmd.eop = 1; ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL); if (ret < 0) IWM_ERR(iwm, "Couldn't send JMP command\n"); return ret; }