drivers/net/wireless/marvell/libertas/rx.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/marvell/libertas/rx.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/marvell/libertas/rx.c
Extension
.c
Size
7274 bytes
Lines
272
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

struct eth803hdr {
	u8 dest_addr[6];
	u8 src_addr[6];
	u16 h803_len;
} __packed;

struct rfc1042hdr {
	u8 llc_dsap;
	u8 llc_ssap;
	u8 llc_ctrl;
	u8 snap_oui[3];
	u16 snap_type;
} __packed;

struct rxpackethdr {
	struct eth803hdr eth803_hdr;
	struct rfc1042hdr rfc1042_hdr;
} __packed;

struct rx80211packethdr {
	struct rxpd rx_pd;
	void *eth80211_hdr;
} __packed;

static int process_rxed_802_11_packet(struct lbs_private *priv,
	struct sk_buff *skb);

/**
 * lbs_process_rxed_packet - processes received packet and forwards it
 * to kernel/upper layer
 *
 * @priv:	A pointer to &struct lbs_private
 * @skb:	A pointer to skb which includes the received packet
 * returns:	0 or -1
 */
int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
{
	int ret = 0;
	struct net_device *dev = priv->dev;
	struct rxpackethdr *p_rx_pkt;
	struct rxpd *p_rx_pd;
	int hdrchop;
	struct ethhdr *p_ethhdr;

	BUG_ON(!skb);

	skb->ip_summed = CHECKSUM_NONE;

	if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
		ret = process_rxed_802_11_packet(priv, skb);
		goto done;
	}

	p_rx_pd = (struct rxpd *) skb->data;
	p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd +
		le32_to_cpu(p_rx_pd->pkt_ptr));

	dev = lbs_mesh_set_dev(priv, dev, p_rx_pd);

	lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data,
		 min_t(unsigned int, skb->len, 100));

	if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
		lbs_deb_rx("rx err: frame received with bad length\n");
		dev->stats.rx_length_errors++;
		ret = -EINVAL;
		dev_kfree_skb(skb);
		goto done;
	}

	lbs_deb_rx("rx data: skb->len - pkt_ptr = %d-%zd = %zd\n",
		skb->len, (size_t)le32_to_cpu(p_rx_pd->pkt_ptr),
		skb->len - (size_t)le32_to_cpu(p_rx_pd->pkt_ptr));

	lbs_deb_hex(LBS_DEB_RX, "RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
		sizeof(p_rx_pkt->eth803_hdr.dest_addr));
	lbs_deb_hex(LBS_DEB_RX, "RX Data: Src", p_rx_pkt->eth803_hdr.src_addr,
		sizeof(p_rx_pkt->eth803_hdr.src_addr));

	if (memcmp(&p_rx_pkt->rfc1042_hdr,
		   rfc1042_header, sizeof(rfc1042_header)) == 0) {
		/*
		 *  Replace the 803 header and rfc1042 header (llc/snap) with an
		 *    EthernetII header, keep the src/dst and snap_type (ethertype)
		 *
		 *  The firmware only passes up SNAP frames converting
		 *    all RX Data from 802.11 to 802.2/LLC/SNAP frames.
		 *
		 *  To create the Ethernet II, just move the src, dst address right
		 *    before the snap_type.

Annotation

Implementation Notes