drivers/net/wireless/purelifi/plfxlc/mac.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/purelifi/plfxlc/mac.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/purelifi/plfxlc/mac.c
Extension
.c
Size
19797 bytes
Lines
760
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

if (beacon) {
			/*beacon is hardcoded in firmware */
			kfree_skb(beacon);
			/* Returned skb is used only once and lowlevel
			 * driver is responsible for freeing it.
			 */
		}
	}

	plfxlc_set_beacon_interval(&mac->chip, beacon_interval,
				   beacon_period, mac->type);

	spin_lock_irq(&mac->lock);
	mac->beacon.last_update = jiffies;
	spin_unlock_irq(&mac->lock);

	return 0;
}

static void plfxlc_mac_tx_status(struct ieee80211_hw *hw,
				 struct sk_buff *skb,
				 int ackssi,
				 struct tx_status *tx_status)
{
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	int success = 1;

	ieee80211_tx_info_clear_status(info);
	if (tx_status)
		success = !tx_status->failure;

	if (success)
		info->flags |= IEEE80211_TX_STAT_ACK;
	else
		info->flags &= ~IEEE80211_TX_STAT_ACK;

	info->status.ack_signal = 50;
	ieee80211_tx_status_irqsafe(hw, skb);
}

void plfxlc_mac_tx_to_dev(struct sk_buff *skb, int error)
{
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct ieee80211_hw *hw = info->rate_driver_data[0];
	struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
	struct sk_buff_head *q = NULL;

	ieee80211_tx_info_clear_status(info);
	skb_pull(skb, sizeof(struct plfxlc_ctrlset));

	if (unlikely(error ||
		     (info->flags & IEEE80211_TX_CTL_NO_ACK))) {
		ieee80211_tx_status_irqsafe(hw, skb);
		return;
	}

	q = &mac->ack_wait_queue;

	skb_queue_tail(q, skb);
	while (skb_queue_len(q)/* > PURELIFI_MAC_MAX_ACK_WAITERS*/) {
		plfxlc_mac_tx_status(hw, skb_dequeue(q),
				     mac->ack_pending ?
				     mac->ack_signal : 0,
				     NULL);
		mac->ack_pending = 0;
	}
}

static int plfxlc_fill_ctrlset(struct plfxlc_mac *mac, struct sk_buff *skb)
{
	unsigned int frag_len = skb->len;
	struct plfxlc_ctrlset *cs;
	u32 temp_payload_len = 0;
	unsigned int tmp;
	u32 temp_len = 0;

	if (skb_headroom(skb) < sizeof(struct plfxlc_ctrlset)) {
		dev_dbg(plfxlc_mac_dev(mac), "Not enough hroom(1)\n");
		return 1;
	}

	cs = (void *)skb_push(skb, sizeof(struct plfxlc_ctrlset));
	temp_payload_len = frag_len;
	temp_len = temp_payload_len +
		  sizeof(struct plfxlc_ctrlset) -
		  sizeof(cs->id) - sizeof(cs->len);

	/* Data packet lengths must be multiple of four bytes and must
	 * not be a multiple of 512 bytes. First, it is attempted to
	 * append the data packet in the tailroom of the skb. In rare

Annotation

Implementation Notes