|
@@ -928,6 +928,41 @@ static int ti_cpu_rev(struct edge_ti_manuf_descriptor *desc)
|
|
|
return TI_GET_CPU_REVISION(desc->CpuRev_BoardRev);
|
|
|
}
|
|
|
|
|
|
+static int check_fw_sanity(struct edgeport_serial *serial,
|
|
|
+ const struct firmware *fw)
|
|
|
+{
|
|
|
+ u16 length_total;
|
|
|
+ u8 checksum = 0;
|
|
|
+ int pos;
|
|
|
+ struct device *dev = &serial->serial->interface->dev;
|
|
|
+ struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;
|
|
|
+
|
|
|
+ if (fw->size < sizeof(struct edgeport_fw_hdr)) {
|
|
|
+ dev_err(dev, "incomplete fw header\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ length_total = le16_to_cpu(fw_hdr->length) +
|
|
|
+ sizeof(struct edgeport_fw_hdr);
|
|
|
+
|
|
|
+ if (fw->size != length_total) {
|
|
|
+ dev_err(dev, "bad fw size (expected: %u, got: %zu)\n",
|
|
|
+ length_total, fw->size);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (pos = sizeof(struct edgeport_fw_hdr); pos < fw->size; ++pos)
|
|
|
+ checksum += fw->data[pos];
|
|
|
+
|
|
|
+ if (checksum != fw_hdr->checksum) {
|
|
|
+ dev_err(dev, "bad fw checksum (expected: 0x%x, got: 0x%x)\n",
|
|
|
+ fw_hdr->checksum, checksum);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* DownloadTIFirmware - Download run-time operating firmware to the TI5052
|
|
|
*
|
|
@@ -946,11 +981,8 @@ static int download_fw(struct edgeport_serial *serial,
|
|
|
int download_new_ver;
|
|
|
struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;
|
|
|
|
|
|
- if (fw->size < sizeof(struct edgeport_fw_hdr)) {
|
|
|
- dev_err(&serial->serial->interface->dev,
|
|
|
- "Incomplete firmware header.\n");
|
|
|
+ if (check_fw_sanity(serial, fw))
|
|
|
return -EINVAL;
|
|
|
- }
|
|
|
|
|
|
/* If on-board version is newer, "fw_version" will be updated below. */
|
|
|
serial->fw_version = (fw_hdr->major_version << 8) +
|