drivers/net/ipa/ipa_modem.c

Source file repositories/reference/linux-study-clean/drivers/net/ipa/ipa_modem.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ipa/ipa_modem.c
Extension
.c
Size
12318 bytes
Lines
499
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 ipa_modem_ops = {
	.ndo_open	= ipa_open,
	.ndo_stop	= ipa_stop,
	.ndo_start_xmit	= ipa_start_xmit,
};

/** ipa_modem_netdev_setup() - netdev setup function for the modem */
static void ipa_modem_netdev_setup(struct net_device *netdev)
{
	netdev->netdev_ops = &ipa_modem_ops;

	netdev->header_ops = NULL;
	netdev->type = ARPHRD_RAWIP;
	netdev->hard_header_len = 0;
	netdev->min_header_len = ETH_HLEN;
	netdev->min_mtu = ETH_MIN_MTU;
	netdev->max_mtu = IPA_MTU;
	netdev->mtu = netdev->max_mtu;
	netdev->addr_len = 0;
	netdev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
	netdev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
	netdev->priv_flags |= IFF_TX_SKB_SHARING;
	eth_broadcast_addr(netdev->broadcast);

	/* The endpoint is configured for QMAP */
	netdev->needed_headroom = sizeof(struct rmnet_map_header);
	netdev->needed_tailroom = IPA_NETDEV_TAILROOM;
	netdev->watchdog_timeo = IPA_NETDEV_TIMEOUT * HZ;
	netdev->hw_features = NETIF_F_SG;
}

/** ipa_modem_suspend() - suspend callback
 * @netdev:	Network device
 *
 * Suspend the modem's endpoints.
 */
void ipa_modem_suspend(struct net_device *netdev)
{
	struct ipa_priv *priv;

	if (!(netdev->flags & IFF_UP))
		return;

	priv = netdev_priv(netdev);
	ipa_endpoint_suspend_one(priv->rx);
	ipa_endpoint_suspend_one(priv->tx);
}

/**
 * ipa_modem_wake_queue_work() - enable modem netdev queue
 * @work:	Work structure
 *
 * Re-enable transmit on the modem network device.  This is called
 * in (power management) work queue context, scheduled when resuming
 * the modem.  We can't enable the queue directly in ipa_modem_resume()
 * because transmits restart the instant the queue is awakened; but the
 * device power state won't be ACTIVE until *after* ipa_modem_resume()
 * returns.
 */
static void ipa_modem_wake_queue_work(struct work_struct *work)
{
	struct ipa_priv *priv = container_of(work, struct ipa_priv, work);

	netif_wake_queue(priv->tx->netdev);
}

/** ipa_modem_resume() - resume callback for runtime_pm
 * @dev: pointer to device
 *
 * Resume the modem's endpoints.
 */
void ipa_modem_resume(struct net_device *netdev)
{
	struct ipa_priv *priv;

	if (!(netdev->flags & IFF_UP))
		return;

	priv = netdev_priv(netdev);
	ipa_endpoint_resume_one(priv->tx);
	ipa_endpoint_resume_one(priv->rx);

	/* Arrange for the TX queue to be restarted */
	(void)queue_pm_work(&priv->work);
}

int ipa_modem_start(struct ipa *ipa)
{
	enum ipa_modem_state state;
	struct net_device *netdev;

Annotation

Implementation Notes