drivers/net/wireless/intel/iwlegacy/3945.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/intel/iwlegacy/3945.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/intel/iwlegacy/3945.c
Extension
.c
Size
76819 bytes
Lines
2726
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

il_is_associated(il)) {
			if (rate == RATE_11M_IDX)
				next_rate = RATE_5M_IDX;
		}
		break;

	default:
		break;
	}

	return next_rate;
}

/*
 * il3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
 *
 * When FW advances 'R' idx, all entries between old and new 'R' idx
 * need to be reclaimed. As result, some free space forms. If there is
 * enough free space (> low mark), wake the stack that feeds us.
 */
static void
il3945_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
{
	struct il_tx_queue *txq = &il->txq[txq_id];
	struct il_queue *q = &txq->q;
	struct sk_buff *skb;

	BUG_ON(txq_id == IL39_CMD_QUEUE_NUM);

	for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
	     q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) {

		skb = txq->skbs[txq->q.read_ptr];
		ieee80211_tx_status_irqsafe(il->hw, skb);
		txq->skbs[txq->q.read_ptr] = NULL;
		il->ops->txq_free_tfd(il, txq);
	}

	if (il_queue_space(q) > q->low_mark && txq_id >= 0 &&
	    txq_id != IL39_CMD_QUEUE_NUM && il->mac80211_registered)
		il_wake_queue(il, txq);
}

/*
 * il3945_hdl_tx - Handle Tx response
 */
static void
il3945_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
{
	struct il_rx_pkt *pkt = rxb_addr(rxb);
	u16 sequence = le16_to_cpu(pkt->hdr.sequence);
	int txq_id = SEQ_TO_QUEUE(sequence);
	int idx = SEQ_TO_IDX(sequence);
	struct il_tx_queue *txq = &il->txq[txq_id];
	struct ieee80211_tx_info *info;
	struct il3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
	u32 status = le32_to_cpu(tx_resp->status);
	int rate_idx;
	int fail;

	if (idx >= txq->q.n_bd || il_queue_used(&txq->q, idx) == 0) {
		IL_ERR("Read idx for DMA queue txq_id (%d) idx %d "
		       "is out of range [0-%d] %d %d\n", txq_id, idx,
		       txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr);
		return;
	}

	/*
	 * Firmware will not transmit frame on passive channel, if it not yet
	 * received some valid frame on that channel. When this error happen
	 * we have to wait until firmware will unblock itself i.e. when we
	 * note received beacon or other frame. We unblock queues in
	 * il3945_pass_packet_to_mac80211 or in il_mac_bss_info_changed.
	 */
	if (unlikely((status & TX_STATUS_MSK) == TX_STATUS_FAIL_PASSIVE_NO_RX) &&
	    il->iw_mode == NL80211_IFTYPE_STATION) {
		il_stop_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
		D_INFO("Stopped queues - RX waiting on passive channel\n");
	}

	txq->time_stamp = jiffies;
	info = IEEE80211_SKB_CB(txq->skbs[txq->q.read_ptr]);
	ieee80211_tx_info_clear_status(info);

	/* Fill the MRR chain with some info about on-chip retransmissions */
	rate_idx = il3945_hwrate_to_plcp_idx(tx_resp->rate);
	if (info->band == NL80211_BAND_5GHZ)
		rate_idx -= IL_FIRST_OFDM_RATE;

	fail = tx_resp->failure_frame;

Annotation

Implementation Notes