drivers/net/usb/sierra_net.c

Source file repositories/reference/linux-study-clean/drivers/net/usb/sierra_net.c

File Facts

System
Linux kernel
Corpus path
drivers/net/usb/sierra_net.c
Extension
.c
Size
27989 bytes
Lines
966
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 sierra_net_device_ops = {
	.ndo_open               = usbnet_open,
	.ndo_stop               = usbnet_stop,
	.ndo_start_xmit         = usbnet_start_xmit,
	.ndo_tx_timeout         = usbnet_tx_timeout,
	.ndo_change_mtu         = usbnet_change_mtu,
	.ndo_get_stats64        = dev_get_tstats64,
	.ndo_set_mac_address    = eth_mac_addr,
	.ndo_validate_addr      = eth_validate_addr,
};

/* get private data associated with passed in usbnet device */
static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev)
{
	return (struct sierra_net_data *)dev->data[0];
}

/* set private data associated with passed in usbnet device */
static inline void sierra_net_set_private(struct usbnet *dev,
			struct sierra_net_data *priv)
{
	dev->data[0] = (unsigned long)priv;
}

/* is packet IPv4/IPv6 */
static inline int is_ip(struct sk_buff *skb)
{
	return skb->protocol == cpu_to_be16(ETH_P_IP) ||
	       skb->protocol == cpu_to_be16(ETH_P_IPV6);
}

/*
 * check passed in packet and make sure that:
 *  - it is linear (no scatter/gather)
 *  - it is ethernet (mac_header properly set)
 */
static int check_ethip_packet(struct sk_buff *skb, struct usbnet *dev)
{
	skb_reset_mac_header(skb); /* ethernet header */

	if (skb_is_nonlinear(skb)) {
		netdev_err(dev->net, "Non linear buffer-dropping\n");
		return 0;
	}

	if (!pskb_may_pull(skb, ETH_HLEN))
		return 0;
	skb->protocol = eth_hdr(skb)->h_proto;

	return 1;
}

static const u8 *save16bit(struct param *p, const u8 *datap)
{
	p->is_present = 1;
	p->word = get_unaligned_be16(datap);
	return datap + sizeof(p->word);
}

static const u8 *save8bit(struct param *p, const u8 *datap)
{
	p->is_present = 1;
	p->byte = *datap;
	return datap + sizeof(p->byte);
}

/*----------------------------------------------------------------------------*
 *                              BEGIN HIP                                     *
 *----------------------------------------------------------------------------*/
/* HIP header */
#define SIERRA_NET_HIP_HDR_LEN 4
/* Extended HIP header */
#define SIERRA_NET_HIP_EXT_HDR_LEN 6

struct hip_hdr {
	int    hdrlen;
	struct param payload_len;
	struct param msgid;
	struct param msgspecific;
	struct param extmsgid;
};

static int parse_hip(const u8 *buf, const u32 buflen, struct hip_hdr *hh)
{
	const u8 *curp = buf;
	int    padded;

	if (buflen < SIERRA_NET_HIP_HDR_LEN)
		return -EPROTO;

Annotation

Implementation Notes