drivers/net/wireless/marvell/mwifiex/11h.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/marvell/mwifiex/11h.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/marvell/mwifiex/11h.c
Extension
.c
Size
9214 bytes
Lines
295
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

switch (le16_to_cpu(rpt->header.type)) {
		case TLV_TYPE_CHANRPT_11H_BASIC:
			if (rpt->map.radar) {
				mwifiex_dbg(priv->adapter, MSG,
					    "RADAR Detected on channel %d!\n",
					    priv->dfs_chandef.chan->hw_value);
				cancel_delayed_work_sync(&priv->dfs_cac_work);
				cfg80211_cac_event(priv->netdev,
						   &priv->dfs_chandef,
						   NL80211_RADAR_DETECTED,
						   GFP_KERNEL, 0);
			}
			break;
		default:
			break;
		}

		event_len -= (tlv_len + sizeof(rpt->header));
	}

	return 0;
}

/* Handler for radar detected event from FW.*/
int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv,
				      struct sk_buff *skb)
{
	struct mwifiex_radar_det_event *rdr_event;

	rdr_event = (void *)(skb->data + sizeof(u32));

	mwifiex_dbg(priv->adapter, MSG,
		    "radar detected; indicating kernel\n");
	if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef))
		mwifiex_dbg(priv->adapter, ERROR,
			    "Failed to stop CAC in FW\n");
	cfg80211_radar_event(priv->adapter->wiphy, &priv->dfs_chandef,
			     GFP_KERNEL);
	mwifiex_dbg(priv->adapter, MSG, "regdomain: %d\n",
		    rdr_event->reg_domain);
	mwifiex_dbg(priv->adapter, MSG, "radar detection type: %d\n",
		    rdr_event->det_type);

	return 0;
}

/* This is work queue function for channel switch handling.
 * This function takes care of updating new channel definitin to
 * bss config structure, restart AP and indicate channel switch success
 * to cfg80211.
 */
void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work)
{
	struct mwifiex_uap_bss_param *bss_cfg;
	struct delayed_work *delayed_work = to_delayed_work(work);
	struct mwifiex_private *priv =
			container_of(delayed_work, struct mwifiex_private,
				     dfs_chan_sw_work);

	bss_cfg = &priv->bss_cfg;
	if (!bss_cfg->beacon_period) {
		mwifiex_dbg(priv->adapter, ERROR,
			    "channel switch: AP already stopped\n");
		return;
	}

	mwifiex_uap_set_channel(priv, bss_cfg, priv->dfs_chandef);

	if (mwifiex_config_start_uap(priv, bss_cfg)) {
		mwifiex_dbg(priv->adapter, ERROR,
			    "Failed to start AP after channel switch\n");
		return;
	}

	mwifiex_dbg(priv->adapter, MSG,
		    "indicating channel switch completion to kernel\n");
	wiphy_lock(priv->wdev.wiphy);
	cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef, 0);
	wiphy_unlock(priv->wdev.wiphy);
}

Annotation

Implementation Notes