drivers/net/wireless/ath/wil6210/main.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/wil6210/main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/wil6210/main.c
Extension
.c
Size
53121 bytes
Lines
2014
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

test_bit(wil_status_suspended, wil->status)) {
		up_read(&wil->mem_lock);
		return -EBUSY;
	}

	return 0;
}

void wil_mem_access_unlock(struct wil6210_priv *wil)
{
	up_read(&wil->mem_lock);
}

static void wil_ring_fini_tx(struct wil6210_priv *wil, int id)
{
	struct wil_ring *ring = &wil->ring_tx[id];
	struct wil_ring_tx_data *txdata = &wil->ring_tx_data[id];

	lockdep_assert_held(&wil->mutex);

	if (!ring->va)
		return;

	wil_dbg_misc(wil, "vring_fini_tx: id=%d\n", id);

	spin_lock_bh(&txdata->lock);
	txdata->dot1x_open = false;
	txdata->mid = U8_MAX;
	txdata->enabled = 0; /* no Tx can be in progress or start anew */
	spin_unlock_bh(&txdata->lock);
	/* napi_synchronize waits for completion of the current NAPI but will
	 * not prevent the next NAPI run.
	 * Add a memory barrier to guarantee that txdata->enabled is zeroed
	 * before napi_synchronize so that the next scheduled NAPI will not
	 * handle this vring
	 */
	wmb();
	/* make sure NAPI won't touch this vring */
	if (test_bit(wil_status_napi_en, wil->status))
		napi_synchronize(&wil->napi_tx);

	wil->txrx_ops.ring_fini_tx(wil, ring);
}

static bool wil_vif_is_connected(struct wil6210_priv *wil, u8 mid)
{
	int i;

	for (i = 0; i < wil->max_assoc_sta; i++) {
		if (wil->sta[i].mid == mid &&
		    wil->sta[i].status == wil_sta_connected)
			return true;
	}

	return false;
}

static void wil_disconnect_cid_complete(struct wil6210_vif *vif, int cid,
					u16 reason_code)
__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
{
	uint i;
	struct wil6210_priv *wil = vif_to_wil(vif);
	struct wireless_dev *wdev = vif_to_wdev(vif);
	struct wil_sta_info *sta = &wil->sta[cid];
	int min_ring_id = wil_get_min_tx_ring_id(wil);

	might_sleep();
	wil_dbg_misc(wil,
		     "disconnect_cid_complete: CID %d, MID %d, status %d\n",
		     cid, sta->mid, sta->status);
	/* inform upper layers */
	if (sta->status != wil_sta_unused) {
		if (vif->mid != sta->mid) {
			wil_err(wil, "STA MID mismatch with VIF MID(%d)\n",
				vif->mid);
		}

		switch (wdev->iftype) {
		case NL80211_IFTYPE_AP:
		case NL80211_IFTYPE_P2P_GO:
			/* AP-like interface */
			cfg80211_del_sta(wdev, sta->addr, GFP_KERNEL);
			break;
		default:
			break;
		}
		sta->status = wil_sta_unused;
		sta->mid = U8_MAX;
	}

Annotation

Implementation Notes