ptp_ocp.c (b88fdbba931e9c79772120cb60a6ea8adaf0b451) | ptp_ocp.c (3c3673bde50c31d1f5ab0b39e9eeb555285786bb) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* Copyright (c) 2020 Facebook */ 3 4#include <linux/err.h> 5#include <linux/kernel.h> 6#include <linux/module.h> 7#include <linux/debugfs.h> 8#include <linux/init.h> --- 5 unchanged lines hidden (view full) --- 14#include <linux/platform_data/i2c-xiic.h> 15#include <linux/ptp_clock_kernel.h> 16#include <linux/spi/spi.h> 17#include <linux/spi/xilinx_spi.h> 18#include <net/devlink.h> 19#include <linux/i2c.h> 20#include <linux/mtd/mtd.h> 21#include <linux/nvmem-consumer.h> | 1// SPDX-License-Identifier: GPL-2.0-only 2/* Copyright (c) 2020 Facebook */ 3 4#include <linux/err.h> 5#include <linux/kernel.h> 6#include <linux/module.h> 7#include <linux/debugfs.h> 8#include <linux/init.h> --- 5 unchanged lines hidden (view full) --- 14#include <linux/platform_data/i2c-xiic.h> 15#include <linux/ptp_clock_kernel.h> 16#include <linux/spi/spi.h> 17#include <linux/spi/xilinx_spi.h> 18#include <net/devlink.h> 19#include <linux/i2c.h> 20#include <linux/mtd/mtd.h> 21#include <linux/nvmem-consumer.h> |
22#include <linux/crc16.h> |
|
22 23#define PCI_VENDOR_ID_FACEBOOK 0x1d9b 24#define PCI_DEVICE_ID_FACEBOOK_TIMECARD 0x0400 25 26#define PCI_VENDOR_ID_CELESTICA 0x18d4 27#define PCI_DEVICE_ID_CELESTICA_TIMECARD 0x1008 28 29static struct class timecard_class = { --- 178 unchanged lines hidden (view full) --- 208 209struct ptp_ocp_flash_info { 210 const char *name; 211 int pci_offset; 212 int data_size; 213 void *data; 214}; 215 | 23 24#define PCI_VENDOR_ID_FACEBOOK 0x1d9b 25#define PCI_DEVICE_ID_FACEBOOK_TIMECARD 0x0400 26 27#define PCI_VENDOR_ID_CELESTICA 0x18d4 28#define PCI_DEVICE_ID_CELESTICA_TIMECARD 0x1008 29 30static struct class timecard_class = { --- 178 unchanged lines hidden (view full) --- 209 210struct ptp_ocp_flash_info { 211 const char *name; 212 int pci_offset; 213 int data_size; 214 void *data; 215}; 216 |
217struct ptp_ocp_firmware_header { 218 char magic[4]; 219 __be16 pci_vendor_id; 220 __be16 pci_device_id; 221 __be32 image_size; 222 __be16 hw_revision; 223 __be16 crc; 224}; 225 226#define OCP_FIRMWARE_MAGIC_HEADER "OCPC" 227 |
|
216struct ptp_ocp_i2c_info { 217 const char *name; 218 unsigned long fixed_rate; 219 size_t data_size; 220 void *data; 221}; 222 223struct ptp_ocp_ext_info { --- 1095 unchanged lines hidden (view full) --- 1319 last = dev; 1320 } 1321 put_device(last); 1322 1323 return dev; 1324} 1325 1326static int | 228struct ptp_ocp_i2c_info { 229 const char *name; 230 unsigned long fixed_rate; 231 size_t data_size; 232 void *data; 233}; 234 235struct ptp_ocp_ext_info { --- 1095 unchanged lines hidden (view full) --- 1331 last = dev; 1332 } 1333 put_device(last); 1334 1335 return dev; 1336} 1337 1338static int |
1339ptp_ocp_devlink_fw_image(struct devlink *devlink, const struct firmware *fw, 1340 const u8 **data, size_t *size) 1341{ 1342 struct ptp_ocp *bp = devlink_priv(devlink); 1343 const struct ptp_ocp_firmware_header *hdr; 1344 size_t offset, length; 1345 u16 crc; 1346 1347 hdr = (const struct ptp_ocp_firmware_header *)fw->data; 1348 if (memcmp(hdr->magic, OCP_FIRMWARE_MAGIC_HEADER, 4)) { 1349 devlink_flash_update_status_notify(devlink, 1350 "No firmware header found, flashing raw image", 1351 NULL, 0, 0); 1352 offset = 0; 1353 length = fw->size; 1354 goto out; 1355 } 1356 1357 if (be16_to_cpu(hdr->pci_vendor_id) != bp->pdev->vendor || 1358 be16_to_cpu(hdr->pci_device_id) != bp->pdev->device) { 1359 devlink_flash_update_status_notify(devlink, 1360 "Firmware image compatibility check failed", 1361 NULL, 0, 0); 1362 return -EINVAL; 1363 } 1364 1365 offset = sizeof(*hdr); 1366 length = be32_to_cpu(hdr->image_size); 1367 if (length != (fw->size - offset)) { 1368 devlink_flash_update_status_notify(devlink, 1369 "Firmware image size check failed", 1370 NULL, 0, 0); 1371 return -EINVAL; 1372 } 1373 1374 crc = crc16(0xffff, &fw->data[offset], length); 1375 if (be16_to_cpu(hdr->crc) != crc) { 1376 devlink_flash_update_status_notify(devlink, 1377 "Firmware image CRC check failed", 1378 NULL, 0, 0); 1379 return -EINVAL; 1380 } 1381 1382out: 1383 *data = &fw->data[offset]; 1384 *size = length; 1385 1386 return 0; 1387} 1388 1389static int |
|
1327ptp_ocp_devlink_flash(struct devlink *devlink, struct device *dev, 1328 const struct firmware *fw) 1329{ 1330 struct mtd_info *mtd = dev_get_drvdata(dev); 1331 struct ptp_ocp *bp = devlink_priv(devlink); | 1390ptp_ocp_devlink_flash(struct devlink *devlink, struct device *dev, 1391 const struct firmware *fw) 1392{ 1393 struct mtd_info *mtd = dev_get_drvdata(dev); 1394 struct ptp_ocp *bp = devlink_priv(devlink); |
1332 size_t off, len, resid, wrote; | 1395 size_t off, len, size, resid, wrote; |
1333 struct erase_info erase; 1334 size_t base, blksz; | 1396 struct erase_info erase; 1397 size_t base, blksz; |
1335 int err = 0; | 1398 const u8 *data; 1399 int err; |
1336 | 1400 |
1401 err = ptp_ocp_devlink_fw_image(devlink, fw, &data, &size); 1402 if (err) 1403 goto out; 1404 |
|
1337 off = 0; 1338 base = bp->flash_start; 1339 blksz = 4096; | 1405 off = 0; 1406 base = bp->flash_start; 1407 blksz = 4096; |
1340 resid = fw->size; | 1408 resid = size; |
1341 1342 while (resid) { 1343 devlink_flash_update_status_notify(devlink, "Flashing", | 1409 1410 while (resid) { 1411 devlink_flash_update_status_notify(devlink, "Flashing", |
1344 NULL, off, fw->size); | 1412 NULL, off, size); |
1345 1346 len = min_t(size_t, resid, blksz); 1347 erase.addr = base + off; 1348 erase.len = blksz; 1349 1350 err = mtd_erase(mtd, &erase); 1351 if (err) 1352 goto out; 1353 | 1413 1414 len = min_t(size_t, resid, blksz); 1415 erase.addr = base + off; 1416 erase.len = blksz; 1417 1418 err = mtd_erase(mtd, &erase); 1419 if (err) 1420 goto out; 1421 |
1354 err = mtd_write(mtd, base + off, len, &wrote, &fw->data[off]); | 1422 err = mtd_write(mtd, base + off, len, &wrote, data + off); |
1355 if (err) 1356 goto out; 1357 1358 off += blksz; 1359 resid -= len; 1360 } 1361out: 1362 return err; --- 2463 unchanged lines hidden --- | 1423 if (err) 1424 goto out; 1425 1426 off += blksz; 1427 resid -= len; 1428 } 1429out: 1430 return err; --- 2463 unchanged lines hidden --- |