drivers/net/wwan/wwan_hwsim.c

Source file repositories/reference/linux-study-clean/drivers/net/wwan/wwan_hwsim.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wwan/wwan_hwsim.c
Extension
.c
Size
17905 bytes
Lines
693
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 file_operations wwan_hwsim_debugfs_portdestroy_fops;
static const struct file_operations wwan_hwsim_debugfs_portcreate_fops;
static const struct file_operations wwan_hwsim_debugfs_devdestroy_fops;
static void wwan_hwsim_port_del_work(struct work_struct *work);
static void wwan_hwsim_dev_del_work(struct work_struct *work);

static netdev_tx_t wwan_hwsim_netdev_xmit(struct sk_buff *skb,
					  struct net_device *ndev)
{
	ndev->stats.tx_packets++;
	ndev->stats.tx_bytes += skb->len;
	consume_skb(skb);
	return NETDEV_TX_OK;
}

static const struct net_device_ops wwan_hwsim_netdev_ops = {
	.ndo_start_xmit = wwan_hwsim_netdev_xmit,
};

static void wwan_hwsim_netdev_setup(struct net_device *ndev)
{
	ndev->netdev_ops = &wwan_hwsim_netdev_ops;
	ndev->needs_free_netdev = true;

	ndev->mtu = ETH_DATA_LEN;
	ndev->min_mtu = ETH_MIN_MTU;
	ndev->max_mtu = ETH_MAX_MTU;

	ndev->type = ARPHRD_NONE;
	ndev->flags = IFF_POINTOPOINT | IFF_NOARP;
}

static const struct wwan_ops wwan_hwsim_wwan_rtnl_ops = {
	.priv_size = 0,			/* No private data */
	.setup = wwan_hwsim_netdev_setup,
};

static int wwan_hwsim_at_emul_start(struct wwan_port *wport)
{
	struct wwan_hwsim_port *port = wwan_port_get_drvdata(wport);

	port->at_emul.pstate = AT_PARSER_WAIT_A;

	return 0;
}

static void wwan_hwsim_at_emul_stop(struct wwan_port *wport)
{
}

/* Implements a minimalistic AT commands parser that echo input back and
 * reply with 'OK' to each input command. See AT command protocol details in the
 * ITU-T V.250 recomendations document.
 *
 * Be aware that this processor is not fully V.250 compliant.
 */
static int wwan_hwsim_at_emul_tx(struct wwan_port *wport, struct sk_buff *in)
{
	struct wwan_hwsim_port *port = wwan_port_get_drvdata(wport);
	struct sk_buff *out;
	int i, n, s;

	/* Estimate a max possible number of commands by counting the number of
	 * termination chars (S3 param, CR by default). And then allocate the
	 * output buffer that will be enough to fit the echo and result codes of
	 * all commands.
	 */
	for (i = 0, n = 0; i < in->len; ++i)
		if (in->data[i] == '\r')
			n++;
	n = in->len + n * (2 + 2 + 2);	/* Output buffer size */
	out = alloc_skb(n, GFP_KERNEL);
	if (!out)
		return -ENOMEM;

	for (i = 0, s = 0; i < in->len; ++i) {
		char c = in->data[i];

		if (port->at_emul.pstate == AT_PARSER_WAIT_A) {
			if (c == 'A' || c == 'a')
				port->at_emul.pstate = AT_PARSER_WAIT_T;
			else if (c != '\n')	/* Ignore formating char */
				port->at_emul.pstate = AT_PARSER_SKIP_LINE;
		} else if (port->at_emul.pstate == AT_PARSER_WAIT_T) {
			if (c == 'T' || c == 't')
				port->at_emul.pstate = AT_PARSER_WAIT_TERM;
			else
				port->at_emul.pstate = AT_PARSER_SKIP_LINE;
		} else if (port->at_emul.pstate == AT_PARSER_WAIT_TERM) {
			if (c != '\r')

Annotation

Implementation Notes