drivers/net/wireless/ath/ath11k/mac.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/ath11k/mac.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/ath11k/mac.c
Extension
.c
Size
296291 bytes
Lines
10879
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

struct ath11k_mac_change_chanctx_arg {
	struct ieee80211_chanctx_conf *ctx;
	struct ieee80211_vif_chanctx_switch *vifs;
	int n_vifs;
	int next_vif;
};

static void
ath11k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
				   struct ieee80211_vif *vif)
{
	struct ath11k_mac_change_chanctx_arg *arg = data;

	if (rcu_access_pointer(vif->bss_conf.chanctx_conf) != arg->ctx)
		return;

	arg->n_vifs++;
}

static void
ath11k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
				    struct ieee80211_vif *vif)
{
	struct ath11k_mac_change_chanctx_arg *arg = data;
	struct ieee80211_chanctx_conf *ctx;

	ctx = rcu_access_pointer(vif->bss_conf.chanctx_conf);
	if (ctx != arg->ctx)
		return;

	if (WARN_ON(arg->next_vif == arg->n_vifs))
		return;

	arg->vifs[arg->next_vif].vif = vif;
	arg->vifs[arg->next_vif].old_ctx = ctx;
	arg->vifs[arg->next_vif].new_ctx = ctx;
	arg->next_vif++;
}

static void
ath11k_mac_update_vif_chan(struct ath11k *ar,
			   struct ieee80211_vif_chanctx_switch *vifs,
			   int n_vifs)
{
	struct ath11k_base *ab = ar->ab;
	struct ath11k_vif *arvif, *tx_arvif;
	int ret;
	int i;
	bool monitor_vif = false;

	lockdep_assert_held(&ar->conf_mutex);

	/* Associated channel resources of all relevant vdevs
	 * should be available for the channel switch now.
	 */

	/* TODO: Update ar->rx_channel */

	for (i = 0; i < n_vifs; i++) {
		arvif = ath11k_vif_to_arvif(vifs[i].vif);

		if (WARN_ON(!arvif->is_started))
			continue;

		/* change_chanctx can be called even before vdev_up from
		 * ieee80211_start_ap->ieee80211_vif_use_channel->
		 * ieee80211_recalc_radar_chanctx.
		 *
		 * Firmware expect vdev_restart only if vdev is up.
		 * If vdev is down then it expect vdev_stop->vdev_start.
		 */
		if (arvif->is_up) {
			ret = ath11k_mac_vdev_restart(arvif, vifs[i].new_ctx);
			if (ret) {
				ath11k_warn(ab, "failed to restart vdev %d: %d\n",
					    arvif->vdev_id, ret);
				continue;
			}
		} else {
			ret = ath11k_mac_vdev_stop(arvif);
			if (ret) {
				ath11k_warn(ab, "failed to stop vdev %d: %d\n",
					    arvif->vdev_id, ret);
				continue;
			}

			ret = ath11k_mac_vdev_start(arvif, vifs[i].new_ctx);
			if (ret)
				ath11k_warn(ab, "failed to start vdev %d: %d\n",
					    arvif->vdev_id, ret);

Annotation

Implementation Notes