drivers/net/can/ifi_canfd/ifi_canfd.c
Source file repositories/reference/linux-study-clean/drivers/net/can/ifi_canfd/ifi_canfd.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/ifi_canfd/ifi_canfd.c- Extension
.c- Size
- 30095 bytes
- Lines
- 1065
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/delay.hlinux/ethtool.hlinux/interrupt.hlinux/io.hlinux/kernel.hlinux/module.hlinux/netdevice.hlinux/of.hlinux/platform_device.hlinux/can/dev.h
Detected Declarations
struct ifi_canfd_privfunction ifi_canfd_irq_enablefunction ifi_canfd_read_fifofunction ifi_canfd_do_rx_pollfunction ifi_canfd_handle_lost_msgfunction ifi_canfd_handle_lec_errfunction ifi_canfd_get_berr_counterfunction ifi_canfd_handle_state_changefunction ifi_canfd_handle_state_errorsfunction ifi_canfd_pollfunction ifi_canfd_isrfunction ifi_canfd_set_bittimingfunction ifi_canfd_set_filterfunction ifi_canfd_set_filtersfunction ifi_canfd_startfunction ifi_canfd_stopfunction ifi_canfd_set_modefunction ifi_canfd_openfunction ifi_canfd_closefunction ifi_canfd_start_xmitfunction ifi_canfd_plat_probefunction ifi_canfd_plat_remove
Annotated Snippet
static const struct net_device_ops ifi_canfd_netdev_ops = {
.ndo_open = ifi_canfd_open,
.ndo_stop = ifi_canfd_close,
.ndo_start_xmit = ifi_canfd_start_xmit,
};
static const struct ethtool_ops ifi_canfd_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static int ifi_canfd_plat_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct net_device *ndev;
struct ifi_canfd_priv *priv;
void __iomem *addr;
int irq, ret;
u32 id, rev;
addr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(addr))
return PTR_ERR(addr);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return -EINVAL;
id = readl(addr + IFI_CANFD_IP_ID);
if (id != IFI_CANFD_IP_ID_VALUE) {
dev_err(dev, "This block is not IFI CANFD, id=%08x\n", id);
return -EINVAL;
}
rev = readl(addr + IFI_CANFD_VER) & IFI_CANFD_VER_REV_MASK;
if (rev < IFI_CANFD_VER_REV_MIN_SUPPORTED) {
dev_err(dev, "This block is too old (rev %i), minimum supported is rev %i\n",
rev, IFI_CANFD_VER_REV_MIN_SUPPORTED);
return -EINVAL;
}
ndev = alloc_candev(sizeof(*priv), 1);
if (!ndev)
return -ENOMEM;
ndev->irq = irq;
ndev->flags |= IFF_ECHO; /* we support local echo */
ndev->netdev_ops = &ifi_canfd_netdev_ops;
ndev->ethtool_ops = &ifi_canfd_ethtool_ops;
priv = netdev_priv(ndev);
priv->ndev = ndev;
priv->base = addr;
netif_napi_add(ndev, &priv->napi, ifi_canfd_poll);
priv->can.state = CAN_STATE_STOPPED;
priv->can.clock.freq = readl(addr + IFI_CANFD_CANCLOCK);
priv->can.bittiming_const = &ifi_canfd_bittiming_const;
priv->can.fd.data_bittiming_const = &ifi_canfd_bittiming_const;
priv->can.do_set_mode = ifi_canfd_set_mode;
priv->can.do_get_berr_counter = ifi_canfd_get_berr_counter;
/* IFI CANFD can do both Bosch FD and ISO FD */
priv->can.ctrlmode = CAN_CTRLMODE_FD;
/* IFI CANFD can do both Bosch FD and ISO FD */
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
CAN_CTRLMODE_LISTENONLY |
CAN_CTRLMODE_FD |
CAN_CTRLMODE_FD_NON_ISO |
CAN_CTRLMODE_BERR_REPORTING;
platform_set_drvdata(pdev, ndev);
SET_NETDEV_DEV(ndev, dev);
ret = register_candev(ndev);
if (ret) {
dev_err(dev, "Failed to register (ret=%d)\n", ret);
goto err_reg;
}
dev_info(dev, "Driver registered: regs=%p, irq=%d, clock=%d\n",
priv->base, ndev->irq, priv->can.clock.freq);
return 0;
err_reg:
free_candev(ndev);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/delay.h`, `linux/ethtool.h`, `linux/interrupt.h`, `linux/io.h`, `linux/kernel.h`, `linux/module.h`, `linux/netdevice.h`.
- Detected declarations: `struct ifi_canfd_priv`, `function ifi_canfd_irq_enable`, `function ifi_canfd_read_fifo`, `function ifi_canfd_do_rx_poll`, `function ifi_canfd_handle_lost_msg`, `function ifi_canfd_handle_lec_err`, `function ifi_canfd_get_berr_counter`, `function ifi_canfd_handle_state_change`, `function ifi_canfd_handle_state_errors`, `function ifi_canfd_poll`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.