can: kvaser_pciefd: Remove SPI flash parameter read functionality

Remove SPI flash parameter read functionality, since it's only used for
reading the interface CAN controller count.
This information is already read from a register, making the information
redundant.

Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Link: https://lore.kernel.org/all/20230529134248.752036-7-extja@kvaser.com
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
Jimmy Assarsson 2023-05-29 15:42:40 +02:00 committed by Marc Kleine-Budde
parent 2c470dbbd3
commit c496adafee
2 changed files with 5 additions and 218 deletions

View File

@ -153,8 +153,7 @@ config CAN_JANZ_ICAN3
config CAN_KVASER_PCIEFD
depends on PCI
tristate "Kvaser PCIe FD cards"
select CRC32
help
help
This is a driver for the Kvaser PCI Express CAN FD family.
Supported devices:

View File

@ -3,10 +3,10 @@
* Parts of this driver are based on the following:
* - Kvaser linux pciefd driver (version 5.25)
* - PEAK linux canfd driver
* - Altera Avalon EPCS flash controller driver
*/
#include <linux/kernel.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/ethtool.h>
@ -14,7 +14,6 @@
#include <linux/can/dev.h>
#include <linux/timer.h>
#include <linux/netdevice.h>
#include <linux/crc32.h>
#include <linux/iopoll.h>
MODULE_LICENSE("Dual BSD/GPL");
@ -78,13 +77,6 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
#define KVASER_PCIEFD_SRB_STAT_REG (KVASER_PCIEFD_SRB_BASE + 0x210)
#define KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG (KVASER_PCIEFD_SRB_BASE + 0x214)
#define KVASER_PCIEFD_SRB_CTRL_REG (KVASER_PCIEFD_SRB_BASE + 0x218)
/* EPCS flash controller registers */
#define KVASER_PCIEFD_SPI_BASE 0x1fc00
#define KVASER_PCIEFD_SPI_RX_REG KVASER_PCIEFD_SPI_BASE
#define KVASER_PCIEFD_SPI_TX_REG (KVASER_PCIEFD_SPI_BASE + 0x4)
#define KVASER_PCIEFD_SPI_STATUS_REG (KVASER_PCIEFD_SPI_BASE + 0x8)
#define KVASER_PCIEFD_SPI_CTRL_REG (KVASER_PCIEFD_SPI_BASE + 0xc)
#define KVASER_PCIEFD_SPI_SSEL_REG (KVASER_PCIEFD_SPI_BASE + 0x14)
#define KVASER_PCIEFD_IRQ_ALL_MSK 0x1f
#define KVASER_PCIEFD_IRQ_SRB BIT(4)
@ -119,23 +111,6 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
/* DMA Enable */
#define KVASER_PCIEFD_SRB_CTRL_DMA_ENABLE BIT(0)
/* EPCS flash controller definitions */
#define KVASER_PCIEFD_CFG_IMG_SZ (64 * 1024)
#define KVASER_PCIEFD_CFG_IMG_OFFSET (31 * 65536L)
#define KVASER_PCIEFD_CFG_MAX_PARAMS 256
#define KVASER_PCIEFD_CFG_MAGIC 0xcafef00d
#define KVASER_PCIEFD_CFG_PARAM_MAX_SZ 24
#define KVASER_PCIEFD_CFG_SYS_VER 1
#define KVASER_PCIEFD_CFG_PARAM_NR_CHAN 130
#define KVASER_PCIEFD_SPI_TMT BIT(5)
#define KVASER_PCIEFD_SPI_TRDY BIT(6)
#define KVASER_PCIEFD_SPI_RRDY BIT(7)
#define KVASER_PCIEFD_FLASH_ID_EPCS16 0x14
/* Commands for controlling the onboard flash */
#define KVASER_PCIEFD_FLASH_RES_CMD 0xab
#define KVASER_PCIEFD_FLASH_READ_CMD 0x3
#define KVASER_PCIEFD_FLASH_STATUS_CMD 0x5
/* Kvaser KCAN definitions */
#define KVASER_PCIEFD_KCAN_CTRL_EFLUSH (4 << 29)
#define KVASER_PCIEFD_KCAN_CTRL_EFRAME (5 << 29)
@ -306,20 +281,6 @@ static const struct can_bittiming_const kvaser_pciefd_bittiming_const = {
.brp_inc = 1,
};
struct kvaser_pciefd_cfg_param {
__le32 magic;
__le32 nr;
__le32 len;
u8 data[KVASER_PCIEFD_CFG_PARAM_MAX_SZ];
};
struct kvaser_pciefd_cfg_img {
__le32 version;
__le32 magic;
__le32 crc;
struct kvaser_pciefd_cfg_param params[KVASER_PCIEFD_CFG_MAX_PARAMS];
};
static struct pci_device_id kvaser_pciefd_id_table[] = {
{ PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_4HS_ID), },
{ PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_2HS_ID), },
@ -330,164 +291,6 @@ static struct pci_device_id kvaser_pciefd_id_table[] = {
};
MODULE_DEVICE_TABLE(pci, kvaser_pciefd_id_table);
/* Onboard flash memory functions */
static int kvaser_pciefd_spi_wait_loop(struct kvaser_pciefd *pcie, int msk)
{
u32 res;
return readl_poll_timeout(pcie->reg_base + KVASER_PCIEFD_SPI_STATUS_REG,
res, res & msk, 0, 10);
}
static int kvaser_pciefd_spi_cmd(struct kvaser_pciefd *pcie, const u8 *tx,
u32 tx_len, u8 *rx, u32 rx_len)
{
int c;
iowrite32(BIT(0), pcie->reg_base + KVASER_PCIEFD_SPI_SSEL_REG);
iowrite32(BIT(10), pcie->reg_base + KVASER_PCIEFD_SPI_CTRL_REG);
ioread32(pcie->reg_base + KVASER_PCIEFD_SPI_RX_REG);
c = tx_len;
while (c--) {
if (kvaser_pciefd_spi_wait_loop(pcie, KVASER_PCIEFD_SPI_TRDY))
return -EIO;
iowrite32(*tx++, pcie->reg_base + KVASER_PCIEFD_SPI_TX_REG);
if (kvaser_pciefd_spi_wait_loop(pcie, KVASER_PCIEFD_SPI_RRDY))
return -EIO;
ioread32(pcie->reg_base + KVASER_PCIEFD_SPI_RX_REG);
}
c = rx_len;
while (c-- > 0) {
if (kvaser_pciefd_spi_wait_loop(pcie, KVASER_PCIEFD_SPI_TRDY))
return -EIO;
iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SPI_TX_REG);
if (kvaser_pciefd_spi_wait_loop(pcie, KVASER_PCIEFD_SPI_RRDY))
return -EIO;
*rx++ = ioread32(pcie->reg_base + KVASER_PCIEFD_SPI_RX_REG);
}
if (kvaser_pciefd_spi_wait_loop(pcie, KVASER_PCIEFD_SPI_TMT))
return -EIO;
iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SPI_CTRL_REG);
if (c != -1) {
dev_err(&pcie->pci->dev, "Flash SPI transfer failed\n");
return -EIO;
}
return 0;
}
static int kvaser_pciefd_cfg_read_and_verify(struct kvaser_pciefd *pcie,
struct kvaser_pciefd_cfg_img *img)
{
int offset = KVASER_PCIEFD_CFG_IMG_OFFSET;
int res, crc;
u8 *crc_buff;
u8 cmd[] = {
KVASER_PCIEFD_FLASH_READ_CMD,
(u8)((offset >> 16) & 0xff),
(u8)((offset >> 8) & 0xff),
(u8)(offset & 0xff)
};
res = kvaser_pciefd_spi_cmd(pcie, cmd, ARRAY_SIZE(cmd), (u8 *)img,
KVASER_PCIEFD_CFG_IMG_SZ);
if (res)
return res;
crc_buff = (u8 *)img->params;
if (le32_to_cpu(img->version) != KVASER_PCIEFD_CFG_SYS_VER) {
dev_err(&pcie->pci->dev,
"Config flash corrupted, version number is wrong\n");
return -ENODEV;
}
if (le32_to_cpu(img->magic) != KVASER_PCIEFD_CFG_MAGIC) {
dev_err(&pcie->pci->dev,
"Config flash corrupted, magic number is wrong\n");
return -ENODEV;
}
crc = ~crc32_be(0xffffffff, crc_buff, sizeof(img->params));
if (le32_to_cpu(img->crc) != crc) {
dev_err(&pcie->pci->dev,
"Stored CRC does not match flash image contents\n");
return -EIO;
}
return 0;
}
static void kvaser_pciefd_cfg_read_params(struct kvaser_pciefd *pcie,
struct kvaser_pciefd_cfg_img *img)
{
struct kvaser_pciefd_cfg_param *param;
param = &img->params[KVASER_PCIEFD_CFG_PARAM_NR_CHAN];
memcpy(&pcie->nr_channels, param->data, le32_to_cpu(param->len));
}
static int kvaser_pciefd_read_cfg(struct kvaser_pciefd *pcie)
{
int res;
struct kvaser_pciefd_cfg_img *img;
/* Read electronic signature */
u8 cmd[] = {KVASER_PCIEFD_FLASH_RES_CMD, 0, 0, 0};
res = kvaser_pciefd_spi_cmd(pcie, cmd, ARRAY_SIZE(cmd), cmd, 1);
if (res)
return -EIO;
img = kmalloc(KVASER_PCIEFD_CFG_IMG_SZ, GFP_KERNEL);
if (!img)
return -ENOMEM;
if (cmd[0] != KVASER_PCIEFD_FLASH_ID_EPCS16) {
dev_err(&pcie->pci->dev,
"Flash id is 0x%x instead of expected EPCS16 (0x%x)\n",
cmd[0], KVASER_PCIEFD_FLASH_ID_EPCS16);
res = -ENODEV;
goto image_free;
}
cmd[0] = KVASER_PCIEFD_FLASH_STATUS_CMD;
res = kvaser_pciefd_spi_cmd(pcie, cmd, 1, cmd, 1);
if (res) {
goto image_free;
} else if (cmd[0] & 1) {
res = -EIO;
/* No write is ever done, the WIP should never be set */
dev_err(&pcie->pci->dev, "Unexpected WIP bit set in flash\n");
goto image_free;
}
res = kvaser_pciefd_cfg_read_and_verify(pcie, img);
if (res) {
res = -EIO;
goto image_free;
}
kvaser_pciefd_cfg_read_params(pcie, img);
image_free:
kfree(img);
return res;
}
static void kvaser_pciefd_request_status(struct kvaser_pciefd_can *can)
{
u32 cmd;
@ -1125,25 +928,10 @@ static int kvaser_pciefd_setup_dma(struct kvaser_pciefd *pcie)
static int kvaser_pciefd_setup_board(struct kvaser_pciefd *pcie)
{
u32 sysid, srb_status, build;
u8 sysid_nr_chan;
int ret;
ret = kvaser_pciefd_read_cfg(pcie);
if (ret)
return ret;
sysid = ioread32(pcie->reg_base + KVASER_PCIEFD_SYSID_VERSION_REG);
sysid_nr_chan = (sysid >> KVASER_PCIEFD_SYSID_NRCHAN_SHIFT) & 0xff;
if (pcie->nr_channels != sysid_nr_chan) {
dev_err(&pcie->pci->dev,
"Number of channels does not match: %u vs %u\n",
pcie->nr_channels,
sysid_nr_chan);
return -ENODEV;
}
if (pcie->nr_channels > KVASER_PCIEFD_MAX_CAN_CHANNELS)
pcie->nr_channels = KVASER_PCIEFD_MAX_CAN_CHANNELS;
pcie->nr_channels = min(KVASER_PCIEFD_MAX_CAN_CHANNELS,
((sysid >> KVASER_PCIEFD_SYSID_NRCHAN_SHIFT) & 0xff));
build = ioread32(pcie->reg_base + KVASER_PCIEFD_SYSID_BUILD_REG);
dev_dbg(&pcie->pci->dev, "Version %u.%u.%u\n",
@ -1167,7 +955,7 @@ static int kvaser_pciefd_setup_board(struct kvaser_pciefd *pcie)
/* Turn off all loopback functionality */
iowrite32(0, pcie->reg_base + KVASER_PCIEFD_LOOP_REG);
return ret;
return 0;
}
static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie,