drivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c
Source file repositories/reference/linux-study-clean/drivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c- Extension
.c- Size
- 57987 bytes
- Lines
- 1909
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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
kvaser_pciefd.hlinux/bitfield.hlinux/can/dev.hlinux/device.hlinux/ethtool.hlinux/iopoll.hlinux/kernel.hlinux/minmax.hlinux/module.hlinux/netdevice.hlinux/pci.hlinux/timer.hnet/netdev_queues.h
Detected Declarations
struct kvaser_pciefdstruct kvaser_pciefd_rx_packetstruct kvaser_pciefd_tx_packetfunction kvaser_pciefd_send_kcan_cmdfunction kvaser_pciefd_request_statusfunction kvaser_pciefd_abort_flush_resetfunction kvaser_pciefd_set_ledfunction kvaser_pciefd_enable_err_genfunction kvaser_pciefd_disable_err_genfunction kvaser_pciefd_set_tx_irqfunction kvaser_pciefd_set_skb_timestampfunction kvaser_pciefd_setup_controllerfunction kvaser_pciefd_start_controller_flushfunction kvaser_pciefd_bus_onfunction kvaser_pciefd_pwm_stopfunction kvaser_pciefd_pwm_startfunction kvaser_pciefd_openfunction kvaser_pciefd_stopfunction kvaser_pciefd_tx_availfunction kvaser_pciefd_prepare_tx_packetfunction kvaser_pciefd_start_xmitfunction kvaser_pciefd_set_bittimingfunction kvaser_pciefd_set_nominal_bittimingfunction kvaser_pciefd_set_data_bittimingfunction kvaser_pciefd_set_modefunction kvaser_pciefd_get_berr_counterfunction kvaser_pciefd_bec_poll_timerfunction kvaser_pciefd_set_phys_idfunction kvaser_pciefd_setup_can_ctrlsfunction kvaser_pciefd_reg_candevfunction kvaser_pciefd_write_dma_map_alterafunction kvaser_pciefd_write_dma_map_sf2function kvaser_pciefd_write_dma_map_xilinxfunction kvaser_pciefd_setup_dmafunction kvaser_pciefd_setup_boardfunction kvaser_pciefd_handle_data_packetfunction kvaser_pciefd_change_statefunction kvaser_pciefd_packet_to_statefunction kvaser_pciefd_rx_error_framefunction kvaser_pciefd_handle_error_packetfunction kvaser_pciefd_handle_status_respfunction kvaser_pciefd_handle_status_packetfunction kvaser_pciefd_handle_nack_packetfunction kvaser_pciefd_handle_ack_packetfunction kvaser_pciefd_handle_eflush_packetfunction kvaser_pciefd_read_packetfunction kvaser_pciefd_read_bufferfunction kvaser_pciefd_receive_irq
Annotated Snippet
static const struct net_device_ops kvaser_pciefd_netdev_ops = {
.ndo_open = kvaser_pciefd_open,
.ndo_stop = kvaser_pciefd_stop,
.ndo_start_xmit = kvaser_pciefd_start_xmit,
.ndo_hwtstamp_get = can_hwtstamp_get,
.ndo_hwtstamp_set = can_hwtstamp_set,
};
static int kvaser_pciefd_set_phys_id(struct net_device *netdev,
enum ethtool_phys_id_state state)
{
struct kvaser_pciefd_can *can = netdev_priv(netdev);
switch (state) {
case ETHTOOL_ID_ACTIVE:
return 3; /* 3 On/Off cycles per second */
case ETHTOOL_ID_ON:
kvaser_pciefd_set_led(can, true);
return 0;
case ETHTOOL_ID_OFF:
case ETHTOOL_ID_INACTIVE:
kvaser_pciefd_set_led(can, false);
return 0;
default:
return -EINVAL;
}
}
static const struct ethtool_ops kvaser_pciefd_ethtool_ops = {
.get_ts_info = can_ethtool_op_get_ts_info_hwts,
.set_phys_id = kvaser_pciefd_set_phys_id,
};
static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
{
int i;
for (i = 0; i < pcie->nr_channels; i++) {
struct net_device *netdev;
struct kvaser_pciefd_can *can;
u32 status, tx_nr_packets_max;
int ret;
netdev = alloc_candev(sizeof(struct kvaser_pciefd_can),
roundup_pow_of_two(KVASER_PCIEFD_CAN_TX_MAX_COUNT));
if (!netdev)
return -ENOMEM;
can = netdev_priv(netdev);
netdev->netdev_ops = &kvaser_pciefd_netdev_ops;
netdev->ethtool_ops = &kvaser_pciefd_ethtool_ops;
can->reg_base = KVASER_PCIEFD_KCAN_CHX_ADDR(pcie, i);
can->kv_pcie = pcie;
can->cmd_seq = 0;
can->err_rep_cnt = 0;
can->completed_tx_pkts = 0;
can->completed_tx_bytes = 0;
can->bec.txerr = 0;
can->bec.rxerr = 0;
can->can.dev->dev_port = i;
init_completion(&can->start_comp);
init_completion(&can->flush_comp);
timer_setup(&can->bec_poll_timer, kvaser_pciefd_bec_poll_timer, 0);
/* Disable Bus load reporting */
iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_BUS_LOAD_REG);
can->ioc = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_IOC_REG);
kvaser_pciefd_set_led(can, false);
tx_nr_packets_max =
FIELD_GET(KVASER_PCIEFD_KCAN_TX_NR_PACKETS_MAX_MASK,
ioread32(can->reg_base + KVASER_PCIEFD_KCAN_TX_NR_PACKETS_REG));
can->tx_max_count = min(KVASER_PCIEFD_CAN_TX_MAX_COUNT, tx_nr_packets_max - 1);
can->can.clock.freq = pcie->freq;
spin_lock_init(&can->lock);
can->can.bittiming_const = &kvaser_pciefd_bittiming_const;
can->can.fd.data_bittiming_const = &kvaser_pciefd_bittiming_const;
can->can.do_set_bittiming = kvaser_pciefd_set_nominal_bittiming;
can->can.fd.do_set_data_bittiming = kvaser_pciefd_set_data_bittiming;
can->can.do_set_mode = kvaser_pciefd_set_mode;
can->can.do_get_berr_counter = kvaser_pciefd_get_berr_counter;
can->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY |
CAN_CTRLMODE_FD |
Annotation
- Immediate include surface: `kvaser_pciefd.h`, `linux/bitfield.h`, `linux/can/dev.h`, `linux/device.h`, `linux/ethtool.h`, `linux/iopoll.h`, `linux/kernel.h`, `linux/minmax.h`.
- Detected declarations: `struct kvaser_pciefd`, `struct kvaser_pciefd_rx_packet`, `struct kvaser_pciefd_tx_packet`, `function kvaser_pciefd_send_kcan_cmd`, `function kvaser_pciefd_request_status`, `function kvaser_pciefd_abort_flush_reset`, `function kvaser_pciefd_set_led`, `function kvaser_pciefd_enable_err_gen`, `function kvaser_pciefd_disable_err_gen`, `function kvaser_pciefd_set_tx_irq`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.