[can-next] can: remove Softing CANcard driver
Oliver Hartkopp <[email protected]>
| Newsgroups | org.kernel.vger.linux-can |
|---|---|
| Message-ID | <[email protected]> |
The PCMCIA Softing CANcard2 is discontinued since 2013 and the latest Windows drivers date back to Windows 7/8. The CANcard2 and also the rebranded Vector CANcardXL make use of a firmware to drive its onboard CPU to handle raw CAN messages (DPRAM) and its capability to perform timing critical Classical CAN protocols like ISO 15765-2:2004. The Softing Linux driver supported none of those higher layer CAN protocols but only raw CAN CC traffic. In 2026 this functionality is substituted with cost-effective USB CAN adapters, e.g. gs_usb. Remove the softing driver as there's no known user and we lack the access to this at least 25 y/o hardware for 10 years now. Cc: Kurt Van Dijck <[email protected]> Signed-off-by: Oliver Hartkopp <[email protected]> --- drivers/net/can/Kconfig | 1 - drivers/net/can/Makefile | 1 - drivers/net/can/softing/Kconfig | 31 - drivers/net/can/softing/Makefile | 5 - drivers/net/can/softing/softing.h | 168 ---- drivers/net/can/softing/softing_cs.c | 335 -------- drivers/net/can/softing/softing_fw.c | 700 ----------------- drivers/net/can/softing/softing_main.c | 864 --------------------- drivers/net/can/softing/softing_platform.h | 41 - 9 files changed, 2146 deletions(-) delete mode 100644 drivers/net/can/softing/Kconfig delete mode 100644 drivers/net/can/softing/Makefile delete mode 100644 drivers/net/can/softing/softing.h delete mode 100644 drivers/net/can/softing/softing_cs.c delete mode 100644 drivers/net/can/softing/softing_fw.c delete mode 100644 drivers/net/can/softing/softing_main.c delete mode 100644 drivers/net/can/softing/softing_platform.h diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index a8fad6fe5302..fb16f67a99f9 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -252,11 +252,10 @@ source "drivers/net/can/m_can/Kconfig" source "drivers/net/can/mscan/Kconfig" source "drivers/net/can/peak_canfd/Kconfig" source "drivers/net/can/rcar/Kconfig" source "drivers/net/can/rockchip/Kconfig" source "drivers/net/can/sja1000/Kconfig" -source "drivers/net/can/softing/Kconfig" source "drivers/net/can/spi/Kconfig" source "drivers/net/can/usb/Kconfig" endif #CAN_NETLINK diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 4010d17f8583..fa2cdd7bcd0a 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile @@ -11,11 +11,10 @@ obj-y += dev/ obj-y += esd/ obj-y += rcar/ obj-y += rockchip/ obj-y += spi/ obj-y += usb/ -obj-y += softing/ obj-$(CONFIG_CAN_AT91) += at91_can.o obj-$(CONFIG_CAN_BXCAN) += bxcan.o obj-$(CONFIG_CAN_CAN327) += can327.o obj-$(CONFIG_CAN_CC770) += cc770/ diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig deleted file mode 100644 index 8afd7d0a1000..000000000000 --- a/drivers/net/can/softing/Kconfig +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config CAN_SOFTING - tristate "Softing Gmbh CAN generic support" - depends on HAS_IOMEM - help - Support for CAN cards from Softing Gmbh & some cards - from Vector Gmbh. - Softing Gmbh CAN cards come with 1 or 2 physical buses. - Those cards typically use Dual Port RAM to communicate - with the host CPU. The interface is then identical for PCI - and PCMCIA cards. This driver operates on a platform device, - which has been created by softing_cs or softing_pci driver. - Warning: - The API of the card does not allow fine control per bus, but - controls the 2 buses on the card together. - As such, some actions (start/stop/busoff recovery) on 1 bus - must bring down the other bus too temporarily. - -config CAN_SOFTING_CS - tristate "Softing Gmbh CAN pcmcia cards" - depends on PCMCIA - depends on CAN_SOFTING - help - Support for PCMCIA cards from Softing Gmbh & some cards - from Vector Gmbh. - You need firmware for these, which you can get at - https://github.com/linux-can/can-firmware - This version of the driver is written against - firmware version 4.6 (softing-fw-4.6-binaries.tar.gz) - In order to use the card as CAN device, you need the Softing generic - support too. diff --git a/drivers/net/can/softing/Makefile b/drivers/net/can/softing/Makefile deleted file mode 100644 index c51154000377..000000000000 --- a/drivers/net/can/softing/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -softing-y := softing_main.o softing_fw.o -obj-$(CONFIG_CAN_SOFTING) += softing.o -obj-$(CONFIG_CAN_SOFTING_CS) += softing_cs.o diff --git a/drivers/net/can/softing/softing.h b/drivers/net/can/softing/softing.h deleted file mode 100644 index 2893007ea05e..000000000000 --- a/drivers/net/can/softing/softing.h +++ /dev/null @@ -1,168 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * softing common interfaces - * - * by Kurt Van Dijck, 2008-2010 - */ - -#include <linux/atomic.h> -#include <linux/netdevice.h> -#include <linux/ktime.h> -#include <linux/mutex.h> -#include <linux/spinlock.h> -#include <linux/can.h> -#include <linux/can/dev.h> - -#include "softing_platform.h" - -struct softing; - -struct softing_priv { - struct can_priv can; /* must be the first member! */ - struct net_device *netdev; - struct softing *card; - struct { - int pending; - /* variables which hold the circular buffer */ - int echo_put; - int echo_get; - } tx; - struct can_bittiming_const btr_const; - int index; - uint8_t output; - uint16_t chip; -}; -#define netdev2softing(netdev) ((struct softing_priv *)netdev_priv(netdev)) - -struct softing { - const struct softing_platform_data *pdat; - struct platform_device *pdev; - struct net_device *net[2]; - spinlock_t spin; /* protect this structure & DPRAM access */ - ktime_t ts_ref; - ktime_t ts_overflow; /* timestamp overflow value, in ktime */ - - struct { - /* indication of firmware status */ - int up; - /* protection of the 'up' variable */ - struct mutex lock; - } fw; - struct { - int nr; - int requested; - int svc_count; - unsigned int dpram_position; - } irq; - struct { - int pending; - int last_bus; - /* - * keep the bus that last tx'd a message, - * in order to let every netdev queue resume - */ - } tx; - __iomem uint8_t *dpram; - unsigned long dpram_phys; - unsigned long dpram_size; - struct { - uint16_t fw_version, hw_version, license, serial; - uint16_t chip[2]; - unsigned int freq; /* remote cpu's operating frequency */ - } id; -}; - -int softing_default_output(struct net_device *netdev); - -ktime_t softing_raw2ktime(struct softing *card, u32 raw); - -int softing_chip_poweron(struct softing *card); - -int softing_bootloader_command(struct softing *card, int16_t cmd, - const char *msg); - -/* Load firmware after reset */ -int softing_load_fw(const char *file, struct softing *card, - __iomem uint8_t *virt, unsigned int size, int offset); - -/* Load final application firmware after bootloader */ -int softing_load_app_fw(const char *file, struct softing *card); - -/* - * enable or disable irq - * only called with fw.lock locked - */ -int softing_enable_irq(struct softing *card, int enable); - -/* start/stop 1 bus on card */ -int softing_startstop(struct net_device *netdev, int up); - -/* netif_rx() */ -int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg, - ktime_t ktime); - -/* SOFTING DPRAM mappings */ -#define DPRAM_RX 0x0000 - #define DPRAM_RX_SIZE 32 - #define DPRAM_RX_CNT 16 -#define DPRAM_RX_RD 0x0201 /* uint8_t */ -#define DPRAM_RX_WR 0x0205 /* uint8_t */ -#define DPRAM_RX_LOST 0x0207 /* uint8_t */ - -#define DPRAM_FCT_PARAM 0x0300 /* int16_t [20] */ -#define DPRAM_FCT_RESULT 0x0328 /* int16_t */ -#define DPRAM_FCT_HOST 0x032b /* uint16_t */ - -#define DPRAM_INFO_BUSSTATE 0x0331 /* uint16_t */ -#define DPRAM_INFO_BUSSTATE2 0x0335 /* uint16_t */ -#define DPRAM_INFO_ERRSTATE 0x0339 /* uint16_t */ -#define DPRAM_INFO_ERRSTATE2 0x033d /* uint16_t */ -#define DPRAM_RESET 0x0341 /* uint16_t */ -#define DPRAM_CLR_RECV_FIFO 0x0345 /* uint16_t */ -#define DPRAM_RESET_TIME 0x034d /* uint16_t */ -#define DPRAM_TIME 0x0350 /* uint64_t */ -#define DPRAM_WR_START 0x0358 /* uint8_t */ -#define DPRAM_WR_END 0x0359 /* uint8_t */ -#define DPRAM_RESET_RX_FIFO 0x0361 /* uint16_t */ -#define DPRAM_RESET_TX_FIFO 0x0364 /* uint8_t */ -#define DPRAM_READ_FIFO_LEVEL 0x0365 /* uint8_t */ -#define DPRAM_RX_FIFO_LEVEL 0x0366 /* uint16_t */ -#define DPRAM_TX_FIFO_LEVEL 0x0366 /* uint16_t */ - -#define DPRAM_TX 0x0400 /* uint16_t */ - #define DPRAM_TX_SIZE 16 - #define DPRAM_TX_CNT 32 -#define DPRAM_TX_RD 0x0601 /* uint8_t */ -#define DPRAM_TX_WR 0x0605 /* uint8_t */ - -#define DPRAM_COMMAND 0x07e0 /* uint16_t */ -#define DPRAM_RECEIPT 0x07f0 /* uint16_t */ -#define DPRAM_IRQ_TOHOST 0x07fe /* uint8_t */ -#define DPRAM_IRQ_TOCARD 0x07ff /* uint8_t */ - -#define DPRAM_V2_RESET 0x0e00 /* uint8_t */ -#define DPRAM_V2_IRQ_TOHOST 0x0e02 /* uint8_t */ - -#define TXMAX (DPRAM_TX_CNT - 1) - -/* DPRAM return codes */ -#define RES_NONE 0 -#define RES_OK 1 -#define RES_NOK 2 -#define RES_UNKNOWN 3 -/* DPRAM flags */ -#define CMD_TX 0x01 -#define CMD_ACK 0x02 -#define CMD_XTD 0x04 -#define CMD_RTR 0x08 -#define CMD_ERR 0x10 -#define CMD_BUS2 0x80 - -/* returned fifo entry bus state masks */ -#define SF_MASK_BUSOFF 0x80 -#define SF_MASK_EPASSIVE 0x60 - -/* bus states */ -#define STATE_BUSOFF 2 -#define STATE_EPASSIVE 1 -#define STATE_EACTIVE 0 diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c deleted file mode 100644 index 3cea14cf055a..000000000000 --- a/drivers/net/can/softing/softing_cs.c +++ /dev/null @@ -1,335 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2008-2010 - * - * - Kurt Van Dijck, EIA Electronics - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/slab.h> - -#include <pcmcia/cistpl.h> -#include <pcmcia/ds.h> - -#include "softing_platform.h" - -static int softingcs_index; -static DEFINE_SPINLOCK(softingcs_index_lock); - -static int softingcs_reset(struct platform_device *pdev, int v); -static int softingcs_enable_irq(struct platform_device *pdev, int v); - -/* - * platform_data descriptions - */ -#define MHZ (1000*1000) -static const struct softing_platform_data softingcs_platform_data[] = { -{ - .name = "CANcard", - .manf = 0x0168, .prod = 0x001, - .generation = 1, - .nbus = 2, - .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, - .dpram_size = 0x0800, - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, - .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, - .reset = softingcs_reset, - .enable_irq = softingcs_enable_irq, -}, { - .name = "CANcard-NEC", - .manf = 0x0168, .prod = 0x002, - .generation = 1, - .nbus = 2, - .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, - .dpram_size = 0x0800, - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, - .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, - .reset = softingcs_reset, - .enable_irq = softingcs_enable_irq, -}, { - .name = "CANcard-SJA", - .manf = 0x0168, .prod = 0x004, - .generation = 1, - .nbus = 2, - .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, - .dpram_size = 0x0800, - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, - .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, - .reset = softingcs_reset, - .enable_irq = softingcs_enable_irq, -}, { - .name = "CANcard-2", - .manf = 0x0168, .prod = 0x005, - .generation = 2, - .nbus = 2, - .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, - .dpram_size = 0x1000, - .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, - .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, - .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, - .reset = softingcs_reset, - .enable_irq = NULL, -}, { - .name = "Vector-CANcard", - .manf = 0x0168, .prod = 0x081, - .generation = 1, - .nbus = 2, - .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, - .dpram_size = 0x0800, - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, - .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, - .reset = softingcs_reset, - .enable_irq = softingcs_enable_irq, -}, { - .name = "Vector-CANcard-SJA", - .manf = 0x0168, .prod = 0x084, - .generation = 1, - .nbus = 2, - .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, - .dpram_size = 0x0800, - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, - .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, - .reset = softingcs_reset, - .enable_irq = softingcs_enable_irq, -}, { - .name = "Vector-CANcard-2", - .manf = 0x0168, .prod = 0x085, - .generation = 2, - .nbus = 2, - .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, - .dpram_size = 0x1000, - .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, - .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, - .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, - .reset = softingcs_reset, - .enable_irq = NULL, -}, { - .name = "EDICcard-NEC", - .manf = 0x0168, .prod = 0x102, - .generation = 1, - .nbus = 2, - .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, - .dpram_size = 0x0800, - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, - .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, - .reset = softingcs_reset, - .enable_irq = softingcs_enable_irq, -}, { - .name = "EDICcard-2", - .manf = 0x0168, .prod = 0x105, - .generation = 2, - .nbus = 2, - .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, - .dpram_size = 0x1000, - .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, - .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, - .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, - .reset = softingcs_reset, - .enable_irq = NULL, -}, { - 0, 0, -}, -}; - -MODULE_FIRMWARE(fw_dir "bcard.bin"); -MODULE_FIRMWARE(fw_dir "ldcard.bin"); -MODULE_FIRMWARE(fw_dir "cancard.bin"); -MODULE_FIRMWARE(fw_dir "cansja.bin"); - -MODULE_FIRMWARE(fw_dir "bcard2.bin"); -MODULE_FIRMWARE(fw_dir "ldcard2.bin"); -MODULE_FIRMWARE(fw_dir "cancrd2.bin"); - -static const struct softing_platform_data -*softingcs_find_platform_data(unsigned int manf, unsigned int prod) -{ - const struct softing_platform_data *lp; - - for (lp = softingcs_platform_data; lp->manf; ++lp) { - if ((lp->manf == manf) && (lp->prod == prod)) - return lp; - } - return NULL; -} - -/* - * platformdata callbacks - */ -static int softingcs_reset(struct platform_device *pdev, int v) -{ - struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); - - dev_dbg(&pdev->dev, "pcmcia config [2] %02x\n", v ? 0 : 0x20); - return pcmcia_write_config_byte(pcmcia, 2, v ? 0 : 0x20); -} - -static int softingcs_enable_irq(struct platform_device *pdev, int v) -{ - struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); - - dev_dbg(&pdev->dev, "pcmcia config [0] %02x\n", v ? 0x60 : 0); - return pcmcia_write_config_byte(pcmcia, 0, v ? 0x60 : 0); -} - -/* - * pcmcia check - */ -static int softingcs_probe_config(struct pcmcia_device *pcmcia, void *priv_data) -{ - struct softing_platform_data *pdat = priv_data; - struct resource *pres; - int memspeed = 0; - - WARN_ON(!pdat); - pres = pcmcia->resource[PCMCIA_IOMEM_0]; - if (resource_size(pres) < 0x1000) - return -ERANGE; - - pres->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE; - if (pdat->generation < 2) { - pres->flags |= WIN_USE_WAIT | WIN_DATA_WIDTH_8; - memspeed = 3; - } else { - pres->flags |= WIN_DATA_WIDTH_16; - } - return pcmcia_request_window(pcmcia, pres, memspeed); -} - -static void softingcs_remove(struct pcmcia_device *pcmcia) -{ - struct platform_device *pdev = pcmcia->priv; - - /* free bits */ - platform_device_unregister(pdev); - /* release pcmcia stuff */ - pcmcia_disable_device(pcmcia); -} - -/* - * platform_device wrapper - * pdev->resource has 2 entries: io & irq - */ -static void softingcs_pdev_release(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - kfree(pdev); -} - -static int softingcs_probe(struct pcmcia_device *pcmcia) -{ - int ret; - struct platform_device *pdev; - const struct softing_platform_data *pdat; - struct resource *pres; - struct dev { - struct platform_device pdev; - struct resource res[2]; - } *dev; - - /* find matching platform_data */ - pdat = softingcs_find_platform_data(pcmcia->manf_id, pcmcia->card_id); - if (!pdat) - return -ENOTTY; - - /* setup pcmcia device */ - pcmcia->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IOMEM | - CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC; - ret = pcmcia_loop_config(pcmcia, softingcs_probe_config, (void *)pdat); - if (ret) - goto pcmcia_failed; - - ret = pcmcia_enable_device(pcmcia); - if (ret < 0) - goto pcmcia_failed; - - pres = pcmcia->resource[PCMCIA_IOMEM_0]; - if (!pres) { - ret = -EBADF; - goto pcmcia_bad; - } - - /* create softing platform device */ - dev = kzalloc_obj(*dev); - if (!dev) { - ret = -ENOMEM; - goto mem_failed; - } - dev->pdev.resource = dev->res; - dev->pdev.num_resources = ARRAY_SIZE(dev->res); - dev->pdev.dev.release = softingcs_pdev_release; - - pdev = &dev->pdev; - pdev->dev.platform_data = (void *)pdat; - pdev->dev.parent = &pcmcia->dev; - pcmcia->priv = pdev; - - /* platform device resources */ - pdev->resource[0].flags = IORESOURCE_MEM; - pdev->resource[0].start = pres->start; - pdev->resource[0].end = pres->end; - - pdev->resource[1].flags = IORESOURCE_IRQ; - pdev->resource[1].start = pcmcia->irq; - pdev->resource[1].end = pdev->resource[1].start; - - /* platform device setup */ - spin_lock(&softingcs_index_lock); - pdev->id = softingcs_index++; - spin_unlock(&softingcs_index_lock); - pdev->name = "softing"; - dev_set_name(&pdev->dev, "softingcs.%i", pdev->id); - ret = platform_device_register(pdev); - if (ret < 0) - goto platform_failed; - - dev_info(&pcmcia->dev, "created %s\n", dev_name(&pdev->dev)); - return 0; - -platform_failed: - platform_device_put(pdev); -mem_failed: -pcmcia_bad: -pcmcia_failed: - pcmcia_disable_device(pcmcia); - pcmcia->priv = NULL; - return ret; -} - -static const struct pcmcia_device_id softingcs_ids[] = { - /* softing */ - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0001), - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0002), - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0004), - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0005), - /* vector, manufacturer? */ - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0081), - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0084), - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0085), - /* EDIC */ - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0102), - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0105), - PCMCIA_DEVICE_NULL, -}; - -MODULE_DEVICE_TABLE(pcmcia, softingcs_ids); - -static struct pcmcia_driver softingcs_driver = { - .owner = THIS_MODULE, - .name = "softingcs", - .id_table = softingcs_ids, - .probe = softingcs_probe, - .remove = softingcs_remove, -}; - -module_pcmcia_driver(softingcs_driver); - -MODULE_DESCRIPTION("softing CANcard driver" - ", links PCMCIA card to softing driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c deleted file mode 100644 index 282570daf3ef..000000000000 --- a/drivers/net/can/softing/softing_fw.c +++ /dev/null @@ -1,700 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2008-2010 - * - * - Kurt Van Dijck, EIA Electronics - */ - -#include <linux/firmware.h> -#include <linux/sched/signal.h> -#include <asm/div64.h> -#include <asm/io.h> - -#include "softing.h" - -/* - * low level DPRAM command. - * Make sure that card->dpram[DPRAM_FCT_HOST] is preset - */ -static int _softing_fct_cmd(struct softing *card, int16_t cmd, uint16_t vector, - const char *msg) -{ - int ret; - unsigned long stamp; - - iowrite16(cmd, &card->dpram[DPRAM_FCT_PARAM]); - iowrite8(vector >> 8, &card->dpram[DPRAM_FCT_HOST + 1]); - iowrite8(vector, &card->dpram[DPRAM_FCT_HOST]); - /* be sure to flush this to the card */ - wmb(); - stamp = jiffies + 1 * HZ; - /* wait for card */ - do { - /* DPRAM_FCT_HOST is _not_ aligned */ - ret = ioread8(&card->dpram[DPRAM_FCT_HOST]) + - (ioread8(&card->dpram[DPRAM_FCT_HOST + 1]) << 8); - /* don't have any cached variables */ - rmb(); - if (ret == RES_OK) - /* read return-value now */ - return ioread16(&card->dpram[DPRAM_FCT_RESULT]); - - if ((ret != vector) || time_after(jiffies, stamp)) - break; - /* process context => relax */ - usleep_range(500, 10000); - } while (1); - - ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; - dev_alert(&card->pdev->dev, "firmware %s failed (%i)\n", msg, ret); - return ret; -} - -static int softing_fct_cmd(struct softing *card, int16_t cmd, const char *msg) -{ - int ret; - - ret = _softing_fct_cmd(card, cmd, 0, msg); - if (ret > 0) { - dev_alert(&card->pdev->dev, "%s returned %u\n", msg, ret); - ret = -EIO; - } - return ret; -} - -int softing_bootloader_command(struct softing *card, int16_t cmd, - const char *msg) -{ - int ret; - unsigned long stamp; - - iowrite16(RES_NONE, &card->dpram[DPRAM_RECEIPT]); - iowrite16(cmd, &card->dpram[DPRAM_COMMAND]); - /* be sure to flush this to the card */ - wmb(); - stamp = jiffies + 3 * HZ; - /* wait for card */ - do { - ret = ioread16(&card->dpram[DPRAM_RECEIPT]); - /* don't have any cached variables */ - rmb(); - if (ret == RES_OK) - return 0; - if (time_after(jiffies, stamp)) - break; - /* process context => relax */ - usleep_range(500, 10000); - } while (!signal_pending(current)); - - ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; - dev_alert(&card->pdev->dev, "bootloader %s failed (%i)\n", msg, ret); - return ret; -} - -static int fw_parse(const u8 **pmem, const u8 *limit, u16 *ptype, - u32 *paddr, u16 *plen, const u8 **pdat) -{ - uint16_t checksum[2]; - const u8 *mem; - const u8 *record_end; - - /* - * firmware records are a binary, unaligned stream composed of: - * uint16_t type; - * uint32_t addr; - * uint16_t len; - * uint8_t dat[len]; - * uint16_t checksum; - * all values in little endian. - * We could define a struct for this, with __attribute__((packed)), - * but would that solve the alignment in _all_ cases (cfr. the - * struct itself may be an odd address)? - * - * I chose to use leXX_to_cpup() since this solves both - * endianness & alignment. - */ - mem = *pmem; - /* A record needs an 8-byte prefix and a 2-byte checksum. */ - if (mem > limit || limit - mem < 10) - return -EINVAL; - - *ptype = le16_to_cpup((void *)&mem[0]); - *paddr = le32_to_cpup((void *)&mem[2]); - *plen = le16_to_cpup((void *)&mem[6]); - if (*plen > limit - mem - 10) - return -EINVAL; - - *pdat = &mem[8]; - /* verify checksum */ - record_end = &mem[8 + *plen]; - checksum[0] = le16_to_cpup((void *)record_end); - for (checksum[1] = 0; mem < record_end; ++mem) - checksum[1] += *mem; - if (checksum[0] != checksum[1]) - return -EINVAL; - /* increment */ - *pmem += 10 + *plen; - return 0; -} - -int softing_load_fw(const char *file, struct softing *card, - __iomem uint8_t *dpram, unsigned int size, int offset) -{ - const struct firmware *fw; - int ret; - const uint8_t *mem, *end, *dat; - uint16_t type, len; - uint32_t addr; - uint8_t *buf = NULL, *new_buf; - s64 dpram_offset; - int buflen = 0; - int8_t type_end = 0; - - ret = request_firmware(&fw, file, &card->pdev->dev); - if (ret < 0) - return ret; - dev_dbg(&card->pdev->dev, "%s, firmware(%s) got %u bytes" - ", offset %c0x%04x\n", - card->pdat->name, file, (unsigned int)fw->size, - (offset >= 0) ? '+' : '-', (unsigned int)abs(offset)); - /* parse the firmware */ - mem = fw->data; - end = &mem[fw->size]; - /* look for header record */ - ret = fw_parse(&mem, end, &type, &addr, &len, &dat); - if (ret < 0) - goto failed; - if (type != 0xffff) - goto failed; - if (strncmp("Structured Binary Format, Softing GmbH" , dat, len)) { - ret = -EINVAL; - goto failed; - } - /* ok, we had a header */ - while (mem < end) { - ret = fw_parse(&mem, end, &type, &addr, &len, &dat); - if (ret < 0) - goto failed; - if (type == 3) { - /* start address, not used here */ - continue; - } else if (type == 1) { - /* eof */ - type_end = 1; - break; - } else if (type != 0) { - ret = -EINVAL; - goto failed; - } - - dpram_offset = (s64)addr + offset; - if (dpram_offset < 0 || dpram_offset > size || - len > size - dpram_offset) { - ret = -EINVAL; - goto failed; - } - memcpy_toio(&dpram[dpram_offset], dat, len); - /* be sure to flush caches from IO space */ - mb(); - if (len > buflen) { - /* align buflen */ - buflen = (len + (1024-1)) & ~(1024-1); - new_buf = krealloc(buf, buflen, GFP_KERNEL); - if (!new_buf) { - ret = -ENOMEM; - goto failed; - } - buf = new_buf; - } - /* verify record data */ - memcpy_fromio(buf, &dpram[dpram_offset], len); - if (memcmp(buf, dat, len)) { - /* is not ok */ - dev_alert(&card->pdev->dev, "DPRAM readback failed\n"); - ret = -EIO; - goto failed; - } - } - if (!type_end) - /* no end record seen */ - goto failed; - ret = 0; -failed: - kfree(buf); - release_firmware(fw); - if (ret < 0) - dev_info(&card->pdev->dev, "firmware %s failed\n", file); - return ret; -} - -int softing_load_app_fw(const char *file, struct softing *card) -{ - const struct firmware *fw; - const uint8_t *mem, *end, *dat; - int ret, j; - uint16_t type, len; - uint32_t addr, start_addr = 0; - unsigned int sum, rx_sum; - int8_t type_end = 0, type_entrypoint = 0; - - ret = request_firmware(&fw, file, &card->pdev->dev); - if (ret) { - dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n", - file, ret); - return ret; - } - dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n", - file, (unsigned long)fw->size); - /* parse the firmware */ - mem = fw->data; - end = &mem[fw->size]; - /* look for header record */ - ret = fw_parse(&mem, end, &type, &addr, &len, &dat); - if (ret) - goto failed; - ret = -EINVAL; - if (type != 0xffff) { - dev_alert(&card->pdev->dev, "firmware starts with type 0x%x\n", - type); - goto failed; - } - if (strncmp("Structured Binary Format, Softing GmbH", dat, len)) { - dev_alert(&card->pdev->dev, "firmware string '%.*s' fault\n", - len, dat); - goto failed; - } - /* ok, we had a header */ - while (mem < end) { - ret = fw_parse(&mem, end, &type, &addr, &len, &dat); - if (ret) - goto failed; - - if (type == 3) { - /* start address */ - start_addr = addr; - type_entrypoint = 1; - continue; - } else if (type == 1) { - /* eof */ - type_end = 1; - break; - } else if (type != 0) { - dev_alert(&card->pdev->dev, - "unknown record type 0x%04x\n", type); - ret = -EINVAL; - goto failed; - } - - /* regular data */ - for (sum = 0, j = 0; j < len; ++j) - sum += dat[j]; - /* work in 16bit (target) */ - sum &= 0xffff; - - if (card->pdat->app.offs > card->dpram_size || - len > card->dpram_size - card->pdat->app.offs) { - ret = -EINVAL; - goto failed; - } - - memcpy_toio(&card->dpram[card->pdat->app.offs], dat, len); - iowrite32(card->pdat->app.offs + card->pdat->app.addr, - &card->dpram[DPRAM_COMMAND + 2]); - iowrite32(addr, &card->dpram[DPRAM_COMMAND + 6]); - iowrite16(len, &card->dpram[DPRAM_COMMAND + 10]); - iowrite8(1, &card->dpram[DPRAM_COMMAND + 12]); - ret = softing_bootloader_command(card, 1, "loading app."); - if (ret < 0) - goto failed; - /* verify checksum */ - rx_sum = ioread16(&card->dpram[DPRAM_RECEIPT + 2]); - if (rx_sum != sum) { - dev_alert(&card->pdev->dev, "SRAM seems to be damaged" - ", wanted 0x%04x, got 0x%04x\n", sum, rx_sum); - ret = -EIO; - goto failed; - } - } - if (!type_end || !type_entrypoint) - goto failed; - /* start application in card */ - iowrite32(start_addr, &card->dpram[DPRAM_COMMAND + 2]); - iowrite8(1, &card->dpram[DPRAM_COMMAND + 6]); - ret = softing_bootloader_command(card, 3, "start app."); - if (ret < 0) - goto failed; - ret = 0; -failed: - release_firmware(fw); - if (ret < 0) - dev_info(&card->pdev->dev, "firmware %s failed\n", file); - return ret; -} - -static int softing_reset_chip(struct softing *card) -{ - int ret; - - do { - /* reset chip */ - iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO]); - iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO+1]); - iowrite8(1, &card->dpram[DPRAM_RESET]); - iowrite8(0, &card->dpram[DPRAM_RESET+1]); - - ret = softing_fct_cmd(card, 0, "reset_can"); - if (!ret) - break; - if (signal_pending(current)) - /* don't wait any longer */ - break; - } while (1); - card->tx.pending = 0; - return ret; -} - -int softing_chip_poweron(struct softing *card) -{ - int ret; - /* sync */ - ret = _softing_fct_cmd(card, 99, 0x55, "sync-a"); - if (ret < 0) - goto failed; - - ret = _softing_fct_cmd(card, 99, 0xaa, "sync-b"); - if (ret < 0) - goto failed; - - ret = softing_reset_chip(card); - if (ret < 0) - goto failed; - /* get_serial */ - ret = softing_fct_cmd(card, 43, "get_serial_number"); - if (ret < 0) - goto failed; - card->id.serial = ioread32(&card->dpram[DPRAM_FCT_PARAM]); - /* get_version */ - ret = softing_fct_cmd(card, 12, "get_version"); - if (ret < 0) - goto failed; - card->id.fw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 2]); - card->id.hw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 4]); - card->id.license = ioread16(&card->dpram[DPRAM_FCT_PARAM + 6]); - card->id.chip[0] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 8]); - card->id.chip[1] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 10]); - return 0; -failed: - return ret; -} - -static void softing_initialize_timestamp(struct softing *card) -{ - uint64_t ovf; - - card->ts_ref = ktime_get(); - - /* 16MHz is the reference */ - ovf = 0x100000000ULL * 16; - do_div(ovf, card->pdat->freq ?: 16); - - card->ts_overflow = ktime_add_us(0, ovf); -} - -ktime_t softing_raw2ktime(struct softing *card, u32 raw) -{ - uint64_t rawl; - ktime_t now, real_offset; - ktime_t target; - ktime_t tmp; - - now = ktime_get(); - real_offset = ktime_sub(ktime_get_real(), now); - - /* find nsec from card */ - rawl = raw * 16; - do_div(rawl, card->pdat->freq ?: 16); - target = ktime_add_us(card->ts_ref, rawl); - /* test for overflows */ - tmp = ktime_add(target, card->ts_overflow); - while (unlikely(ktime_to_ns(tmp) > ktime_to_ns(now))) { - card->ts_ref = ktime_add(card->ts_ref, card->ts_overflow); - target = tmp; - tmp = ktime_add(target, card->ts_overflow); - } - return ktime_add(target, real_offset); -} - -static inline int softing_error_reporting(struct net_device *netdev) -{ - struct softing_priv *priv = netdev_priv(netdev); - - return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) - ? 1 : 0; -} - -int softing_startstop(struct net_device *dev, int up) -{ - int ret; - struct softing *card; - struct softing_priv *priv; - struct net_device *netdev; - int bus_bitmask_start; - int j, error_reporting; - struct can_frame msg; - const struct can_bittiming *bt; - - priv = netdev_priv(dev); - card = priv->card; - - if (!card->fw.up) - return -EIO; - - ret = mutex_lock_interruptible(&card->fw.lock); - if (ret) - return ret; - - bus_bitmask_start = 0; - if (up) - /* prepare to start this bus as well */ - bus_bitmask_start |= (1 << priv->index); - /* bring netdevs down */ - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { - netdev = card->net[j]; - if (!netdev) - continue; - priv = netdev_priv(netdev); - - if (dev != netdev) - netif_stop_queue(netdev); - - if (netif_running(netdev)) { - if (dev != netdev) - bus_bitmask_start |= (1 << j); - priv->tx.pending = 0; - priv->tx.echo_put = 0; - priv->tx.echo_get = 0; - /* - * this bus' may just have called open_candev() - * which is rather stupid to call close_candev() - * already - * but we may come here from busoff recovery too - * in which case the echo_skb _needs_ flushing too. - * just be sure to call open_candev() again - */ - close_candev(netdev); - } - priv->can.state = CAN_STATE_STOPPED; - } - card->tx.pending = 0; - - softing_enable_irq(card, 0); - ret = softing_reset_chip(card); - if (ret) - goto failed; - if (!bus_bitmask_start) - /* no buses to be brought up */ - goto card_done; - - if ((bus_bitmask_start & 1) && (bus_bitmask_start & 2) - && (softing_error_reporting(card->net[0]) - != softing_error_reporting(card->net[1]))) { - dev_alert(&card->pdev->dev, - "err_reporting flag differs for buses\n"); - goto invalid; - } - error_reporting = 0; - if (bus_bitmask_start & 1) { - netdev = card->net[0]; - priv = netdev_priv(netdev); - error_reporting += softing_error_reporting(netdev); - /* init chip 1 */ - bt = &priv->can.bittiming; - iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); - iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); - iowrite16(bt->phase_seg1 + bt->prop_seg, - &card->dpram[DPRAM_FCT_PARAM + 6]); - iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); - iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, - &card->dpram[DPRAM_FCT_PARAM + 10]); - ret = softing_fct_cmd(card, 1, "initialize_chip[0]"); - if (ret < 0) - goto failed; - /* set mode */ - iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); - iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); - ret = softing_fct_cmd(card, 3, "set_mode[0]"); - if (ret < 0) - goto failed; - /* set filter */ - /* 11bit id & mask */ - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); - iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); - /* 29bit id.lo & mask.lo & id.hi & mask.hi */ - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); - iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); - iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); - ret = softing_fct_cmd(card, 7, "set_filter[0]"); - if (ret < 0) - goto failed; - /* set output control */ - iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); - ret = softing_fct_cmd(card, 5, "set_output[0]"); - if (ret < 0) - goto failed; - } - if (bus_bitmask_start & 2) { - netdev = card->net[1]; - priv = netdev_priv(netdev); - error_reporting += softing_error_reporting(netdev); - /* init chip2 */ - bt = &priv->can.bittiming; - iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); - iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); - iowrite16(bt->phase_seg1 + bt->prop_seg, - &card->dpram[DPRAM_FCT_PARAM + 6]); - iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); - iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, - &card->dpram[DPRAM_FCT_PARAM + 10]); - ret = softing_fct_cmd(card, 2, "initialize_chip[1]"); - if (ret < 0) - goto failed; - /* set mode2 */ - iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); - iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); - ret = softing_fct_cmd(card, 4, "set_mode[1]"); - if (ret < 0) - goto failed; - /* set filter2 */ - /* 11bit id & mask */ - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); - iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); - /* 29bit id.lo & mask.lo & id.hi & mask.hi */ - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); - iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); - iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); - ret = softing_fct_cmd(card, 8, "set_filter[1]"); - if (ret < 0) - goto failed; - /* set output control2 */ - iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); - ret = softing_fct_cmd(card, 6, "set_output[1]"); - if (ret < 0) - goto failed; - } - - /* enable_error_frame - * - * Error reporting is switched off at the moment since - * the receiving of them is not yet 100% verified - * This should be enabled sooner or later - */ - if (0 && error_reporting) { - ret = softing_fct_cmd(card, 51, "enable_error_frame"); - if (ret < 0) - goto failed; - } - - /* initialize interface */ - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 2]); - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 4]); - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 6]); - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 8]); - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 10]); - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 12]); - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 14]); - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 16]); - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 18]); - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 20]); - ret = softing_fct_cmd(card, 17, "initialize_interface"); - if (ret < 0) - goto failed; - /* enable_fifo */ - ret = softing_fct_cmd(card, 36, "enable_fifo"); - if (ret < 0) - goto failed; - /* enable fifo tx ack */ - ret = softing_fct_cmd(card, 13, "fifo_tx_ack[0]"); - if (ret < 0) - goto failed; - /* enable fifo tx ack2 */ - ret = softing_fct_cmd(card, 14, "fifo_tx_ack[1]"); - if (ret < 0) - goto failed; - /* start_chip */ - ret = softing_fct_cmd(card, 11, "start_chip"); - if (ret < 0) - goto failed; - iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE]); - iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE2]); - if (card->pdat->generation < 2) { - iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]); - /* flush the DPRAM caches */ - wmb(); - } - - softing_initialize_timestamp(card); - - /* - * do socketcan notifications/status changes - * from here, no errors should occur, or the failed: part - * must be reviewed - */ - memset(&msg, 0, sizeof(msg)); - msg.can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED; - msg.len = CAN_ERR_DLC; - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { - if (!(bus_bitmask_start & (1 << j))) - continue; - netdev = card->net[j]; - if (!netdev) - continue; - priv = netdev_priv(netdev); - priv->can.state = CAN_STATE_ERROR_ACTIVE; - open_candev(netdev); - if (dev != netdev) { - /* notify other buses on the restart */ - softing_netdev_rx(netdev, &msg, 0); - ++priv->can.can_stats.restarts; - } - netif_wake_queue(netdev); - } - - /* enable interrupts */ - ret = softing_enable_irq(card, 1); - if (ret) - goto failed; -card_done: - mutex_unlock(&card->fw.lock); - return 0; -invalid: - ret = -EINVAL; -failed: - softing_enable_irq(card, 0); - softing_reset_chip(card); - mutex_unlock(&card->fw.lock); - /* bring all other interfaces down */ - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { - netdev = card->net[j]; - if (!netdev) - continue; - dev_close(netdev); - } - return ret; -} - -int softing_default_output(struct net_device *netdev) -{ - struct softing_priv *priv = netdev_priv(netdev); - struct softing *card = priv->card; - - switch (priv->chip) { - case 1000: - return (card->pdat->generation < 2) ? 0xfb : 0xfa; - case 5: - return 0x60; - default: - return 0x40; - } -} diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c deleted file mode 100644 index 519ab3097f86..000000000000 --- a/drivers/net/can/softing/softing_main.c +++ /dev/null @@ -1,864 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2008-2010 - * - * - Kurt Van Dijck, EIA Electronics - */ - -#include <linux/ethtool.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <asm/io.h> - -#include "softing.h" - -#define TX_ECHO_SKB_MAX (((TXMAX+1)/2)-1) - -/* - * test is a specific CAN netdev - * is online (ie. up 'n running, not sleeping, not busoff - */ -static inline int canif_is_active(struct net_device *netdev) -{ - struct can_priv *can = netdev_priv(netdev); - - if (!netif_running(netdev)) - return 0; - return (can->state <= CAN_STATE_ERROR_PASSIVE); -} - -/* reset DPRAM */ -static inline void softing_set_reset_dpram(struct softing *card) -{ - if (card->pdat->generation >= 2) { - spin_lock_bh(&card->spin); - iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) & ~1, - &card->dpram[DPRAM_V2_RESET]); - spin_unlock_bh(&card->spin); - } -} - -static inline void softing_clr_reset_dpram(struct softing *card) -{ - if (card->pdat->generation >= 2) { - spin_lock_bh(&card->spin); - iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) | 1, - &card->dpram[DPRAM_V2_RESET]); - spin_unlock_bh(&card->spin); - } -} - -/* trigger the tx queue-ing */ -static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - struct softing_priv *priv = netdev_priv(dev); - struct softing *card = priv->card; - int ret; - uint8_t *ptr; - uint8_t fifo_wr, fifo_rd; - struct can_frame *cf = (struct can_frame *)skb->data; - uint8_t buf[DPRAM_TX_SIZE]; - - if (can_dev_dropped_skb(dev, skb)) - return NETDEV_TX_OK; - - spin_lock(&card->spin); - - ret = NETDEV_TX_BUSY; - if (!card->fw.up || - (card->tx.pending >= TXMAX) || - (priv->tx.pending >= TX_ECHO_SKB_MAX)) - goto xmit_done; - fifo_wr = ioread8(&card->dpram[DPRAM_TX_WR]); - fifo_rd = ioread8(&card->dpram[DPRAM_TX_RD]); - if (fifo_wr == fifo_rd) - /* fifo full */ - goto xmit_done; - memset(buf, 0, sizeof(buf)); - ptr = buf; - *ptr = CMD_TX; - if (cf->can_id & CAN_RTR_FLAG) - *ptr |= CMD_RTR; - if (cf->can_id & CAN_EFF_FLAG) - *ptr |= CMD_XTD; - if (priv->index) - *ptr |= CMD_BUS2; - ++ptr; - *ptr++ = cf->len; - *ptr++ = (cf->can_id >> 0); - *ptr++ = (cf->can_id >> 8); - if (cf->can_id & CAN_EFF_FLAG) { - *ptr++ = (cf->can_id >> 16); - *ptr++ = (cf->can_id >> 24); - } else { - /* increment 1, not 2 as you might think */ - ptr += 1; - } - if (!(cf->can_id & CAN_RTR_FLAG)) - memcpy(ptr, &cf->data[0], cf->len); - memcpy_toio(&card->dpram[DPRAM_TX + DPRAM_TX_SIZE * fifo_wr], - buf, DPRAM_TX_SIZE); - if (++fifo_wr >= DPRAM_TX_CNT) - fifo_wr = 0; - iowrite8(fifo_wr, &card->dpram[DPRAM_TX_WR]); - card->tx.last_bus = priv->index; - ++card->tx.pending; - ++priv->tx.pending; - can_put_echo_skb(skb, dev, priv->tx.echo_put, 0); - ++priv->tx.echo_put; - if (priv->tx.echo_put >= TX_ECHO_SKB_MAX) - priv->tx.echo_put = 0; - /* can_put_echo_skb() saves the skb, safe to return TX_OK */ - ret = NETDEV_TX_OK; -xmit_done: - spin_unlock(&card->spin); - if (card->tx.pending >= TXMAX) { - int j; - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { - if (card->net[j]) - netif_stop_queue(card->net[j]); - } - } - if (ret != NETDEV_TX_OK) - netif_stop_queue(dev); - - return ret; -} - -/* - * shortcut for skb delivery - */ -int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg, - ktime_t ktime) -{ - struct sk_buff *skb; - struct can_frame *cf; - - skb = alloc_can_skb(netdev, &cf); - if (!skb) - return -ENOMEM; - memcpy(cf, msg, sizeof(*msg)); - skb->tstamp = ktime; - return netif_rx(skb); -} - -/* - * softing_handle_1 - * pop 1 entry from the DPRAM queue, and process - */ -static int softing_handle_1(struct softing *card) -{ - struct net_device *netdev; - struct softing_priv *priv; - ktime_t ktime; - struct can_frame msg; - int cnt = 0, lost_msg; - uint8_t fifo_rd, fifo_wr, cmd; - uint8_t *ptr; - uint32_t tmp_u32; - uint8_t buf[DPRAM_RX_SIZE]; - - memset(&msg, 0, sizeof(msg)); - /* test for lost msgs */ - lost_msg = ioread8(&card->dpram[DPRAM_RX_LOST]); - if (lost_msg) { - int j; - /* reset condition */ - iowrite8(0, &card->dpram[DPRAM_RX_LOST]); - /* prepare msg */ - msg.can_id = CAN_ERR_FLAG | CAN_ERR_CRTL; - msg.len = CAN_ERR_DLC; - msg.data[1] = CAN_ERR_CRTL_RX_OVERFLOW; - /* - * service to all buses, we don't know which it was applicable - * but only service buses that are online - */ - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { - netdev = card->net[j]; - if (!netdev) - continue; - if (!canif_is_active(netdev)) - /* a dead bus has no overflows */ - continue; - ++netdev->stats.rx_over_errors; - softing_netdev_rx(netdev, &msg, 0); - } - /* prepare for other use */ - memset(&msg, 0, sizeof(msg)); - ++cnt; - } - - fifo_rd = ioread8(&card->dpram[DPRAM_RX_RD]); - fifo_wr = ioread8(&card->dpram[DPRAM_RX_WR]); - - if (++fifo_rd >= DPRAM_RX_CNT) - fifo_rd = 0; - if (fifo_wr == fifo_rd) - return cnt; - - memcpy_fromio(buf, &card->dpram[DPRAM_RX + DPRAM_RX_SIZE*fifo_rd], - DPRAM_RX_SIZE); - mb(); - /* trigger dual port RAM */ - iowrite8(fifo_rd, &card->dpram[DPRAM_RX_RD]); - - ptr = buf; - cmd = *ptr++; - if (cmd == 0xff) - /* not quite useful, probably the card has got out */ - return 0; - netdev = card->net[0]; - if (cmd & CMD_BUS2) - netdev = card->net[1]; - priv = netdev_priv(netdev); - - if (cmd & CMD_ERR) { - uint8_t can_state, state; - - state = *ptr++; - - msg.can_id = CAN_ERR_FLAG; - msg.len = CAN_ERR_DLC; - - if (state & SF_MASK_BUSOFF) { - can_state = CAN_STATE_BUS_OFF; - msg.can_id |= CAN_ERR_BUSOFF; - state = STATE_BUSOFF; - } else if (state & SF_MASK_EPASSIVE) { - can_state = CAN_STATE_ERROR_PASSIVE; - msg.can_id |= CAN_ERR_CRTL; - msg.data[1] = CAN_ERR_CRTL_TX_PASSIVE; - state = STATE_EPASSIVE; - } else { - can_state = CAN_STATE_ERROR_ACTIVE; - msg.can_id |= CAN_ERR_CRTL; - state = STATE_EACTIVE; - } - /* update DPRAM */ - iowrite8(state, &card->dpram[priv->index ? - DPRAM_INFO_BUSSTATE2 : DPRAM_INFO_BUSSTATE]); - /* timestamp */ - tmp_u32 = le32_to_cpup((void *)ptr); - ktime = softing_raw2ktime(card, tmp_u32); - - ++netdev->stats.rx_errors; - /* update internal status */ - if (can_state != priv->can.state) { - priv->can.state = can_state; - if (can_state == CAN_STATE_ERROR_PASSIVE) - ++priv->can.can_stats.error_passive; - else if (can_state == CAN_STATE_BUS_OFF) { - /* this calls can_close_cleanup() */ - ++priv->can.can_stats.bus_off; - can_bus_off(netdev); - netif_stop_queue(netdev); - } - /* trigger socketcan */ - softing_netdev_rx(netdev, &msg, ktime); - } - - } else { - if (cmd & CMD_RTR) - msg.can_id |= CAN_RTR_FLAG; - msg.len = can_cc_dlc2len(*ptr++); - if (cmd & CMD_XTD) { - msg.can_id |= CAN_EFF_FLAG; - msg.can_id |= le32_to_cpup((void *)ptr); - ptr += 4; - } else { - msg.can_id |= le16_to_cpup((void *)ptr); - ptr += 2; - } - /* timestamp */ - tmp_u32 = le32_to_cpup((void *)ptr); - ptr += 4; - ktime = softing_raw2ktime(card, tmp_u32); - if (!(msg.can_id & CAN_RTR_FLAG)) - memcpy(&msg.data[0], ptr, 8); - /* update socket */ - if (cmd & CMD_ACK) { - /* acknowledge, was tx msg */ - struct sk_buff *skb; - skb = priv->can.echo_skb[priv->tx.echo_get]; - if (skb) - skb->tstamp = ktime; - ++netdev->stats.tx_packets; - netdev->stats.tx_bytes += - can_get_echo_skb(netdev, priv->tx.echo_get, - NULL); - ++priv->tx.echo_get; - if (priv->tx.echo_get >= TX_ECHO_SKB_MAX) - priv->tx.echo_get = 0; - if (priv->tx.pending) - --priv->tx.pending; - if (card->tx.pending) - --card->tx.pending; - } else { - int ret; - - ret = softing_netdev_rx(netdev, &msg, ktime); - if (ret == NET_RX_SUCCESS) { - ++netdev->stats.rx_packets; - if (!(msg.can_id & CAN_RTR_FLAG)) - netdev->stats.rx_bytes += msg.len; - } else { - ++netdev->stats.rx_dropped; - } - } - } - ++cnt; - return cnt; -} - -/* - * real interrupt handler - */ -static irqreturn_t softing_irq_thread(int irq, void *dev_id) -{ - struct softing *card = (struct softing *)dev_id; - struct net_device *netdev; - struct softing_priv *priv; - int j, offset, work_done; - - work_done = 0; - spin_lock_bh(&card->spin); - while (softing_handle_1(card) > 0) { - ++card->irq.svc_count; - ++work_done; - } - spin_unlock_bh(&card->spin); - /* resume tx queue's */ - offset = card->tx.last_bus; - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { - if (card->tx.pending >= TXMAX) - break; - netdev = card->net[(j + offset + 1) % card->pdat->nbus]; - if (!netdev) - continue; - priv = netdev_priv(netdev); - if (!canif_is_active(netdev)) - /* it makes no sense to wake dead buses */ - continue; - if (priv->tx.pending >= TX_ECHO_SKB_MAX) - continue; - ++work_done; - netif_wake_queue(netdev); - } - return work_done ? IRQ_HANDLED : IRQ_NONE; -} - -/* - * interrupt routines: - * schedule the 'real interrupt handler' - */ -static irqreturn_t softing_irq_v2(int irq, void *dev_id) -{ - struct softing *card = (struct softing *)dev_id; - uint8_t ir; - - ir = ioread8(&card->dpram[DPRAM_V2_IRQ_TOHOST]); - iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]); - return (1 == ir) ? IRQ_WAKE_THREAD : IRQ_NONE; -} - -static irqreturn_t softing_irq_v1(int irq, void *dev_id) -{ - struct softing *card = (struct softing *)dev_id; - uint8_t ir; - - ir = ioread8(&card->dpram[DPRAM_IRQ_TOHOST]); - iowrite8(0, &card->dpram[DPRAM_IRQ_TOHOST]); - return ir ? IRQ_WAKE_THREAD : IRQ_NONE; -} - -/* - * netdev/candev interoperability - */ -static int softing_netdev_open(struct net_device *ndev) -{ - int ret; - - /* check or determine and set bittime */ - ret = open_candev(ndev); - if (ret) - return ret; - - ret = softing_startstop(ndev, 1); - if (ret < 0) - close_candev(ndev); - - return ret; -} - -static int softing_netdev_stop(struct net_device *ndev) -{ - netif_stop_queue(ndev); - - /* softing cycle does close_candev() */ - return softing_startstop(ndev, 0); -} - -static int softing_candev_set_mode(struct net_device *ndev, enum can_mode mode) -{ - int ret; - - switch (mode) { - case CAN_MODE_START: - /* softing_startstop does close_candev() */ - ret = softing_startstop(ndev, 1); - return ret; - case CAN_MODE_STOP: - case CAN_MODE_SLEEP: - return -EOPNOTSUPP; - } - return 0; -} - -/* - * Softing device management helpers - */ -int softing_enable_irq(struct softing *card, int enable) -{ - int ret; - - if (!card->irq.nr) { - return 0; - } else if (card->irq.requested && !enable) { - free_irq(card->irq.nr, card); - card->irq.requested = 0; - } else if (!card->irq.requested && enable) { - ret = request_threaded_irq(card->irq.nr, - (card->pdat->generation >= 2) ? - softing_irq_v2 : softing_irq_v1, - softing_irq_thread, IRQF_SHARED, - dev_name(&card->pdev->dev), card); - if (ret) { - dev_alert(&card->pdev->dev, - "request_threaded_irq(%u) failed\n", - card->irq.nr); - return ret; - } - card->irq.requested = 1; - } - return 0; -} - -static void softing_card_shutdown(struct softing *card) -{ - int fw_up = 0; - - if (mutex_lock_interruptible(&card->fw.lock)) { - /* return -ERESTARTSYS */; - } - fw_up = card->fw.up; - card->fw.up = 0; - - if (card->irq.requested && card->irq.nr) { - free_irq(card->irq.nr, card); - card->irq.requested = 0; - } - if (fw_up) { - if (card->pdat->enable_irq) - card->pdat->enable_irq(card->pdev, 0); - softing_set_reset_dpram(card); - if (card->pdat->reset) - card->pdat->reset(card->pdev, 1); - } - mutex_unlock(&card->fw.lock); -} - -static int softing_card_boot(struct softing *card) -{ - int ret, j; - static const uint8_t stream[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }; - unsigned char back[sizeof(stream)]; - - if (mutex_lock_interruptible(&card->fw.lock)) - return -ERESTARTSYS; - if (card->fw.up) { - mutex_unlock(&card->fw.lock); - return 0; - } - /* reset board */ - if (card->pdat->enable_irq) - card->pdat->enable_irq(card->pdev, 1); - /* boot card */ - softing_set_reset_dpram(card); - if (card->pdat->reset) - card->pdat->reset(card->pdev, 1); - for (j = 0; (j + sizeof(stream)) < card->dpram_size; - j += sizeof(stream)) { - - memcpy_toio(&card->dpram[j], stream, sizeof(stream)); - /* flush IO cache */ - mb(); - memcpy_fromio(back, &card->dpram[j], sizeof(stream)); - - if (!memcmp(back, stream, sizeof(stream))) - continue; - /* memory is not equal */ - dev_alert(&card->pdev->dev, "dpram failed at 0x%04x\n", j); - ret = -EIO; - goto failed; - } - wmb(); - /* load boot firmware */ - ret = softing_load_fw(card->pdat->boot.fw, card, card->dpram, - card->dpram_size, - card->pdat->boot.offs - card->pdat->boot.addr); - if (ret < 0) - goto failed; - /* load loader firmware */ - ret = softing_load_fw(card->pdat->load.fw, card, card->dpram, - card->dpram_size, - card->pdat->load.offs - card->pdat->load.addr); - if (ret < 0) - goto failed; - - if (card->pdat->reset) - card->pdat->reset(card->pdev, 0); - softing_clr_reset_dpram(card); - ret = softing_bootloader_command(card, 0, "card boot"); - if (ret < 0) - goto failed; - ret = softing_load_app_fw(card->pdat->app.fw, card); - if (ret < 0) - goto failed; - - ret = softing_chip_poweron(card); - if (ret < 0) - goto failed; - - card->fw.up = 1; - mutex_unlock(&card->fw.lock); - return 0; -failed: - card->fw.up = 0; - if (card->pdat->enable_irq) - card->pdat->enable_irq(card->pdev, 0); - softing_set_reset_dpram(card); - if (card->pdat->reset) - card->pdat->reset(card->pdev, 1); - mutex_unlock(&card->fw.lock); - return ret; -} - -/* - * netdev sysfs - */ -static ssize_t show_chip(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct net_device *ndev = to_net_dev(dev); - struct softing_priv *priv = netdev2softing(ndev); - - return sprintf(buf, "%i\n", priv->chip); -} - -static ssize_t show_output(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct net_device *ndev = to_net_dev(dev); - struct softing_priv *priv = netdev2softing(ndev); - - return sprintf(buf, "0x%02x\n", priv->output); -} - -static ssize_t store_output(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct net_device *ndev = to_net_dev(dev); - struct softing_priv *priv = netdev2softing(ndev); - struct softing *card = priv->card; - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - val &= 0xFF; - - ret = mutex_lock_interruptible(&card->fw.lock); - if (ret) - return -ERESTARTSYS; - if (netif_running(ndev)) { - mutex_unlock(&card->fw.lock); - return -EBUSY; - } - priv->output = val; - mutex_unlock(&card->fw.lock); - return count; -} - -static const DEVICE_ATTR(chip, 0444, show_chip, NULL); -static const DEVICE_ATTR(output, 0644, show_output, store_output); - -static const struct attribute *const netdev_sysfs_attrs[] = { - &dev_attr_chip.attr, - &dev_attr_output.attr, - NULL, -}; -static const struct attribute_group netdev_sysfs_group = { - .name = NULL, - .attrs = (struct attribute **)netdev_sysfs_attrs, -}; - -static const struct net_device_ops softing_netdev_ops = { - .ndo_open = softing_netdev_open, - .ndo_stop = softing_netdev_stop, - .ndo_start_xmit = softing_netdev_start_xmit, -}; - -static const struct ethtool_ops softing_ethtool_ops = { - .get_ts_info = ethtool_op_get_ts_info, -}; - -static const struct can_bittiming_const softing_btr_const = { - .name = KBUILD_MODNAME, - .tseg1_min = 1, - .tseg1_max = 16, - .tseg2_min = 1, - .tseg2_max = 8, - .sjw_max = 4, /* overruled */ - .brp_min = 1, - .brp_max = 32, /* overruled */ - .brp_inc = 1, -}; - - -static struct net_device *softing_netdev_create(struct softing *card, - uint16_t chip_id) -{ - struct net_device *netdev; - struct softing_priv *priv; - - netdev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX); - if (!netdev) { - dev_alert(&card->pdev->dev, "alloc_candev failed\n"); - return NULL; - } - priv = netdev_priv(netdev); - priv->netdev = netdev; - priv->card = card; - memcpy(&priv->btr_const, &softing_btr_const, sizeof(priv->btr_const)); - priv->btr_const.brp_max = card->pdat->max_brp; - priv->btr_const.sjw_max = card->pdat->max_sjw; - priv->can.bittiming_const = &priv->btr_const; - priv->can.clock.freq = 8000000; - priv->chip = chip_id; - priv->output = softing_default_output(netdev); - SET_NETDEV_DEV(netdev, &card->pdev->dev); - - netdev->flags |= IFF_ECHO; - netdev->netdev_ops = &softing_netdev_ops; - netdev->ethtool_ops = &softing_ethtool_ops; - priv->can.do_set_mode = softing_candev_set_mode; - priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; - - return netdev; -} - -static int softing_netdev_register(struct net_device *netdev) -{ - int ret; - - ret = register_candev(netdev); - if (ret) { - dev_alert(&netdev->dev, "register failed\n"); - return ret; - } - if (sysfs_create_group(&netdev->dev.kobj, &netdev_sysfs_group) < 0) - netdev_alert(netdev, "sysfs group failed\n"); - - return 0; -} - -static void softing_netdev_cleanup(struct net_device *netdev) -{ - sysfs_remove_group(&netdev->dev.kobj, &netdev_sysfs_group); - unregister_candev(netdev); - free_candev(netdev); -} - -/* - * sysfs for Platform device - */ -#define DEV_ATTR_RO(name, member) \ -static ssize_t show_##name(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct softing *card = dev_get_drvdata(dev); \ - return sprintf(buf, "%u\n", card->member); \ -} \ -static DEVICE_ATTR(name, 0444, show_##name, NULL) - -#define DEV_ATTR_RO_STR(name, member) \ -static ssize_t show_##name(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct softing *card = dev_get_drvdata(dev); \ - return sprintf(buf, "%s\n", card->member); \ -} \ -static DEVICE_ATTR(name, 0444, show_##name, NULL) - -DEV_ATTR_RO(serial, id.serial); -DEV_ATTR_RO_STR(firmware, pdat->app.fw); -DEV_ATTR_RO(firmware_version, id.fw_version); -DEV_ATTR_RO_STR(hardware, pdat->name); -DEV_ATTR_RO(hardware_version, id.hw_version); -DEV_ATTR_RO(license, id.license); - -static struct attribute *softing_pdev_attrs[] = { - &dev_attr_serial.attr, - &dev_attr_firmware.attr, - &dev_attr_firmware_version.attr, - &dev_attr_hardware.attr, - &dev_attr_hardware_version.attr, - &dev_attr_license.attr, - NULL, -}; - -static const struct attribute_group softing_pdev_group = { - .name = NULL, - .attrs = softing_pdev_attrs, -}; - -/* - * platform driver - */ -static void softing_pdev_remove(struct platform_device *pdev) -{ - struct softing *card = platform_get_drvdata(pdev); - int j; - - /* first, disable card*/ - softing_card_shutdown(card); - - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { - if (!card->net[j]) - continue; - softing_netdev_cleanup(card->net[j]); - card->net[j] = NULL; - } - sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group); - - iounmap(card->dpram); - kfree(card); -} - -static int softing_pdev_probe(struct platform_device *pdev) -{ - const struct softing_platform_data *pdat = dev_get_platdata(&pdev->dev); - struct softing *card; - struct net_device *netdev; - struct softing_priv *priv; - struct resource *pres; - int ret; - int j; - - if (!pdat) { - dev_warn(&pdev->dev, "no platform data\n"); - return -EINVAL; - } - if (pdat->nbus > ARRAY_SIZE(card->net)) { - dev_warn(&pdev->dev, "%u nets??\n", pdat->nbus); - return -EINVAL; - } - - card = kzalloc_obj(*card); - if (!card) - return -ENOMEM; - card->pdat = pdat; - card->pdev = pdev; - platform_set_drvdata(pdev, card); - mutex_init(&card->fw.lock); - spin_lock_init(&card->spin); - - ret = -EINVAL; - pres = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!pres) - goto platform_resource_failed; - card->dpram_phys = pres->start; - card->dpram_size = resource_size(pres); - card->dpram = ioremap(card->dpram_phys, card->dpram_size); - if (!card->dpram) { - dev_alert(&card->pdev->dev, "dpram ioremap failed\n"); - goto ioremap_failed; - } - - pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (pres) - card->irq.nr = pres->start; - - /* reset card */ - ret = softing_card_boot(card); - if (ret < 0) { - dev_alert(&pdev->dev, "failed to boot\n"); - goto boot_failed; - } - - /* only now, the chip's are known */ - card->id.freq = card->pdat->freq; - - ret = sysfs_create_group(&pdev->dev.kobj, &softing_pdev_group); - if (ret < 0) { - dev_alert(&card->pdev->dev, "sysfs failed\n"); - goto sysfs_failed; - } - - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { - card->net[j] = netdev = - softing_netdev_create(card, card->id.chip[j]); - if (!netdev) { - dev_alert(&pdev->dev, "failed to make can[%i]", j); - ret = -ENOMEM; - goto netdev_failed; - } - netdev->dev_id = j; - priv = netdev_priv(card->net[j]); - priv->index = j; - ret = softing_netdev_register(netdev); - if (ret) { - free_candev(netdev); - card->net[j] = NULL; - dev_alert(&card->pdev->dev, - "failed to register can[%i]\n", j); - goto netdev_failed; - } - } - dev_info(&card->pdev->dev, "%s ready.\n", card->pdat->name); - return 0; - -netdev_failed: - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { - if (!card->net[j]) - continue; - softing_netdev_cleanup(card->net[j]); - } - sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group); -sysfs_failed: - softing_card_shutdown(card); -boot_failed: - iounmap(card->dpram); -ioremap_failed: -platform_resource_failed: - kfree(card); - return ret; -} - -static struct platform_driver softing_driver = { - .driver = { - .name = KBUILD_MODNAME, - }, - .probe = softing_pdev_probe, - .remove = softing_pdev_remove, -}; - -module_platform_driver(softing_driver); - -MODULE_ALIAS("platform:softing"); -MODULE_DESCRIPTION("Softing DPRAM CAN driver"); -MODULE_AUTHOR("Kurt Van Dijck <[email protected]>"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/can/softing/softing_platform.h b/drivers/net/can/softing/softing_platform.h deleted file mode 100644 index cd8d7904c5f0..000000000000 --- a/drivers/net/can/softing/softing_platform.h +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#include <linux/platform_device.h> - -#ifndef _SOFTING_DEVICE_H_ -#define _SOFTING_DEVICE_H_ - -/* softing firmware directory prefix */ -#define fw_dir "softing-4.6/" - -struct softing_platform_data { - unsigned int manf; - unsigned int prod; - /* - * generation - * 1st with NEC or SJA1000 - * 8bit, exclusive interrupt, ... - * 2nd only SJA1000 - * 16bit, shared interrupt - */ - int generation; - int nbus; /* # buses on device */ - unsigned int freq; /* operating frequency in Hz */ - unsigned int max_brp; - unsigned int max_sjw; - unsigned long dpram_size; - const char *name; - struct { - unsigned long offs; - unsigned long addr; - const char *fw; - } boot, load, app; - /* - * reset() function - * bring pdev in or out of reset, depending on value - */ - int (*reset)(struct platform_device *pdev, int value); - int (*enable_irq)(struct platform_device *pdev, int value); -}; - -#endif -- 2.53.0