drivers/net/can/janz-ican3.c

Source file repositories/reference/linux-study-clean/drivers/net/can/janz-ican3.c

File Facts

System
Linux kernel
Corpus path
drivers/net/can/janz-ican3.c
Extension
.c
Size
51114 bytes
Lines
2060
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct net_device_ops ican3_netdev_ops = {
	.ndo_open	= ican3_open,
	.ndo_stop	= ican3_stop,
	.ndo_start_xmit	= ican3_xmit,
};

static const struct ethtool_ops ican3_ethtool_ops = {
	.get_ts_info = ethtool_op_get_ts_info,
};

/*
 * Low-level CAN Device
 */

/* This structure was stolen from drivers/net/can/sja1000/sja1000.c */
static const struct can_bittiming_const ican3_bittiming_const = {
	.name = DRV_NAME,
	.tseg1_min = 1,
	.tseg1_max = 16,
	.tseg2_min = 1,
	.tseg2_max = 8,
	.sjw_max = 4,
	.brp_min = 1,
	.brp_max = 64,
	.brp_inc = 1,
};

static int ican3_set_mode(struct net_device *ndev, enum can_mode mode)
{
	struct ican3_dev *mod = netdev_priv(ndev);
	int ret;

	if (mode != CAN_MODE_START)
		return -ENOTSUPP;

	/* bring the bus online */
	ret = ican3_set_bus_state(mod, true);
	if (ret) {
		netdev_err(ndev, "unable to set bus-on\n");
		return ret;
	}

	/* start up the network device */
	mod->can.state = CAN_STATE_ERROR_ACTIVE;

	if (netif_queue_stopped(ndev))
		netif_wake_queue(ndev);

	return 0;
}

static int ican3_get_berr_counter(const struct net_device *ndev,
				  struct can_berr_counter *bec)
{
	struct ican3_dev *mod = netdev_priv(ndev);
	int ret;

	ret = ican3_send_inquiry(mod, INQUIRY_STATUS);
	if (ret)
		return ret;

	if (!wait_for_completion_timeout(&mod->buserror_comp, HZ)) {
		netdev_info(mod->ndev, "%s timed out\n", __func__);
		return -ETIMEDOUT;
	}

	bec->rxerr = mod->bec.rxerr;
	bec->txerr = mod->bec.txerr;
	return 0;
}

/*
 * Sysfs Attributes
 */

static ssize_t termination_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct ican3_dev *mod = netdev_priv(to_net_dev(dev));
	int ret;

	ret = ican3_send_inquiry(mod, INQUIRY_TERMINATION);
	if (ret)
		return ret;

	if (!wait_for_completion_timeout(&mod->termination_comp, HZ)) {
		netdev_info(mod->ndev, "%s timed out\n", __func__);
		return -ETIMEDOUT;
	}

Annotation

Implementation Notes