in s3fwrn5/firmware.c [109:180]
static int s3fwrn5_fw_enter_update_mode(struct s3fwrn5_fw_info *fw_info,
const void *hash_data, u16 hash_size,
const void *sig_data, u16 sig_size)
{
struct s3fwrn5_fw_cmd_enter_updatemode args;
struct sk_buff *msg, *rsp = NULL;
struct s3fwrn5_fw_header *hdr;
int ret;
/* Send ENTER_UPDATE_MODE command */
args.hashcode_size = hash_size;
args.signature_size = sig_size;
ret = s3fwrn5_fw_prep_msg(fw_info, &msg, S3FWRN5_FW_MSG_CMD,
S3FWRN5_FW_CMD_ENTER_UPDATE_MODE, &args, sizeof(args));
if (ret < 0)
return ret;
ret = s3fwrn5_fw_send_msg(fw_info, msg, &rsp);
kfree_skb(msg);
if (ret < 0)
return ret;
hdr = (struct s3fwrn5_fw_header *) rsp->data;
if (hdr->code != S3FWRN5_FW_RET_SUCCESS) {
ret = -EPROTO;
goto out;
}
kfree_skb(rsp);
/* Send hashcode data */
ret = s3fwrn5_fw_prep_msg(fw_info, &msg, S3FWRN5_FW_MSG_DATA, 0,
hash_data, hash_size);
if (ret < 0)
return ret;
ret = s3fwrn5_fw_send_msg(fw_info, msg, &rsp);
kfree_skb(msg);
if (ret < 0)
return ret;
hdr = (struct s3fwrn5_fw_header *) rsp->data;
if (hdr->code != S3FWRN5_FW_RET_SUCCESS) {
ret = -EPROTO;
goto out;
}
kfree_skb(rsp);
/* Send signature data */
ret = s3fwrn5_fw_prep_msg(fw_info, &msg, S3FWRN5_FW_MSG_DATA, 0,
sig_data, sig_size);
if (ret < 0)
return ret;
ret = s3fwrn5_fw_send_msg(fw_info, msg, &rsp);
kfree_skb(msg);
if (ret < 0)
return ret;
hdr = (struct s3fwrn5_fw_header *) rsp->data;
if (hdr->code != S3FWRN5_FW_RET_SUCCESS)
ret = -EPROTO;
out:
kfree_skb(rsp);
return ret;
}