drivers/net/wwan/t7xx/t7xx_port_proxy.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wwan/t7xx/t7xx_port_proxy.c
Extension
.c
Size
16699 bytes
Lines
656
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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

switch (md_state) {
		case MD_STATE_EXCEPTION:
			if (port_conf->tx_ch != PORT_CH_MD_LOG_TX)
				return -EBUSY;
			break;

		case MD_STATE_WAITING_FOR_HS1:
		case MD_STATE_WAITING_FOR_HS2:
		case MD_STATE_STOPPED:
		case MD_STATE_WAITING_TO_STOP:
		case MD_STATE_INVALID:
			return -ENODEV;

		default:
			break;
		}
	}

	return t7xx_port_send_ccci_skb(port, skb, pkt_header, ex_msg);
}

static void t7xx_proxy_setup_ch_mapping(struct port_proxy *port_prox)
{
	struct t7xx_port *port;

	int i, j;

	for (i = 0; i < ARRAY_SIZE(port_prox->rx_ch_ports); i++)
		INIT_LIST_HEAD(&port_prox->rx_ch_ports[i]);

	for (j = 0; j < ARRAY_SIZE(port_prox->queue_ports); j++) {
		for (i = 0; i < ARRAY_SIZE(port_prox->queue_ports[j]); i++)
			INIT_LIST_HEAD(&port_prox->queue_ports[j][i]);
	}

	for_each_proxy_port(i, port, port_prox) {
		const struct t7xx_port_conf *port_conf = port->port_conf;
		enum cldma_id path_id = port_conf->path_id;
		u8 ch_id;

		ch_id = FIELD_GET(PORT_CH_ID_MASK, port_conf->rx_ch);
		list_add_tail(&port->entry, &port_prox->rx_ch_ports[ch_id]);
		list_add_tail(&port->queue_entry,
			      &port_prox->queue_ports[path_id][port_conf->rxq_index]);
	}
}

/**
 * t7xx_port_proxy_recv_skb_from_dedicated_queue() - Dispatch early port received skb.
 * @queue: CLDMA queue.
 * @skb: Socket buffer.
 *
 * Return:
 ** 0		- Packet consumed.
 ** -ERROR	- Failed to process skb.
 */
int t7xx_port_proxy_recv_skb_from_dedicated_queue(struct cldma_queue *queue, struct sk_buff *skb)
{
	struct t7xx_pci_dev *t7xx_dev = queue->md_ctrl->t7xx_dev;
	struct port_proxy *port_prox = t7xx_dev->md->port_prox;
	const struct t7xx_port_conf *port_conf;
	struct t7xx_port *port;
	int ret;

	port = &port_prox->ports[0];
	if (WARN_ON_ONCE(port->port_conf->rxq_index != queue->index)) {
		dev_kfree_skb_any(skb);
		return -EINVAL;
	}

	port_conf = port->port_conf;
	ret = port_conf->ops->recv_skb(port, skb);
	if (ret < 0 && ret != -ENOBUFS) {
		dev_err(port->dev, "drop on RX ch %d, %d\n", port_conf->rx_ch, ret);
		dev_kfree_skb_any(skb);
	}

	return ret;
}

static struct t7xx_port *t7xx_port_proxy_find_port(struct t7xx_pci_dev *t7xx_dev,
						   struct cldma_queue *queue, u16 channel)
{
	struct port_proxy *port_prox = t7xx_dev->md->port_prox;
	struct list_head *port_list;
	struct t7xx_port *port;
	u8 ch_id;

	ch_id = FIELD_GET(PORT_CH_ID_MASK, channel);
	port_list = &port_prox->rx_ch_ports[ch_id];

Annotation

Implementation Notes